{
  "openapi": "3.1.0",
  "info": {
    "title": "DeployHermes Headless MCP API",
    "version": "2026-08-28",
    "summary": "Machine-readable contract for the workspace API-key MCP endpoint that powers external agents and scripts.",
    "description": "DeployHermes has two API surfaces. The public REST surface under /api/v1 needs no credential: it serves a discovery index, a health check, the MCP server card, the entire public documentation library as structured JSON, and a batch endpoint that dispatches up to 20 of those reads in one call. The headless Model Context Protocol endpoint at POST /mcp/v1 operates a workspace and needs a bearer workspace API key. It is JSON-RPC 2.0 over the Streamable HTTP transport and supports initialize, notifications/initialized, tools/list, and tools/call. The optional manage_workspace and manage_connections scopes are elevated workspace-account/project and integration/communication authority; elevated tools return secure browser, device, dashboard, billing-portal, or hosted-checkout handoffs where needed and never expose share tokens, API-key plaintext, or raw provider, channel, or payment secrets. Versioning: /api/v1 and /mcp/v1 are both versioned by URL path, and a breaking change ships as a new path rather than mutating either contract in place. Nothing described in this document is deprecated today; see x-deployhermes-versioning for what changes once something is. Start at https://deploy-hermes.com/developers for quickstart commands, scopes, and limits.",
    "contact": {
      "name": "DeployHermes",
      "email": "hello@deploy-hermes.com",
      "url": "https://deploy-hermes.com/developers"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://deploy-hermes.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://deploy-hermes.com",
      "description": "DeployHermes. Public REST endpoints and the headless MCP endpoint."
    }
  ],
  "tags": [
    {
      "name": "Public discovery",
      "description": "Unauthenticated REST endpoints for discovery, health, MCP metadata, and the public documentation library."
    },
    {
      "name": "Headless MCP",
      "description": "Workspace automation over JSON-RPC 2.0 for external agents and scripts."
    }
  ],
  "paths": {
    "/api/v1": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "getPublicDiscoveryIndex",
        "summary": "Read the public API discovery index",
        "description": "Unauthenticated index of the public surface. It names every other public endpoint, the OpenAPI document, the MCP server card, the plain-text documentation files, and the signed-in path for creating a workspace API key. Read this first: an agent can plan a whole integration from this one response.",
        "security": [],
        "responses": {
          "200": {
            "description": "Read the public API discovery index",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDiscoveryIndexResponse"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "getPublicDiscoveryHealth",
        "summary": "Check public API health",
        "description": "Unauthenticated liveness check for external monitors and agents. It confirms the public discovery surface is reachable without requiring a workspace API key, and reports how many public documentation pages it is serving.",
        "security": [],
        "responses": {
          "200": {
            "description": "Check public API health",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicHealthResponse"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mcp": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "getMcpServerCard",
        "summary": "Read the MCP server card",
        "description": "The Model Context Protocol server card for the authenticated workspace endpoint, in the MCP registry server.json shape: the streamable-http remote, the bearer header the workspace API key goes in, and every protocol version initialize will echo back. The identical document is served at /.well-known/mcp.json.",
        "security": [],
        "responses": {
          "200": {
            "description": "Read the MCP server card",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpServerCard"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/mcp.json": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "getWellKnownMcpServerCard",
        "summary": "Read the MCP server card at the discovery convention path",
        "description": "Byte-identical to GET /api/v1/mcp, served at the well-known path MCP clients probe. Both come from one generator, so they cannot describe different servers.",
        "security": [],
        "responses": {
          "200": {
            "description": "Read the MCP server card at the discovery convention path",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpServerCard"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/docs": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "listDocumentationPages",
        "summary": "List public documentation articles",
        "description": "The public documentation articles as structured JSON, plus category summaries for the whole library. Each entry in `pages` has its canonical URL, the API URL that returns its full text, its search intent, keywords, and publication dates. Use it to choose an article before fetching it. `pages` is cursor-paginated; `categories` always covers the whole article library regardless of the current page.",
        "security": [],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum pages to return in one page. Defaults to 25; values above 100 are capped at 100 rather than rejected.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque pagination cursor from a previous response's next_cursor. Omit for the first page. The registry this paginates is a fixed, ordered list, so a cursor never goes stale between requests.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List public documentation articles",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentationIndexResponse"
                }
              }
            }
          },
          "400": {
            "description": "limit is not a positive integer, or cursor does not decode.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/docs/{category}/{slug}": {
      "get": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "getDocumentationPage",
        "summary": "Read one documentation page as structured JSON",
        "description": "One public documentation page, decomposed: intro, headed sections with their paragraphs and bullets, frequently asked questions, and any cited external sources with as-of dates. This is the same prose the HTML page renders, without the page around it.",
        "security": [],
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "description": "Documentation category slug, as returned by GET /api/v1/docs.",
            "schema": {
              "type": "string",
              "enum": [
                "getting-started",
                "setup-guides",
                "comparisons",
                "security-privacy",
                "self-hosting",
                "technical",
                "troubleshooting"
              ]
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Page slug within the category, as returned by GET /api/v1/docs.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Read one documentation page as structured JSON",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentationPageResponse"
                }
              }
            }
          },
          "404": {
            "description": "No public resource exists at that path.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and HEAD are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, HEAD"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/ask": {
      "post": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "askNaturalLanguageQuestion",
        "summary": "Ask a natural-language question about DeployHermes",
        "description": "An NLWeb-conformant endpoint that answers from this site's own documentation. Retrieval is deterministic keyword ranking over the published pages — no model is called, so the same question always returns the same ranked pages. Answers as one JSON document by default; send Accept: text/event-stream, or streaming=true, for the NLWeb SSE sequence (start, one result per item, complete).",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskRequest"
              },
              "examples": {
                "question": {
                  "summary": "Ask about setup",
                  "value": {
                    "query": "how do I connect a telegram bot",
                    "num_results": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ranked answers drawn from the public documentation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "NLWeb SSE sequence: a start event carrying _meta, one result event per item, then complete."
                }
              }
            }
          },
          "400": {
            "description": "The query was missing or empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET and POST are supported.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, POST"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/batch": {
      "post": {
        "tags": [
          "Public discovery"
        ],
        "operationId": "postPublicApiBatch",
        "summary": "Batch up to 20 GET requests into one call",
        "description": "Dispatches every operation through the exact same routing a standalone request to that path would hit, so a batched result cannot differ from calling that operation directly. Each operation is { id, method, path }; method defaults to GET. Results come back in request order, one { id, status, body } per operation — one operation 404ing does not fail the batch, and the batch itself only fails (400) if the body is malformed or exceeds the operation cap. This is the one POST on an otherwise GET/HEAD-only surface, and it is still read-only: every path it can dispatch to is one of this API's own GET routes, and an operation targeting /api/v1/batch itself is rejected rather than dispatched. That read-only guarantee is what makes replaying the same Idempotency-Key safe below without a stored dedupe table — there is no side effect a second delivery could double-apply.",
        "security": [],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Echoed back on the response unchanged. Every operation this endpoint dispatches is a read, so replaying the same key is naturally safe — there is nothing to deduplicate, and the key is never stored or inspected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "examples": {
                "batch": {
                  "summary": "Two reads in one call",
                  "value": {
                    "operations": [
                      {
                        "id": "a",
                        "method": "GET",
                        "path": "/api/v1/docs/technical/api-pricing-guide"
                      },
                      {
                        "id": "b",
                        "method": "GET",
                        "path": "/api/v1/health"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One result per requested operation, in request order.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              },
              "Idempotency-Key": {
                "schema": {
                  "type": "string"
                },
                "description": "Echoes the request header of the same name when one was sent."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed batch body, or more than 20 operations.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only POST is supported at this path.",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "POST"
                }
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. This function keeps no per-key or per-IP counter of its own — it is served from the CDN, and this status comes from the platform's abuse protection in front of it, not from a limit the application enforces. Retry after the advertised window.",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "IETF draft-ietf-httpapi-ratelimit-headers, three-field form (this document does not use the alternate combined RateLimit field). The fair-use ceiling this surface is designed to serve (600 today). Not a per-key metered quota."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always equal to RateLimit-Limit today: this endpoint is CDN-served and the application keeps no per-key or per-IP counter to decrement."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Length, in seconds, of the advertised window (60 today)."
              },
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying (RFC 9110 §10.2.3)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/mcp/v1/attachments/upload": {
      "post": {
        "tags": [
          "Headless MCP"
        ],
        "operationId": "headlessAttachmentUpload",
        "summary": "Upload bytes for a pending attachment",
        "description": "Upload the raw bytes for the ticket returned by attachment_begin_upload. Authenticate with a bearer workspace API key and send the required x-deployhermes-upload-ticket header. The body must contain between 1 and 31457280 bytes (30 MiB); the Content-Type header carries the attachment media type. The ticket is single-use and bound to the workspace, authenticated user, API key, message, metadata, and expiry. It is consumed after storage, so a retry cannot attach the same upload twice. Do not put the ticket in a query parameter or send a caller-supplied storageId; neither is part of this contract.",
        "security": [
          {
            "DeployHermesApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "x-deployhermes-upload-ticket",
            "in": "header",
            "required": true,
            "description": "Single-use ticket returned by attachment_begin_upload. It is bound to the authenticated workspace API key and upload metadata.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary",
                "minLength": 1,
                "maxLength": 31457280,
                "description": "Raw attachment bytes, between 1 and 31457280 bytes (30 MiB)."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Attachment bytes stored and attached to the pending message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HeadlessAttachmentUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "The upload ticket is missing, expired, already used, mismatched, or otherwise rejected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer workspace API key.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"Bearer\" when authentication is required."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body is absent or outside the 1–31457280-byte (30 MiB) bound.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/mcp/v1": {
      "post": {
        "tags": [
          "Headless MCP"
        ],
        "operationId": "headlessMcpJsonRpc",
        "summary": "Call the DeployHermes headless MCP endpoint",
        "description": "Send a JSON-RPC 2.0 request to initialize a sessionless client, acknowledge initialization, discover the tools visible to the API key's scopes, or call one tool. tools/call returns plain-text JSON payloads inside the standard MCP content envelope. Workspace-account, billing, API-key, referral, partner, and project self-improvement tools require manage_workspace plus their functional read, write, or decide scope; project_connection_list and project_connection_select also require manage_connections. Elevated tools return secure browser, device, dashboard, billing-portal, or hosted-checkout handoffs where needed and never expose share tokens, API-key plaintext, or raw provider, channel, or payment secrets.",
        "security": [
          {
            "DeployHermesApiKey": []
          }
        ],
        "x-required-scopes": {
          "initialize": [],
          "notifications/initialized": [],
          "tools/list": [],
          "tools/call": {
            "read": [
              "workspace_status",
              "bot_list",
              "bot_list_archived",
              "bot_get",
              "bot_blockers",
              "mission_board",
              "mission_get",
              "mission_watch",
              "mission_lane_health",
              "mission_search",
              "ticket_list",
              "ticket_get",
              "approval_list",
              "approval_get",
              "chat_read",
              "chat_recent",
              "chat_pending_mentions",
              "doc_folder_list",
              "doc_list",
              "doc_read",
              "doc_mark_read",
              "doc_search",
              "doc_export",
              "run_list",
              "run_get",
              "run_stats",
              "run_receipt",
              "run_calendar",
              "schedule_list",
              "schedule_preview",
              "schedule_upcoming",
              "heartbeat_get",
              "workspace_timezone_get",
              "memory_list",
              "memory_search",
              "memory_get",
              "memory_settings_get",
              "memory_corrections_list",
              "memory_graph",
              "skill_list",
              "skill_read",
              "workflow_list",
              "playbook_list",
              "integration_list",
              "integration_get",
              "integration_history",
              "integration_auth_status",
              "integration_tool_list",
              "provider_list",
              "provider_status",
              "provider_login_status",
              "channel_list",
              "inbox_list",
              "email_thread_list",
              "email_thread_get",
              "email_domain_list",
              "email_rule_list",
              "email_rule_preview",
              "attachment_list",
              "feed_list",
              "feed_mark_seen",
              "notification_list",
              "notification_mark_read",
              "notification_mark_all_read",
              "notification_preferences_get",
              "notification_preferences_update",
              "pin_list",
              "pin_toggle",
              "project_status",
              "project_setup_get",
              "sentry_issue_list",
              "sentry_event_get",
              "datafast_metrics",
              "project_connection_list",
              "project_build_detect",
              "release_list",
              "release_get",
              "release_source_list",
              "outcome_campaign_list",
              "outcome_summary",
              "x_launch_list",
              "x_launch_get",
              "x_launch_accounts",
              "workspace_get",
              "workspace_export",
              "team_list",
              "share_status",
              "share_preflight",
              "credits_status",
              "credits_usage",
              "credits_purchase_history",
              "credits_price_menu",
              "api_key_list",
              "provisioning_status",
              "referral_status",
              "partner_status"
            ],
            "decide": [
              "ticket_answer",
              "ticket_undo",
              "ticket_dismiss",
              "approval_request",
              "approval_confirm",
              "clawhub_install",
              "playbook_install",
              "email_escalation_answer",
              "email_escalation_dismiss",
              "project_merge_approved_ticket",
              "x_launch_approve",
              "x_launch_publish",
              "workspace_request_deletion",
              "share_publish",
              "share_revoke",
              "credits_set_auto_recharge",
              "billing_portal_link",
              "credit_pack_checkout",
              "api_key_create",
              "api_key_revoke",
              "provisioning_retry"
            ],
            "write": [
              "mission_create",
              "mission_update",
              "mission_archive",
              "mission_trash",
              "mission_comment",
              "mission_run_now",
              "mission_retry",
              "mission_accept_result",
              "chat_post",
              "chat_reset",
              "workspace_ask_lead",
              "doc_folder_create",
              "doc_write",
              "doc_move",
              "doc_set_pinned",
              "doc_set_archived",
              "memory_write",
              "memory_update",
              "memory_restore",
              "memory_link",
              "memory_forget",
              "workflow_run",
              "integration_begin_connect",
              "integration_auth_cancel",
              "integration_update",
              "integration_verify",
              "integration_disconnect",
              "integration_set_tool_policy",
              "provider_begin_login",
              "provider_cancel_login",
              "provider_disconnect",
              "provider_reorder",
              "channel_begin_connect",
              "channel_update",
              "channel_configure_slack",
              "channel_test",
              "channel_disconnect",
              "inbox_create",
              "inbox_update",
              "inbox_archive",
              "email_thread_mark_read",
              "email_draft_create",
              "email_draft_update",
              "email_draft_revise",
              "email_draft_discard",
              "email_send_approve",
              "email_send_schedule",
              "email_send_cancel",
              "email_domain_add",
              "email_domain_verify",
              "email_domain_remove",
              "email_rule_add",
              "email_rule_remove",
              "attachment_begin_upload",
              "attachment_remove",
              "project_connection_select",
              "project_connections_confirm",
              "project_resource_mapping_save",
              "project_goals_save",
              "project_build_contract_confirm",
              "project_controls_confirm",
              "project_config_update",
              "project_execution_agent_set",
              "project_build_env_set",
              "project_build_env_remove",
              "project_dry_run_start",
              "project_pause",
              "project_resume",
              "project_refresh",
              "project_propose",
              "release_create",
              "release_update",
              "outcome_campaign_create",
              "outcome_campaign_set_disabled",
              "x_launch_create",
              "x_launch_update",
              "x_launch_publish",
              "x_launch_reconcile",
              "workspace_update",
              "team_invite",
              "team_approve",
              "team_reject",
              "team_change_role",
              "team_remove",
              "share_set_indexing",
              "referral_create_code",
              "partner_enroll"
            ],
            "manage_squad": [
              "bot_hire",
              "bot_update",
              "bot_pause",
              "bot_fire",
              "bot_restore",
              "squad_pause",
              "schedule_create",
              "schedule_update",
              "schedule_set_enabled",
              "schedule_remove",
              "schedule_restore",
              "schedule_bulk_set_enabled",
              "heartbeat_set",
              "workspace_timezone_set",
              "skill_save",
              "skill_update",
              "skill_set_agents",
              "skill_set_disabled",
              "skill_archive",
              "skill_restore",
              "clawhub_search",
              "clawhub_preview",
              "clawhub_install",
              "workflow_save",
              "workflow_archive",
              "workflow_restore",
              "playbook_install",
              "playbook_propose"
            ],
            "manage_workspace": [
              "memory_settings_set",
              "project_status",
              "project_setup_get",
              "project_connection_list",
              "project_connection_select",
              "project_connections_confirm",
              "project_resource_mapping_save",
              "project_goals_save",
              "project_build_contract_confirm",
              "project_controls_confirm",
              "project_config_update",
              "project_execution_agent_set",
              "project_build_detect",
              "project_build_env_set",
              "project_build_env_remove",
              "project_dry_run_start",
              "project_pause",
              "project_resume",
              "project_refresh",
              "project_propose",
              "project_merge_approved_ticket",
              "outcome_summary",
              "workspace_get",
              "workspace_update",
              "workspace_export",
              "workspace_request_deletion",
              "team_list",
              "team_invite",
              "team_approve",
              "team_reject",
              "team_change_role",
              "team_remove",
              "share_status",
              "share_preflight",
              "share_publish",
              "share_revoke",
              "share_set_indexing",
              "credits_status",
              "credits_usage",
              "credits_purchase_history",
              "credits_price_menu",
              "credits_set_auto_recharge",
              "billing_portal_link",
              "credit_pack_checkout",
              "api_key_list",
              "api_key_create",
              "api_key_revoke",
              "provisioning_status",
              "provisioning_retry",
              "referral_status",
              "referral_create_code",
              "partner_status",
              "partner_enroll"
            ],
            "manage_connections": [
              "integration_get",
              "integration_history",
              "integration_begin_connect",
              "integration_auth_status",
              "integration_auth_cancel",
              "integration_update",
              "integration_verify",
              "integration_disconnect",
              "integration_tool_list",
              "integration_set_tool_policy",
              "provider_list",
              "provider_status",
              "provider_begin_login",
              "provider_login_status",
              "provider_cancel_login",
              "provider_disconnect",
              "provider_reorder",
              "channel_list",
              "channel_begin_connect",
              "channel_update",
              "channel_configure_slack",
              "channel_test",
              "channel_disconnect",
              "inbox_list",
              "inbox_create",
              "inbox_update",
              "inbox_archive",
              "email_thread_list",
              "email_thread_get",
              "email_thread_mark_read",
              "email_draft_create",
              "email_draft_update",
              "email_draft_revise",
              "email_draft_discard",
              "email_send_approve",
              "email_send_schedule",
              "email_send_cancel",
              "email_escalation_answer",
              "email_escalation_dismiss",
              "email_domain_list",
              "email_domain_add",
              "email_domain_verify",
              "email_domain_remove",
              "email_rule_list",
              "email_rule_preview",
              "email_rule_add",
              "email_rule_remove",
              "attachment_list",
              "attachment_begin_upload",
              "attachment_remove",
              "sentry_issue_list",
              "sentry_event_get",
              "datafast_metrics",
              "project_connection_list",
              "project_connection_select",
              "project_connections_confirm",
              "project_resource_mapping_save",
              "x_launch_accounts",
              "x_launch_publish",
              "x_launch_reconcile"
            ]
          }
        },
        "x-tool-descriptions": {
          "workspace_status": "Snapshot of the workspace: agent count, queued wakes, and remaining usage credits.",
          "bot_list": "List every agent on the squad, with its status and role.",
          "bot_list_archived": "List removed agents that can still be restored.",
          "bot_get": "One agent's identity, role, persona, status, default model, fallback models, allowed models, timeout, and five most recent tasks.",
          "bot_blockers": "List the latest open ticket raised by each agent.",
          "bot_hire": "Add a new agent onto the squad, without waking it or starting a run.",
          "bot_update": "Edit an existing agent's identity, role, persona, or model policy.",
          "bot_pause": "Pause or resume one agent. A paused agent refuses new wakes.",
          "bot_fire": "Remove an agent from the squad. Its open tasks return to the backlog.",
          "bot_restore": "Restore one removed agent by id. Its old slug stays retired, schedules stay disabled, and backlog tasks stay put.",
          "squad_pause": "Pause or resume every agent in the workspace at once.",
          "mission_board": "Read active, human-blocked, archived, or trashed tasks.",
          "mission_get": "One task in full: body, acceptance criteria, tags, and recent comments.",
          "mission_create": "File a task on the board, optionally assigned to an agent.",
          "mission_update": "Edit a task's title, brief, acceptance criteria, priority, tags, or assignee, including unassigning it.",
          "mission_archive": "Archive a task, or restore it from archive.",
          "mission_trash": "Move a task to recoverable trash, or restore it.",
          "mission_comment": "Post a steering comment and notify the responsible agent.",
          "mission_watch": "Watch or unwatch a task for human notifications.",
          "mission_run_now": "Wake the assigned agent to work a task right now, instead of waiting for its next heartbeat.",
          "ticket_list": "Open decisions waiting on a human.",
          "ticket_get": "One decision in full: its sub-asks, approval action, and approval target.",
          "ticket_answer": "Answer one sub-ask on a decision.",
          "ticket_undo": "Withdraw an answer, if the ticket has not resolved yet.",
          "ticket_dismiss": "Decline a ticket outright, without answering its sub-asks.",
          "approval_list": "Open approval requests with their tier and whether the assistant may approve.",
          "approval_get": "One approval request in full: action, target, tier, exact payload and digest, and a server-written summary.",
          "approval_request": "Start approving one request: returns a single-use five-minute token and a summary to show the user.",
          "approval_confirm": "Grant an approval after the user said yes; some actions are held two minutes and owners are notified.",
          "chat_post": "Post into the squad channel or one agent's direct-message thread.",
          "chat_read": "Read recent messages from the squad channel or one agent's DM thread.",
          "chat_pending_mentions": "List unread squad mentions waiting for each live agent.",
          "chat_reset": "Clear one direct-message view without deleting its retained history.",
          "workspace_ask_lead": "Send an unstructured request to the lead or another available agent.",
          "doc_list": "List docs in the workspace, including folder, pin, and archive state filters when present.",
          "doc_read": "Read one doc in full by id, including its current folder and lifecycle metadata.",
          "doc_search": "Search the workspace's docs.",
          "doc_write": "Create a doc, or update it if the title already exists.",
          "doc_folder_list": "List every doc folder in the workspace.",
          "doc_folder_create": "Create a new doc folder.",
          "doc_move": "Move a doc into a folder or back to the unfiled root.",
          "doc_set_pinned": "Pin or unpin one doc.",
          "doc_set_archived": "Archive or restore one doc without deleting it.",
          "doc_export": "Export one doc's current content and metadata.",
          "run_list": "List recent agent runs, filterable by agent, trigger, or outcome.",
          "run_get": "One run's summary: status, trigger, timing, and any error.",
          "run_stats": "Read thirty-day run totals, failures, costs, and usage credits.",
          "run_receipt": "Read one run's redacted tool-call and progress receipt.",
          "run_calendar": "List runs inside an exact time window, optionally for one agent.",
          "schedule_list": "List every schedule in the workspace.",
          "schedule_create": "Create a recurring schedule that wakes one agent on a cadence. Creating it consumes one wake slot because it commits the key to future automated wakes.",
          "schedule_update": "Edit an existing schedule.",
          "schedule_set_enabled": "Turn a schedule on or off without deleting it.",
          "schedule_remove": "Soft-remove a schedule. It stops firing and drops off schedule_list.",
          "schedule_restore": "Restore a soft-removed schedule in the off state.",
          "schedule_preview": "Preview one agent's active cadence overlap.",
          "schedule_upcoming": "List upcoming schedule and heartbeat occurrences.",
          "schedule_bulk_set_enabled": "Enable or disable schedules and heartbeats in bulk.",
          "heartbeat_get": "Read heartbeat cadence and state for one agent or the live squad.",
          "heartbeat_set": "Set, enable, disable, or remove one agent's heartbeat.",
          "workspace_timezone_get": "Read the workspace timezone used by schedules and calendars.",
          "workspace_timezone_set": "Set the owner-only workspace timezone and re-anchor timers.",
          "memory_list": "Facts the squad has learned recently, with forgotten facts available when requested.",
          "memory_search": "Search remembered facts by text.",
          "memory_get": "Read one remembered fact by id, optionally including forgotten ones.",
          "memory_settings_get": "Read whether implicit memory learning is enabled for this workspace.",
          "memory_write": "Write a new remembered fact.",
          "memory_update": "Correct one remembered fact's value.",
          "memory_forget": "Soft-forget one remembered fact. It stays restorable from the dashboard.",
          "memory_restore": "Restore one forgotten fact if its normalized key is still free.",
          "memory_link": "Link two remembered entities with a named relation.",
          "memory_graph": "Read a bounded graph of remembered entities and their links.",
          "skill_list": "List workspace skills, including archived ones when requested.",
          "skill_read": "Read one skill in full by the exact name shown in skill_list.",
          "skill_save": "Create a new workspace skill.",
          "skill_update": "Edit one saved workspace skill.",
          "skill_set_agents": "Replace the full agent assignment set for one skill.",
          "skill_set_disabled": "Disable or re-enable one skill without archiving it.",
          "skill_archive": "Archive one workspace skill.",
          "skill_restore": "Restore one archived workspace skill.",
          "clawhub_search": "Search ClawHub for installable skills, excluding blocked entries.",
          "clawhub_preview": "Fetch one ClawHub skill release, its parsed draft, scan verdict, source URL, and truncation state.",
          "clawhub_install": "Install one reviewed ClawHub skill release with decide and manage_squad after a server-side refetch and safety check. It starts unassigned.",
          "workflow_list": "List workspace workflows, including archived ones when requested.",
          "workflow_save": "Create or update a saved workflow definition for one agent.",
          "workflow_run": "Queue one workflow to run now. Consumes one wake slot because it starts a model run.",
          "workflow_archive": "Archive one workflow.",
          "workflow_restore": "Restore one archived workflow.",
          "playbook_list": "List the playbooks DeployHermes can install into this workspace.",
          "playbook_install": "Direct-install one reviewed playbook with decide and manage_squad after planner checks. It consumes one wake slot and may create schedules that use the workspace owner's own provider subscription.",
          "project_status": "Read the current project self-improvement status: setup, selected connections, pause state, and pending project work.",
          "project_setup_get": "Read the current project setup, goals, controls, mapping, and non-secret configuration.",
          "sentry_issue_list": "List one privacy-bounded page of recent Sentry issues for the selected project and follow nextCursor for complete pagination.",
          "sentry_event_get": "Read allowlisted diagnosis fields for one Sentry issue event without user identity, request bodies, credentials, or unrestricted raw payloads.",
          "datafast_metrics": "Read paginated website, visitor, and conversion-goal aggregates for the selected DataFast website without visitor identities or credentials.",
          "project_connection_list": "List the repository or deployment connections available to project self-improvement without exposing provider secrets.",
          "project_connection_select": "Select which available project connection the self-improvement loop should use; requires elevated workspace and connection authority.",
          "project_config_update": "Update the project's non-secret self-improvement configuration, goals, controls, or repository mapping.",
          "project_execution_agent_set": "Give one live workspace agent the existing code-engineer repository capability without changing its role, persona, or model policy.",
          "project_build_detect": "Inspect the selected repository and detect the build, install, and test commands the project is likely to need.",
          "project_build_env_set": "Set or rotate one named project build environment variable without ever returning its value.",
          "project_build_env_remove": "Remove one named project build environment variable without revealing the deleted value.",
          "project_dry_run_start": "Start a bounded project self-improvement dry run against the selected repository and configuration.",
          "project_pause": "Pause the project self-improvement loop so refreshes and proposes stop waking agents.",
          "project_resume": "Resume a paused project self-improvement loop.",
          "project_refresh": "Wake a full agent run to refresh project evidence, repository state, and operational status.",
          "project_propose": "Wake a full agent run to prepare the next proposed project improvement from current evidence.",
          "project_merge_approved_ticket": "Merge the change already bound to an explicit approved ticket; this does not bypass human approval.",
          "workspace_get": "Read the workspace's identity, lifecycle, public-sharing flags, timezone, and provisioning summary without exposing secrets.",
          "workspace_update": "Rename the workspace. Region changes stay support-operated and are read-only here.",
          "workspace_export": "Export a paged workspace snapshot for offline review without opening the signed-in dashboard.",
          "workspace_request_deletion": "Queue workspace deletion after typed-name confirmation and exact approval; returns the scheduled purge window, not an immediate hard delete.",
          "team_list": "List current and pending workspace members with their roles.",
          "team_invite": "Invite a workspace member with a selected role. Owner invites require exact approval.",
          "team_approve": "Approve a pending workspace member request with a selected role. Granting owner requires exact approval.",
          "team_reject": "Reject a pending workspace member request.",
          "team_change_role": "Change one workspace member's role. Ownership changes require exact approval.",
          "team_remove": "Remove a workspace member. Removing an owner requires exact approval.",
          "share_status": "Read public-sharing state, expiry, indexing choice, and publishable counts without returning the share token itself.",
          "share_preflight": "Scan the selected board or docs share for publishable titles and possible secret exposure before approval.",
          "share_publish": "Request public sharing after exact approval and return a secure dashboard handoff; MCP does not return the share token itself.",
          "share_revoke": "Revoke the public sharing link after exact approval and return a secure dashboard handoff.",
          "share_set_indexing": "Allow or block search-engine indexing for the published workspace share.",
          "credits_status": "Read the workspace's current usage-credit balance and billing state.",
          "credits_usage": "Read workspace usage-credit usage windows and recent spend breakdowns.",
          "credits_purchase_history": "Read recent usage-credit purchases without exposing payment-provider identifiers or secrets.",
          "credits_set_auto_recharge": "Change automatic usage-credit purchase settings after exact approval, including threshold and monthly cap.",
          "billing_portal_link": "Return a safe hosted billing-portal URL for this workspace; MCP does not expose payment method secrets.",
          "credit_pack_checkout": "Open a hosted one-pack usage-credit checkout after exact approval and return only the checkout URL.",
          "api_key_list": "List workspace API keys and their non-secret metadata, scopes, and recent usage.",
          "api_key_create": "Request API-key creation after exact approval and return a secure dashboard handoff; MCP never returns plaintext key material.",
          "api_key_revoke": "Revoke one workspace API key after exact approval without ever revealing its plaintext.",
          "provisioning_status": "Read the workspace's provisioning progress and current lifecycle state.",
          "provisioning_retry": "Retry a failed workspace provisioning attempt after exact approval.",
          "referral_status": "Read the issuing member's referral summary and current workspace referral state.",
          "referral_create_code": "Create the issuing member's referral code if needed, or return the existing code.",
          "partner_status": "Read the workspace's partner-program summary and current status.",
          "partner_enroll": "Enroll the workspace into the partner program when it is eligible.",
          "integration_list": "List the integration catalog and any current connection statuses. Metadata only; never credentials.",
          "integration_get": "Read one integration's non-secret configuration and connection status; credentials are never returned.",
          "integration_history": "Read the audit history for one integration without exposing provider or channel secrets.",
          "integration_begin_connect": "Begin an integration connection and return a secure browser or device authorization handoff, never a raw secret field.",
          "integration_auth_status": "Poll a connection handoff's status and return non-secret progress or the completed connection label.",
          "integration_auth_cancel": "Cancel a pending integration authorization handoff.",
          "integration_update": "Update an integration's non-secret settings; use its secure browser or device handoff for credentials.",
          "integration_verify": "Verify one connected integration and return non-secret health evidence.",
          "integration_disconnect": "Disconnect one integration and revoke its stored connection; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "integration_tool_list": "List the tools enabled for one active custom MCP integration; built-in providers use their provider-specific read tools.",
          "integration_set_tool_policy": "Set the enabled-tool policy for one connected integration.",
          "provider_list": "List supported model providers and non-secret connection state.",
          "provider_status": "Read one model provider's non-secret connection status and account label.",
          "provider_begin_login": "Begin provider login and return a secure browser or device authorization handoff, never a raw provider key.",
          "provider_login_status": "Poll a provider login handoff and return non-secret progress or the completed account label.",
          "provider_cancel_login": "Cancel a pending provider login handoff.",
          "provider_disconnect": "Disconnect a model provider and revoke its stored credential; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "provider_reorder": "Change the workspace's model provider fallback order.",
          "channel_list": "List supported communication channels and non-secret connection state.",
          "channel_begin_connect": "Begin channel connection and return a secure browser or device authorization handoff, never a raw channel token.",
          "channel_update": "Update a channel's non-secret settings; use its secure authorization handoff for credentials.",
          "channel_test": "Send a bounded test through a connected channel and return non-secret delivery status.",
          "channel_disconnect": "Disconnect a communication channel and revoke its stored connection; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "inbox_list": "List workspace inboxes and their non-secret routing state.",
          "inbox_create": "Create a workspace inbox with its non-secret routing settings.",
          "inbox_update": "Update a workspace inbox's routing and presentation settings.",
          "inbox_archive": "Archive or restore a workspace inbox without deleting its retained messages; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_thread_list": "List email threads available to the workspace.",
          "email_thread_get": "Read one email thread and its messages, subject to the workspace policy.",
          "email_thread_mark_read": "Mark one email thread read or unread.",
          "email_draft_create": "Create an email draft without sending it.",
          "email_draft_update": "Update an unsent email draft.",
          "email_draft_revise": "Revise an email draft using the requested changes without sending it.",
          "email_draft_discard": "Discard an email draft without sending it.",
          "email_send_approve": "Approve an email draft for sending through the connected email channel; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_send_schedule": "Schedule an approved email draft for sending through the connected channel; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_send_cancel": "Cancel a scheduled email send before delivery; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_escalation_answer": "Answer an email escalation that is waiting for human direction.",
          "email_escalation_dismiss": "Dismiss an email escalation without sending a message.",
          "email_domain_list": "List configured sending domains and their non-secret verification state.",
          "email_domain_add": "Begin adding a sending domain and return the required non-secret DNS records; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_domain_verify": "Verify a sending domain's published DNS records.",
          "email_domain_remove": "Remove a configured sending domain; requires a payload-bound, single-use approval issued by an authenticated human session.",
          "email_rule_list": "List email routing and handling rules.",
          "email_rule_add": "Add an email routing or handling rule.",
          "email_rule_remove": "Remove an email routing or handling rule.",
          "attachment_list": "List attachments available to the workspace without exposing their contents by default.",
          "attachment_begin_upload": "Begin an attachment upload and return a secure dashboard handoff or upload target; do not pass provider secrets through MCP.",
          "attachment_remove": "Remove one workspace attachment.",
          "feed_list": "Read recent workspace activity and the caller's away summary.",
          "feed_mark_seen": "Mark the activity feed seen for the API key's issuing member.",
          "notification_list": "List recent notifications for the API key's issuing member.",
          "notification_mark_read": "Mark one owned notification read.",
          "notification_mark_all_read": "Mark the issuing member's unread notifications read in a batch.",
          "notification_preferences_get": "Read every notification type and its mute state.",
          "notification_preferences_update": "Mute or unmute one notification type.",
          "pin_list": "List the issuing member's personal board pins.",
          "pin_toggle": "Pin or unpin one task, doc, email, or reminder.",
          "mission_retry": "Retry a task whose work hit a terminal failure, keeping its original brief and checkpoint.",
          "mission_accept_result": "Accept a completed task's linked result doc as its outcome, after checking the doc and brief have not changed.",
          "mission_lane_health": "Whether backlog tasks will actually be picked up: none, agents_paused, or no_consumer.",
          "mission_search": "Find live tasks by title or brief text.",
          "chat_recent": "Recent direct-message conversations, newest first, one row per agent with a preview.",
          "doc_mark_read": "Mark a doc read for the API key's issuing member, which clears its unread badge.",
          "memory_settings_set": "Turn implicit memory learning on or off for the workspace.",
          "memory_corrections_list": "The newest recorded corrections, each with its scope and the preference it was promoted into, if any.",
          "playbook_propose": "Propose installing one built-in playbook by opening an approval ticket; nothing installs until a person approves.",
          "channel_configure_slack": "Bind a connected Slack workspace to one channel with a default agent and the Slack users allowed to reach it.",
          "email_rule_preview": "Check whether an address would be allowed for an agent under the live allow and block rules. Sends nothing.",
          "project_connections_confirm": "Setup step 1: link the active GitHub and Vercel connections to the project config.",
          "project_resource_mapping_save": "Setup step 2: save the selected GitHub repository, Vercel project, and production domain, then check them against the providers.",
          "project_goals_save": "Setup step 3: choose the evidence source, locale, competitors, protected claims, and concurrency limit, and create the project goals.",
          "project_build_contract_confirm": "Setup step 4: save and confirm the build contract with its install, build, test, lint, and typecheck commands.",
          "project_controls_confirm": "Setup step 5: accept the default project controls for approvals, remediation pull-request cap, and rollback.",
          "release_list": "List releases, newest first, with each one's current revision id.",
          "release_get": "Read one release revision with its recorded evidence, the live evidence now, missing content, and whether it can claim live.",
          "release_source_list": "List the most recent experiments that can be the source of a release.",
          "release_create": "Create a release record bound to an experiment, with its first revision. Nothing is published.",
          "release_update": "Edit a release by appending a revision; refused as stale if the expected revision is not current.",
          "outcome_campaign_list": "List outcome-tracking campaigns with their release binding, disabled flag, click count, and public landing URL.",
          "outcome_campaign_create": "Create a tracking campaign bound to one saved release revision, or return the existing one for the same binding.",
          "outcome_campaign_set_disabled": "Disable a campaign so its landing link stops counting clicks, or enable it again.",
          "outcome_summary": "Aggregate clicks, signups, confirmed payers, and first accepted results for one campaign over 7 or 28 days. Counts only.",
          "x_launch_list": "List X launch drafts, newest first, with their delivery state.",
          "x_launch_get": "Read one X launch draft with its current revision, delivery attempts, and recorded approvals. Never includes the X credential.",
          "x_launch_accounts": "List the connected X accounts a launch post can use, as ids and labels only.",
          "x_launch_create": "Create an X launch draft tied to a saved release revision, with a tracked link. Nothing is posted.",
          "x_launch_update": "Edit an X launch draft by appending a revision, which discards any earlier approval.",
          "x_launch_approve": "Approve one exact X draft revision for publishing, through an approval ticket a person answers in the web app.",
          "x_launch_publish": "Publish an approved X draft revision to the connected X account. A public post that cannot be recalled.",
          "x_launch_reconcile": "Resolve an uncertain publish by entering the numeric X post id after the server verifies it.",
          "credits_price_menu": "List what each metered tool or call type costs in usage credits. A static price list that spends nothing extra."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/McpJsonRpcRequest"
              },
              "examples": {
                "initialize": {
                  "summary": "Negotiate the protocol version",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "initialize",
                    "params": {
                      "protocolVersion": "2025-11-25"
                    }
                  }
                },
                "toolsList": {
                  "summary": "List the available tools",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/list",
                    "params": {}
                  }
                },
                "toolsCall": {
                  "summary": "Call one tool",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 3,
                    "method": "tools/call",
                    "params": {
                      "name": "bot_list",
                      "arguments": {}
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful initialize, tools/list, or tools/call result.",
            "headers": {
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594. Present only once an operation is deprecated (\"true\", or a deprecation date). Absent — as on every operation in this document today — means fully supported."
              },
              "Sunset": {
                "schema": {
                  "type": "string",
                  "format": "date-time"
                },
                "description": "RFC 8594. Present alongside Deprecation once an operation is deprecated, naming the date it stops answering. Absent today."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpJsonRpcSuccessResponse"
                }
              }
            }
          },
          "202": {
            "description": "The client sent notifications/initialized: a JSON-RPC *notification* (no `id`), which by the JSON-RPC 2.0 spec has no response and nothing to correlate one to. This 202 is a fire-and-forget receipt, not the first step of a long-running job — there is no job id in it, nothing to poll, and no follow-up request this endpoint expects. Contrast tools/call, which always returns its result inline in the 200 body above: DeployHermes has no asynchronous job or polling endpoint anywhere in this API."
          },
          "400": {
            "description": "Malformed JSON-RPC payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid bearer API key.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"Bearer\" when authentication is required."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Workspace has insufficient usage credits for the requested tool call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-key wake rate limit exceeded for a wake-triggering tool call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "DeployHermesApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "dh_live_*",
        "description": "Create a workspace API key in the signed-in app at https://deploy-hermes.com/settings/api-keys.\nKeys are restricted to the selected scopes and the issuing member's live workspace capabilities; DeployHermes re-checks both on every tools/call request.\nThe published https://deploy-hermes.com/mcp/v1 endpoint is a Vercel proxy; deployment must set CONVEX_SITE_URL to the live Convex origin it forwards to. API-key issuance may return the direct configured endpoint instead.\nHeadless scope map:\nread: workspace_status, bot_list, bot_list_archived, bot_get, bot_blockers, mission_board, mission_get, mission_watch, mission_lane_health, mission_search, ticket_list, ticket_get, approval_list, approval_get, chat_read, chat_recent, chat_pending_mentions, doc_folder_list, doc_list, doc_read, doc_mark_read, doc_search, doc_export, run_list, run_get, run_stats, run_receipt, run_calendar, schedule_list, schedule_preview, schedule_upcoming, heartbeat_get, workspace_timezone_get, memory_list, memory_search, memory_get, memory_settings_get, memory_corrections_list, memory_graph, skill_list, skill_read, workflow_list, playbook_list, integration_list, integration_get, integration_history, integration_auth_status, integration_tool_list, provider_list, provider_status, provider_login_status, channel_list, inbox_list, email_thread_list, email_thread_get, email_domain_list, email_rule_list, email_rule_preview, attachment_list, feed_list, feed_mark_seen, notification_list, notification_mark_read, notification_mark_all_read, notification_preferences_get, notification_preferences_update, pin_list, pin_toggle, project_status, project_setup_get, sentry_issue_list, sentry_event_get, datafast_metrics, project_connection_list, project_build_detect, release_list, release_get, release_source_list, outcome_campaign_list, outcome_summary, x_launch_list, x_launch_get, x_launch_accounts, workspace_get, workspace_export, team_list, share_status, share_preflight, credits_status, credits_usage, credits_purchase_history, credits_price_menu, api_key_list, provisioning_status, referral_status, partner_status\ndecide: ticket_answer, ticket_undo, ticket_dismiss, approval_request, approval_confirm, clawhub_install, playbook_install, email_escalation_answer, email_escalation_dismiss, project_merge_approved_ticket, x_launch_approve, x_launch_publish, workspace_request_deletion, share_publish, share_revoke, credits_set_auto_recharge, billing_portal_link, credit_pack_checkout, api_key_create, api_key_revoke, provisioning_retry\nwrite: mission_create, mission_update, mission_archive, mission_trash, mission_comment, mission_run_now, mission_retry, mission_accept_result, chat_post, chat_reset, workspace_ask_lead, doc_folder_create, doc_write, doc_move, doc_set_pinned, doc_set_archived, memory_write, memory_update, memory_restore, memory_link, memory_forget, workflow_run, integration_begin_connect, integration_auth_cancel, integration_update, integration_verify, integration_disconnect, integration_set_tool_policy, provider_begin_login, provider_cancel_login, provider_disconnect, provider_reorder, channel_begin_connect, channel_update, channel_configure_slack, channel_test, channel_disconnect, inbox_create, inbox_update, inbox_archive, email_thread_mark_read, email_draft_create, email_draft_update, email_draft_revise, email_draft_discard, email_send_approve, email_send_schedule, email_send_cancel, email_domain_add, email_domain_verify, email_domain_remove, email_rule_add, email_rule_remove, attachment_begin_upload, attachment_remove, project_connection_select, project_connections_confirm, project_resource_mapping_save, project_goals_save, project_build_contract_confirm, project_controls_confirm, project_config_update, project_execution_agent_set, project_build_env_set, project_build_env_remove, project_dry_run_start, project_pause, project_resume, project_refresh, project_propose, release_create, release_update, outcome_campaign_create, outcome_campaign_set_disabled, x_launch_create, x_launch_update, x_launch_publish, x_launch_reconcile, workspace_update, team_invite, team_approve, team_reject, team_change_role, team_remove, share_set_indexing, referral_create_code, partner_enroll\nmanage_squad: bot_hire, bot_update, bot_pause, bot_fire, bot_restore, squad_pause, schedule_create, schedule_update, schedule_set_enabled, schedule_remove, schedule_restore, schedule_bulk_set_enabled, heartbeat_set, workspace_timezone_set, skill_save, skill_update, skill_set_agents, skill_set_disabled, skill_archive, skill_restore, clawhub_search, clawhub_preview, clawhub_install, workflow_save, workflow_archive, workflow_restore, playbook_install, playbook_propose\nmanage_workspace: memory_settings_set, project_status, project_setup_get, project_connection_list, project_connection_select, project_connections_confirm, project_resource_mapping_save, project_goals_save, project_build_contract_confirm, project_controls_confirm, project_config_update, project_execution_agent_set, project_build_detect, project_build_env_set, project_build_env_remove, project_dry_run_start, project_pause, project_resume, project_refresh, project_propose, project_merge_approved_ticket, outcome_summary, workspace_get, workspace_update, workspace_export, workspace_request_deletion, team_list, team_invite, team_approve, team_reject, team_change_role, team_remove, share_status, share_preflight, share_publish, share_revoke, share_set_indexing, credits_status, credits_usage, credits_purchase_history, credits_price_menu, credits_set_auto_recharge, billing_portal_link, credit_pack_checkout, api_key_list, api_key_create, api_key_revoke, provisioning_status, provisioning_retry, referral_status, referral_create_code, partner_status, partner_enroll\nmanage_connections: integration_get, integration_history, integration_begin_connect, integration_auth_status, integration_auth_cancel, integration_update, integration_verify, integration_disconnect, integration_tool_list, integration_set_tool_policy, provider_list, provider_status, provider_begin_login, provider_login_status, provider_cancel_login, provider_disconnect, provider_reorder, channel_list, channel_begin_connect, channel_update, channel_configure_slack, channel_test, channel_disconnect, inbox_list, inbox_create, inbox_update, inbox_archive, email_thread_list, email_thread_get, email_thread_mark_read, email_draft_create, email_draft_update, email_draft_revise, email_draft_discard, email_send_approve, email_send_schedule, email_send_cancel, email_escalation_answer, email_escalation_dismiss, email_domain_list, email_domain_add, email_domain_verify, email_domain_remove, email_rule_list, email_rule_preview, email_rule_add, email_rule_remove, attachment_list, attachment_begin_upload, attachment_remove, sentry_issue_list, sentry_event_get, datafast_metrics, project_connection_list, project_connection_select, project_connections_confirm, project_resource_mapping_save, x_launch_accounts, x_launch_publish, x_launch_reconcile\nmanage_workspace and manage_connections are explicitly selected elevated scopes. Ordinary or legacy keys do not inherit either one; connection tools need manage_connections, and workspace-account, billing, API-key, referral, partner, and project self-improvement tools need manage_workspace.",
        "x-scopes": {
          "read": "Read workspace state and manage personal feed, notification, preference, watch, and pin state.",
          "decide": "Resolve, undo, or dismiss a ticket. Direct ClawHub and playbook installs also require this scope with manage_squad; destructive, publication, financial, credential, provisioning, and approved-merge workspace flows also require manage_workspace.",
          "write": "Create, steer, trash, or change tasks; post and reset chat; ask the lead; manage docs and memory; run workflows; and, when manage_workspace is also present, update workspace settings, team, sharing, referral or partner state, and write-scoped project self-improvement tools.",
          "manage_squad": "Add, update, pause, remove, or restore agents; pause the squad; manage schedules, heartbeats, timezone, workspace skills, workflow definitions, and direct installs when decide is also present.",
          "manage_workspace": "Explicitly selected elevated workspace-account, billing, credential, and project authority. Required for workspace account, team, sharing, billing, API-key, provisioning, referral, partner, and project self-improvement tools together with each tool's functional read, write, or decide scope. Share and API-key creation flows use secure dashboard handoffs, billing tools use hosted portal or checkout URLs, and legacy or ordinary keys do not inherit this scope.",
          "manage_connections": "Elevated integration and communication authority. Each connection tool also requires its functional read, write, or decide scope; project_connection_list and project_connection_select additionally require manage_workspace. Connection tools return secure browser or device handoffs; raw provider or channel secrets never pass through MCP."
        }
      }
    },
    "schemas": {
      "JsonRpcId": {
        "oneOf": [
          {
            "type": "integer"
          },
          {
            "type": "string"
          }
        ]
      },
      "McpJsonRpcRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/InitializeRequest"
          },
          {
            "$ref": "#/components/schemas/InitializedNotification"
          },
          {
            "$ref": "#/components/schemas/ToolsListRequest"
          },
          {
            "$ref": "#/components/schemas/ToolsCallRequest"
          }
        ]
      },
      "McpJsonRpcSuccessResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/InitializeResponse"
          },
          {
            "$ref": "#/components/schemas/ToolsListResponse"
          },
          {
            "$ref": "#/components/schemas/ToolsCallResponse"
          },
          {
            "$ref": "#/components/schemas/JsonRpcErrorResponse"
          }
        ]
      },
      "InitializeRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "method": {
            "type": "string",
            "const": "initialize"
          },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "protocolVersion": {
                "type": "string",
                "description": "Requested MCP protocol version. Unsupported values are negotiated to 2025-11-25.",
                "examples": [
                  "2025-11-25",
                  "2025-06-18",
                  "2025-03-26"
                ]
              }
            }
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method"
        ]
      },
      "InitializedNotification": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "method": {
            "type": "string",
            "const": "notifications/initialized"
          }
        },
        "required": [
          "jsonrpc",
          "method"
        ]
      },
      "ToolsListRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "method": {
            "type": "string",
            "const": "tools/list"
          },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "properties": {}
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method"
        ]
      },
      "ToolsCallRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "method": {
            "type": "string",
            "const": "tools/call"
          },
          "params": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "enum": [
                  "workspace_status",
                  "bot_list",
                  "bot_list_archived",
                  "bot_get",
                  "bot_blockers",
                  "bot_hire",
                  "bot_update",
                  "bot_pause",
                  "bot_fire",
                  "bot_restore",
                  "squad_pause",
                  "mission_board",
                  "mission_get",
                  "mission_create",
                  "mission_update",
                  "mission_archive",
                  "mission_trash",
                  "mission_comment",
                  "mission_watch",
                  "mission_run_now",
                  "mission_retry",
                  "mission_accept_result",
                  "mission_lane_health",
                  "mission_search",
                  "ticket_list",
                  "ticket_get",
                  "ticket_answer",
                  "ticket_undo",
                  "ticket_dismiss",
                  "approval_list",
                  "approval_get",
                  "approval_request",
                  "approval_confirm",
                  "chat_post",
                  "chat_read",
                  "chat_recent",
                  "chat_pending_mentions",
                  "chat_reset",
                  "workspace_ask_lead",
                  "doc_folder_list",
                  "doc_folder_create",
                  "doc_list",
                  "doc_read",
                  "doc_mark_read",
                  "doc_search",
                  "doc_write",
                  "doc_move",
                  "doc_set_pinned",
                  "doc_set_archived",
                  "doc_export",
                  "run_list",
                  "run_get",
                  "run_stats",
                  "run_receipt",
                  "run_calendar",
                  "schedule_list",
                  "schedule_create",
                  "schedule_update",
                  "schedule_set_enabled",
                  "schedule_remove",
                  "schedule_restore",
                  "schedule_preview",
                  "schedule_upcoming",
                  "schedule_bulk_set_enabled",
                  "heartbeat_get",
                  "heartbeat_set",
                  "workspace_timezone_get",
                  "workspace_timezone_set",
                  "memory_list",
                  "memory_search",
                  "memory_get",
                  "memory_settings_get",
                  "memory_settings_set",
                  "memory_corrections_list",
                  "memory_write",
                  "memory_update",
                  "memory_restore",
                  "memory_link",
                  "memory_graph",
                  "memory_forget",
                  "skill_list",
                  "skill_read",
                  "skill_save",
                  "skill_update",
                  "skill_set_agents",
                  "skill_set_disabled",
                  "skill_archive",
                  "skill_restore",
                  "clawhub_search",
                  "clawhub_preview",
                  "clawhub_install",
                  "workflow_list",
                  "workflow_save",
                  "workflow_run",
                  "workflow_archive",
                  "workflow_restore",
                  "playbook_list",
                  "playbook_install",
                  "playbook_propose",
                  "integration_list",
                  "integration_get",
                  "integration_history",
                  "integration_begin_connect",
                  "integration_auth_status",
                  "integration_auth_cancel",
                  "integration_update",
                  "integration_verify",
                  "integration_disconnect",
                  "integration_tool_list",
                  "integration_set_tool_policy",
                  "provider_list",
                  "provider_status",
                  "provider_begin_login",
                  "provider_login_status",
                  "provider_cancel_login",
                  "provider_disconnect",
                  "provider_reorder",
                  "channel_list",
                  "channel_begin_connect",
                  "channel_update",
                  "channel_configure_slack",
                  "channel_test",
                  "channel_disconnect",
                  "inbox_list",
                  "inbox_create",
                  "inbox_update",
                  "inbox_archive",
                  "email_thread_list",
                  "email_thread_get",
                  "email_thread_mark_read",
                  "email_draft_create",
                  "email_draft_update",
                  "email_draft_revise",
                  "email_draft_discard",
                  "email_send_approve",
                  "email_send_schedule",
                  "email_send_cancel",
                  "email_escalation_answer",
                  "email_escalation_dismiss",
                  "email_domain_list",
                  "email_domain_add",
                  "email_domain_verify",
                  "email_domain_remove",
                  "email_rule_list",
                  "email_rule_preview",
                  "email_rule_add",
                  "email_rule_remove",
                  "attachment_list",
                  "attachment_begin_upload",
                  "attachment_remove",
                  "feed_list",
                  "feed_mark_seen",
                  "notification_list",
                  "notification_mark_read",
                  "notification_mark_all_read",
                  "notification_preferences_get",
                  "notification_preferences_update",
                  "pin_list",
                  "pin_toggle",
                  "project_status",
                  "project_setup_get",
                  "sentry_issue_list",
                  "sentry_event_get",
                  "datafast_metrics",
                  "project_connection_list",
                  "project_connection_select",
                  "project_connections_confirm",
                  "project_resource_mapping_save",
                  "project_goals_save",
                  "project_build_contract_confirm",
                  "project_controls_confirm",
                  "project_config_update",
                  "project_execution_agent_set",
                  "project_build_detect",
                  "project_build_env_set",
                  "project_build_env_remove",
                  "project_dry_run_start",
                  "project_pause",
                  "project_resume",
                  "project_refresh",
                  "project_propose",
                  "project_merge_approved_ticket",
                  "release_list",
                  "release_get",
                  "release_source_list",
                  "release_create",
                  "release_update",
                  "outcome_campaign_list",
                  "outcome_campaign_create",
                  "outcome_campaign_set_disabled",
                  "outcome_summary",
                  "x_launch_list",
                  "x_launch_get",
                  "x_launch_accounts",
                  "x_launch_create",
                  "x_launch_update",
                  "x_launch_approve",
                  "x_launch_publish",
                  "x_launch_reconcile",
                  "workspace_get",
                  "workspace_update",
                  "workspace_export",
                  "workspace_request_deletion",
                  "team_list",
                  "team_invite",
                  "team_approve",
                  "team_reject",
                  "team_change_role",
                  "team_remove",
                  "share_status",
                  "share_preflight",
                  "share_publish",
                  "share_revoke",
                  "share_set_indexing",
                  "credits_status",
                  "credits_usage",
                  "credits_purchase_history",
                  "credits_price_menu",
                  "credits_set_auto_recharge",
                  "billing_portal_link",
                  "credit_pack_checkout",
                  "api_key_list",
                  "api_key_create",
                  "api_key_revoke",
                  "provisioning_status",
                  "provisioning_retry",
                  "referral_status",
                  "referral_create_code",
                  "partner_status",
                  "partner_enroll"
                ],
                "description": "Tool name from tools/list."
              },
              "arguments": {
                "type": "object",
                "description": "Tool-specific arguments object. Read the live tools/list response for the named tool's full input schema. Connection tools do not accept raw provider, channel, email, or other credential secrets; use the secure browser, device, or dashboard handoff they return.",
                "additionalProperties": true
              }
            },
            "required": [
              "name"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "method",
          "params"
        ]
      },
      "InitializeResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "protocolVersion": {
                "type": "string",
                "enum": [
                  "2025-11-25",
                  "2025-06-18",
                  "2025-03-26"
                ]
              },
              "capabilities": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "tools": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {}
                  }
                },
                "required": [
                  "tools"
                ]
              },
              "serverInfo": {
                "type": "object",
                "additionalProperties": true,
                "description": "Server name and version metadata."
              },
              "instructions": {
                "type": "string",
                "description": "Operator guidance, including call pricing, free workspace_status, and wake-triggering cautions."
              }
            },
            "required": [
              "protocolVersion",
              "capabilities",
              "serverInfo",
              "instructions"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "result"
        ]
      },
      "HeadlessTool": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "workspace_status",
              "bot_list",
              "bot_list_archived",
              "bot_get",
              "bot_blockers",
              "bot_hire",
              "bot_update",
              "bot_pause",
              "bot_fire",
              "bot_restore",
              "squad_pause",
              "mission_board",
              "mission_get",
              "mission_create",
              "mission_update",
              "mission_archive",
              "mission_trash",
              "mission_comment",
              "mission_watch",
              "mission_run_now",
              "mission_retry",
              "mission_accept_result",
              "mission_lane_health",
              "mission_search",
              "ticket_list",
              "ticket_get",
              "ticket_answer",
              "ticket_undo",
              "ticket_dismiss",
              "approval_list",
              "approval_get",
              "approval_request",
              "approval_confirm",
              "chat_post",
              "chat_read",
              "chat_recent",
              "chat_pending_mentions",
              "chat_reset",
              "workspace_ask_lead",
              "doc_folder_list",
              "doc_folder_create",
              "doc_list",
              "doc_read",
              "doc_mark_read",
              "doc_search",
              "doc_write",
              "doc_move",
              "doc_set_pinned",
              "doc_set_archived",
              "doc_export",
              "run_list",
              "run_get",
              "run_stats",
              "run_receipt",
              "run_calendar",
              "schedule_list",
              "schedule_create",
              "schedule_update",
              "schedule_set_enabled",
              "schedule_remove",
              "schedule_restore",
              "schedule_preview",
              "schedule_upcoming",
              "schedule_bulk_set_enabled",
              "heartbeat_get",
              "heartbeat_set",
              "workspace_timezone_get",
              "workspace_timezone_set",
              "memory_list",
              "memory_search",
              "memory_get",
              "memory_settings_get",
              "memory_settings_set",
              "memory_corrections_list",
              "memory_write",
              "memory_update",
              "memory_restore",
              "memory_link",
              "memory_graph",
              "memory_forget",
              "skill_list",
              "skill_read",
              "skill_save",
              "skill_update",
              "skill_set_agents",
              "skill_set_disabled",
              "skill_archive",
              "skill_restore",
              "clawhub_search",
              "clawhub_preview",
              "clawhub_install",
              "workflow_list",
              "workflow_save",
              "workflow_run",
              "workflow_archive",
              "workflow_restore",
              "playbook_list",
              "playbook_install",
              "playbook_propose",
              "integration_list",
              "integration_get",
              "integration_history",
              "integration_begin_connect",
              "integration_auth_status",
              "integration_auth_cancel",
              "integration_update",
              "integration_verify",
              "integration_disconnect",
              "integration_tool_list",
              "integration_set_tool_policy",
              "provider_list",
              "provider_status",
              "provider_begin_login",
              "provider_login_status",
              "provider_cancel_login",
              "provider_disconnect",
              "provider_reorder",
              "channel_list",
              "channel_begin_connect",
              "channel_update",
              "channel_configure_slack",
              "channel_test",
              "channel_disconnect",
              "inbox_list",
              "inbox_create",
              "inbox_update",
              "inbox_archive",
              "email_thread_list",
              "email_thread_get",
              "email_thread_mark_read",
              "email_draft_create",
              "email_draft_update",
              "email_draft_revise",
              "email_draft_discard",
              "email_send_approve",
              "email_send_schedule",
              "email_send_cancel",
              "email_escalation_answer",
              "email_escalation_dismiss",
              "email_domain_list",
              "email_domain_add",
              "email_domain_verify",
              "email_domain_remove",
              "email_rule_list",
              "email_rule_preview",
              "email_rule_add",
              "email_rule_remove",
              "attachment_list",
              "attachment_begin_upload",
              "attachment_remove",
              "feed_list",
              "feed_mark_seen",
              "notification_list",
              "notification_mark_read",
              "notification_mark_all_read",
              "notification_preferences_get",
              "notification_preferences_update",
              "pin_list",
              "pin_toggle",
              "project_status",
              "project_setup_get",
              "sentry_issue_list",
              "sentry_event_get",
              "datafast_metrics",
              "project_connection_list",
              "project_connection_select",
              "project_connections_confirm",
              "project_resource_mapping_save",
              "project_goals_save",
              "project_build_contract_confirm",
              "project_controls_confirm",
              "project_config_update",
              "project_execution_agent_set",
              "project_build_detect",
              "project_build_env_set",
              "project_build_env_remove",
              "project_dry_run_start",
              "project_pause",
              "project_resume",
              "project_refresh",
              "project_propose",
              "project_merge_approved_ticket",
              "release_list",
              "release_get",
              "release_source_list",
              "release_create",
              "release_update",
              "outcome_campaign_list",
              "outcome_campaign_create",
              "outcome_campaign_set_disabled",
              "outcome_summary",
              "x_launch_list",
              "x_launch_get",
              "x_launch_accounts",
              "x_launch_create",
              "x_launch_update",
              "x_launch_approve",
              "x_launch_publish",
              "x_launch_reconcile",
              "workspace_get",
              "workspace_update",
              "workspace_export",
              "workspace_request_deletion",
              "team_list",
              "team_invite",
              "team_approve",
              "team_reject",
              "team_change_role",
              "team_remove",
              "share_status",
              "share_preflight",
              "share_publish",
              "share_revoke",
              "share_set_indexing",
              "credits_status",
              "credits_usage",
              "credits_purchase_history",
              "credits_price_menu",
              "credits_set_auto_recharge",
              "billing_portal_link",
              "credit_pack_checkout",
              "api_key_list",
              "api_key_create",
              "api_key_revoke",
              "provisioning_status",
              "provisioning_retry",
              "referral_status",
              "referral_create_code",
              "partner_status",
              "partner_enroll"
            ]
          },
          "description": {
            "type": "string"
          },
          "inputSchema": {
            "type": "object",
            "additionalProperties": true,
            "description": "JSON Schema for this tool's arguments."
          },
          "annotations": {
            "type": "object",
            "additionalProperties": false,
            "description": "MCP tool annotations. Hints for clients deciding what to confirm with the user, not a security boundary.",
            "properties": {
              "title": {
                "type": "string"
              },
              "readOnlyHint": {
                "type": "boolean"
              },
              "destructiveHint": {
                "type": "boolean"
              },
              "idempotentHint": {
                "type": "boolean"
              },
              "openWorldHint": {
                "type": "boolean"
              }
            },
            "required": [
              "title",
              "readOnlyHint",
              "destructiveHint",
              "idempotentHint",
              "openWorldHint"
            ]
          }
        },
        "required": [
          "name",
          "description",
          "inputSchema",
          "annotations"
        ]
      },
      "ToolsListResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "tools": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/HeadlessTool"
                },
                "maxItems": 230
              }
            },
            "required": [
              "tools"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "result"
        ]
      },
      "ToolsCallResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "$ref": "#/components/schemas/JsonRpcId"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "content": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "type": {
                      "type": "string",
                      "const": "text"
                    },
                    "text": {
                      "type": "string",
                      "description": "Plain-text payload. Many tools serialize structured JSON into this string."
                    }
                  },
                  "required": [
                    "type",
                    "text"
                  ]
                }
              },
              "isError": {
                "type": "boolean"
              }
            },
            "required": [
              "content",
              "isError"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "result"
        ]
      },
      "JsonRpcErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/JsonRpcId"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "jsonrpc",
          "id",
          "error"
        ]
      },
      "PublicDiscoveryIndexResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "The unauthenticated entry point to every public DeployHermes surface.",
        "properties": {
          "product": {
            "type": "string",
            "const": "DeployHermes"
          },
          "public": {
            "type": "boolean",
            "const": true
          },
          "openapi": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/openapi.json"
          },
          "health": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/api/v1/health"
          },
          "developers": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/developers"
          },
          "protectedResourceMetadata": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/.well-known/oauth-protected-resource"
          },
          "llms": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/llms.txt"
          },
          "llmsFull": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/llms-full.txt"
          },
          "sitemap": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/sitemap.xml"
          },
          "apiKeys": {
            "type": "string",
            "format": "uri",
            "const": "https://deploy-hermes.com/settings/api-keys"
          },
          "endpoints": {
            "type": "array",
            "description": "Every endpoint this API answers, method and path.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "method": {
                  "type": "string",
                  "enum": [
                    "GET",
                    "POST"
                  ]
                },
                "path": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                }
              },
              "required": [
                "method",
                "path",
                "description"
              ]
            }
          },
          "mcp": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "transport": {
                "type": "string",
                "const": "streamable-http"
              },
              "protocol": {
                "type": "string",
                "const": "jsonrpc-2.0"
              },
              "authenticated": {
                "type": "boolean",
                "const": true
              },
              "url": {
                "type": "string",
                "format": "uri",
                "const": "https://deploy-hermes.com/mcp/v1"
              },
              "manifest": {
                "type": "string",
                "format": "uri",
                "const": "https://deploy-hermes.com/.well-known/mcp.json"
              },
              "card": {
                "type": "string",
                "format": "uri",
                "const": "https://deploy-hermes.com/api/v1/mcp"
              }
            },
            "required": [
              "transport",
              "protocol",
              "authenticated",
              "url",
              "manifest",
              "card"
            ]
          }
        },
        "required": [
          "product",
          "public",
          "openapi",
          "health",
          "developers",
          "protectedResourceMetadata",
          "llms",
          "llmsFull",
          "sitemap",
          "apiKeys",
          "endpoints",
          "mcp"
        ]
      },
      "PublicHealthResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "Liveness of the public discovery surface.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "service": {
            "type": "string",
            "const": "deployhermes-public-api"
          },
          "version": {
            "type": "string",
            "description": "Build or schema version for the public discovery surface."
          },
          "documentation_pages": {
            "type": "integer",
            "minimum": 0,
            "description": "Public documentation and static pages currently served."
          }
        },
        "required": [
          "ok",
          "service",
          "version",
          "documentation_pages"
        ]
      },
      "AskRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "An NLWeb ask request.",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "description": "The question, in natural language."
          },
          "site": {
            "type": "string",
            "description": "Optional documentation category slug to narrow the search. An unrecognised value narrows nothing rather than returning zero results."
          },
          "mode": {
            "type": "string",
            "enum": [
              "list",
              "summarize",
              "generate"
            ],
            "default": "list",
            "description": "Accepted and echoed. Retrieval is deterministic, so all three answer identically — no model is called."
          },
          "streaming": {
            "type": "boolean",
            "description": "Force the representation. Omitted, it is negotiated from Accept: text/event-stream streams, anything else returns one JSON document."
          },
          "num_results": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 5,
            "description": "How many ranked results to return."
          },
          "query_id": {
            "type": "string",
            "description": "Client-supplied id, echoed back."
          }
        },
        "required": [
          "query"
        ]
      },
      "AskResponse": {
        "type": "object",
        "description": "An NLWeb answer envelope.",
        "properties": {
          "_meta": {
            "type": "object",
            "description": "NLWeb response metadata.",
            "properties": {
              "response_type": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "mode": {
                "type": "string"
              },
              "site": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "response_type",
              "version"
            ]
          },
          "query_id": {
            "type": "string"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "One ranked documentation page.",
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "name": {
                  "type": "string"
                },
                "site": {
                  "type": "string"
                },
                "score": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100
                },
                "description": {
                  "type": "string"
                },
                "schema_object": {
                  "type": "object",
                  "description": "schema.org representation of the page.",
                  "additionalProperties": true
                }
              },
              "required": [
                "url",
                "name",
                "score",
                "description"
              ]
            }
          }
        },
        "required": [
          "_meta",
          "results"
        ]
      },
      "McpServerCard": {
        "type": "object",
        "description": "MCP server metadata in the registry server.json shape (https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json).",
        "properties": {
          "$schema": {
            "type": "string",
            "format": "uri"
          },
          "name": {
            "type": "string",
            "description": "Reverse-DNS server identifier.",
            "const": "com.deploy-hermes/deployhermes"
          },
          "description": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "websiteUrl": {
            "type": "string",
            "format": "uri"
          },
          "supportedProtocolVersions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Every MCP protocol revision initialize will echo back."
          },
          "remotes": {
            "type": "array",
            "description": "Connection endpoints. One streamable-http remote.",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "streamable-http"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "headers": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "isRequired": {
                        "type": "boolean"
                      },
                      "isSecret": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "name"
                    ]
                  }
                }
              },
              "required": [
                "type",
                "url"
              ]
            }
          },
          "_meta": {
            "type": "object",
            "description": "Vendor metadata under a reverse-DNS key.",
            "additionalProperties": true
          }
        },
        "required": [
          "name",
          "description",
          "version",
          "remotes"
        ]
      },
      "DocumentationIndexResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "Every public documentation category, and one cursor-paginated page of documentation pages.",
        "properties": {
          "categories": {
            "type": "array",
            "description": "Always the whole category list, independent of the current pages cursor.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "slug": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "page_count": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Count across the whole library, not just the current page."
                }
              },
              "required": [
                "slug",
                "title",
                "description",
                "url",
                "page_count"
              ]
            }
          },
          "pages": {
            "type": "array",
            "description": "The current page of documentation pages; see limit and cursor.",
            "items": {
              "$ref": "#/components/schemas/DocumentationIndexEntry"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass as ?cursor= to fetch the next page. null on the last page."
          },
          "has_more": {
            "type": "boolean",
            "description": "True unless pages ends the collection."
          }
        },
        "required": [
          "categories",
          "pages",
          "next_cursor",
          "has_more"
        ]
      },
      "DocumentationIndexEntry": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "path": {
            "type": "string",
            "description": "Site path, e.g. /technical/ai-agent-api-costs."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical HTML URL."
          },
          "api_url": {
            "type": "string",
            "format": "uri",
            "description": "URL returning this page as a DocumentationPageResponse."
          },
          "category": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "search_intent": {
            "type": "string",
            "enum": [
              "informational",
              "commercial",
              "comparison",
              "troubleshooting"
            ]
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "published_at": {
            "type": "string",
            "format": "date"
          },
          "updated_at": {
            "type": "string",
            "format": "date"
          }
        },
        "required": [
          "path",
          "url",
          "api_url",
          "category",
          "title",
          "description",
          "search_intent",
          "keywords",
          "published_at",
          "updated_at"
        ]
      },
      "DocumentationPageResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "One documentation page, decomposed into addressable parts.",
        "properties": {
          "path": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "category": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "intro": {
            "type": "string"
          },
          "search_intent": {
            "type": "string",
            "enum": [
              "informational",
              "commercial",
              "comparison",
              "troubleshooting"
            ]
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "published_at": {
            "type": "string",
            "format": "date"
          },
          "updated_at": {
            "type": "string",
            "format": "date"
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "heading": {
                  "type": "string"
                },
                "paragraphs": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "bullets": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "heading",
                "paragraphs",
                "bullets"
              ]
            }
          },
          "faq": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "question": {
                  "type": "string"
                },
                "answer": {
                  "type": "string"
                }
              },
              "required": [
                "question",
                "answer"
              ]
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "label": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "as_of": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Date the source was checked."
                }
              },
              "required": [
                "label",
                "url",
                "as_of"
              ]
            }
          }
        },
        "required": [
          "path",
          "url",
          "category",
          "title",
          "description",
          "intro",
          "search_intent",
          "keywords",
          "published_at",
          "updated_at",
          "sections",
          "faq",
          "sources"
        ]
      },
      "PublicErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code."
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "resolution_hints": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "description": "Concrete next steps an agent can follow."
              }
            },
            "required": [
              "code",
              "message",
              "resolution_hints"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "HeadlessAttachmentUploadResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "Successful response from the dedicated attachment byte-upload endpoint. attachmentId is returned by the normal finalize flow.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "attachmentId": {
            "type": "string",
            "description": "The attachment record created from the single-use upload ticket."
          }
        },
        "required": [
          "ok"
        ]
      },
      "BatchOperation": {
        "type": "object",
        "additionalProperties": false,
        "description": "One request to dispatch inside a POST /api/v1/batch call.",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Caller-chosen id, echoed back on the matching BatchResult."
          },
          "method": {
            "type": "string",
            "default": "GET",
            "description": "Defaults to GET. Any other verb resolves to the same 405 a direct request would get."
          },
          "path": {
            "type": "string",
            "description": "A path this API answers, e.g. /api/v1/docs/technical/api-pricing-guide. May include a query string."
          }
        },
        "required": [
          "id",
          "path"
        ]
      },
      "BatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "The POST /api/v1/batch request body. At most 20 operations.",
        "properties": {
          "operations": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/BatchOperation"
            }
          }
        },
        "required": [
          "operations"
        ]
      },
      "BatchResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "One operation's outcome, byte-identical to calling that path directly.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Matches the id on the requesting BatchOperation."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status the direct call would have returned."
          },
          "body": {
            "type": "object",
            "additionalProperties": true,
            "description": "The direct call's JSON body: the matching GET operation's typed success schema when status is 2xx, PublicErrorResponse otherwise. Every response in this document is a JSON object, so `object` is the true shared shape here; which named schema applies is determined by status."
          }
        },
        "required": [
          "id",
          "status",
          "body"
        ]
      },
      "BatchResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "The POST /api/v1/batch response body: one result per operation, in request order.",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchResult"
            }
          }
        },
        "required": [
          "results"
        ]
      }
    }
  },
  "externalDocs": {
    "description": "DeployHermes developer portal: authentication, endpoints, quickstart, and limits.",
    "url": "https://deploy-hermes.com/developers"
  },
  "x-deployhermes-headless": {
    "transport": "streamable-http",
    "transportNotes": "Stateless JSON-RPC 2.0 over HTTP POST, answering application/json. No session is held, so GET and DELETE answer 405.",
    "serverCard": "https://deploy-hermes.com/.well-known/mcp.json",
    "developerPortal": "https://deploy-hermes.com/developers",
    "apiKeyManagementUrl": "https://deploy-hermes.com/settings/api-keys",
    "deploymentRequirement": "The public /mcp/v1 route proxies to the deployment's Convex HTTP origin, taken from CONVEX_SITE_URL or derived from VITE_CONVEX_URL.",
    "callPriceCredits": 0.5,
    "freeTools": [
      "workspace_status"
    ],
    "wakeTriggeringNotes": [
      "mission_run_now wakes the assigned agent immediately.",
      "chat_post can wake an agent when the message is a DM or names an agent.",
      "workflow_run consumes one wake slot because it starts a model run immediately.",
      "schedule_create consumes one wake slot because it commits the key to future automated wakes.",
      "project_refresh consumes one wake slot because it wakes a full agent run to refresh project evidence and status.",
      "project_propose consumes one wake slot because it wakes a full agent run to prepare the next proposed project improvement.",
      "playbook_install consumes one wake slot because it may commit the workspace to future scheduled model runs.",
      "Later schedule firings still consume the workspace owner's own model subscription, but they are not attributable to the API key that created the schedule."
    ]
  },
  "x-deployhermes-versioning": {
    "policy": "Both surfaces are versioned by URL path — /api/v1 and /mcp/v1 — and a breaking change ships as a new path (/api/v2, /mcp/v2) rather than mutating either contract in place. The headless endpoint additionally negotiates a JSON-RPC protocolVersion per request; supportedProtocolVersions on the MCP server card and InitializeRequest.params.protocolVersion.examples list every revision it accepts.",
    "deprecationSignal": "A deprecated operation is marked `deprecated: true`, and its responses carry a `Deprecation` header (and a `Sunset` header once a shutoff date is set) per RFC 8594 — declared as possible response headers throughout this document (see components... responses' headers objects), currently always absent because nothing described here is deprecated.",
    "today": "Nothing in this document is deprecated."
  }
}
