{
  "openapi": "3.1.0",
  "info": {
    "title": "Control Center website API",
    "version": "v0.0.1-rc.1",
    "description": "Machine-readable surface of usectrl.dev — the Control Center website. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md). The product's own API (103 MCP tools over Streamable HTTP) runs inside the self-hosted cc_server, not on this origin; see https://usectrl.dev/manual/guides/mcp-server/.",
    "contact": {
      "name": "Control Center maintainers",
      "url": "https://github.com/SamuelAlev/control-center/issues"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/SamuelAlev/control-center/blob/main/LICENSE"
    }
  },
  "servers": [
    {
      "url": "https://usectrl.dev",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Product manual",
    "url": "https://usectrl.dev/manual/"
  },
  "tags": [
    {
      "name": "Content",
      "description": "Pages and their markdown twins (Accept-negotiated)."
    },
    {
      "name": "Feeds",
      "description": "Whole-site serializations for agents and readers."
    },
    {
      "name": "Agent",
      "description": "Endpoints designed for AI agents: MCP server, llms.txt, this document."
    },
    {
      "name": "Errors",
      "description": "Structured error behavior for every unpublished path."
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "getLandingPage",
        "summary": "Landing page",
        "description": "What the product is, the four pillars, downloads. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/about": {
      "get": {
        "operationId": "getAboutPage",
        "summary": "About",
        "description": "What Control Center is, how it is built, who maintains it. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/contact": {
      "get": {
        "operationId": "getContactPage",
        "summary": "Contact",
        "description": "How to reach the maintainers (GitHub issues; security and privacy process). Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/developers": {
      "get": {
        "operationId": "getDevelopersPage",
        "summary": "Developer portal",
        "description": "Integration surface: product MCP server, cc_server CLI and Docker images, plus this site's agent endpoints. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/changelog": {
      "get": {
        "operationId": "getChangelogPage",
        "summary": "Changelog",
        "description": "Every release, newest first. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/compare": {
      "get": {
        "operationId": "getComparePage",
        "summary": "Comparison matrix",
        "description": "Control Center vs the alternatives, capability by capability. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/compare/{tool}": {
      "get": {
        "operationId": "getCompareToolPage",
        "summary": "Per-tool comparison",
        "description": "Control Center vs one named tool. Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          },
          {
            "name": "tool",
            "in": "path",
            "required": true,
            "description": "Competitor slug.",
            "schema": {
              "type": "string",
              "enum": [
                "conductor",
                "superset",
                "orca",
                "paperclip",
                "multica",
                "openclaw",
                "hermes",
                "goose",
                "cursor"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/manual/{page}": {
      "get": {
        "operationId": "getDocsPage",
        "summary": "Documentation page",
        "description": "One manual page (tutorial, guide, concept or reference). Every HTML page here serves a markdown twin: send `Accept: text/markdown` on the page URL (responses carry `Vary: Accept`), or append `.md` to the path (e.g. /manual/quick-start.md).",
        "tags": [
          "Content"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          },
          {
            "name": "page",
            "in": "path",
            "required": true,
            "description": "Docs slug; may span multiple segments (e.g. manual/guides/mcp-server).",
            "style": "simple",
            "allowReserved": true,
            "schema": {
              "type": "string",
              "enum": [
                "manual",
                "manual/concepts",
                "manual/concepts/agent-model",
                "manual/concepts/ai-review",
                "manual/concepts/architecture",
                "manual/concepts/authorization",
                "manual/concepts/calendar",
                "manual/concepts/chat-bridges",
                "manual/concepts/code-intelligence",
                "manual/concepts/conversation-history",
                "manual/concepts/deployment",
                "manual/concepts/dispatch-lifecycle",
                "manual/concepts/domain-events",
                "manual/concepts/evals-replay",
                "manual/concepts/guardrails",
                "manual/concepts/meetings",
                "manual/concepts/memory-knowledge",
                "manual/concepts/modes",
                "manual/concepts/multiplayer",
                "manual/concepts/orchestration",
                "manual/concepts/pipelines",
                "manual/concepts/pr-conversations",
                "manual/concepts/remote-control",
                "manual/concepts/rigs",
                "manual/concepts/sandbox-security",
                "manual/concepts/sso",
                "manual/concepts/tickets",
                "manual/concepts/tool-context",
                "manual/concepts/workspaces",
                "manual/guides",
                "manual/guides/adapters",
                "manual/guides/add-repos",
                "manual/guides/agent-diagnostics",
                "manual/guides/ai-review",
                "manual/guides/api-keys",
                "manual/guides/back-up-and-restore",
                "manual/guides/branch-a-conversation",
                "manual/guides/build-team",
                "manual/guides/chat-with-agent",
                "manual/guides/code-search",
                "manual/guides/configure-guardrails",
                "manual/guides/connect-calendar",
                "manual/guides/connect-forges",
                "manual/guides/connect-remote-server",
                "manual/guides/create-agent",
                "manual/guides/create-pipeline",
                "manual/guides/customize-chat-bot",
                "manual/guides/debug-a-failing-test",
                "manual/guides/delegate-tickets",
                "manual/guides/direct-background-workers",
                "manual/guides/dispatch-reviewers",
                "manual/guides/explore-data-in-a-kernel",
                "manual/guides/focus-mode",
                "manual/guides/github-app",
                "manual/guides/github-integration",
                "manual/guides/github-pr-conversations",
                "manual/guides/linear-integration",
                "manual/guides/link-chat-account",
                "manual/guides/manage-costs",
                "manual/guides/manage-memory",
                "manual/guides/manage-skills",
                "manual/guides/manage-tickets",
                "manual/guides/mcp-server",
                "manual/guides/mention-agents",
                "manual/guides/monitor-pipelines",
                "manual/guides/newsfeed",
                "manual/guides/notifications",
                "manual/guides/pair-a-device",
                "manual/guides/parallel-agents",
                "manual/guides/pipeline-triggers",
                "manual/guides/plan-mode",
                "manual/guides/plan-studio",
                "manual/guides/projects",
                "manual/guides/record-meeting",
                "manual/guides/repo-scripts",
                "manual/guides/review-merge-pr",
                "manual/guides/review-studio",
                "manual/guides/run-fleet-worker",
                "manual/guides/run-headless-server",
                "manual/guides/run-orchestration",
                "manual/guides/run-pipeline",
                "manual/guides/sandbox-policies",
                "manual/guides/slack-integration",
                "manual/guides/spaces",
                "manual/guides/sso-oidc",
                "manual/guides/sso-scim",
                "manual/guides/structural-refactor",
                "manual/guides/triage-inbox",
                "manual/guides/tune-tool-context",
                "manual/guides/use-rigs",
                "manual/guides/vm-ports",
                "manual/install",
                "manual/quick-start",
                "manual/reference",
                "manual/reference/agent-configuration",
                "manual/reference/agent-tools",
                "manual/reference/backup",
                "manual/reference/cc-server-cli",
                "manual/reference/chat-bridge",
                "manual/reference/domain-events",
                "manual/reference/glossary",
                "manual/reference/keyboard-shortcuts",
                "manual/reference/mcp-tools",
                "manual/reference/pipeline-steps",
                "manual/reference/rigs",
                "manual/reference/route-map",
                "manual/reference/sandbox-backends",
                "manual/reference/slash-commands",
                "manual/reference/sso",
                "manual/reference/ticket-lifecycle",
                "manual/tutorials",
                "manual/tutorials/first-agent",
                "manual/tutorials/first-chat-bridge",
                "manual/tutorials/first-pipeline",
                "manual/tutorials/first-pr",
                "manual/tutorials/first-workspace",
                "manual/tutorials/sso"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page as HTML.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/index.md": {
      "get": {
        "operationId": "getLandingMarkdown",
        "summary": "Landing page as markdown",
        "description": "The direct markdown twin of /. Every page has one: append .md to its path.",
        "tags": [
          "Content"
        ],
        "responses": {
          "200": {
            "description": "The page as markdown (title, description, body, canonical-URL footer).",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Always includes `Accept`."
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Curated site index for LLMs",
        "description": "The llmstxt.org index: product summary, when-to-use guidance, developer resources and every docs page with a one-line description.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "The index.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "summary": "Entire site as one text file",
        "description": "Product overview, FAQ, comparison matrix, changelog and every manual page body in one download.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "The full dump.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiDocument",
        "summary": "This OpenAPI document",
        "description": "The OpenAPI 3.1 description of this site’s endpoints.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "This document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "callDocsMcpServerShortPath",
        "summary": "Docs MCP server (short path)",
        "description": "The same Streamable HTTP MCP server as /.well-known/mcp, mounted at the conventional /mcp path. Identical request and response contract; either path may be used.",
        "tags": [
          "Agent"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response (initialize, ping, tools/list, tools/call).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "202": {
            "description": "Notification accepted (empty body)."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      },
      "get": {
        "operationId": "docsMcpServerInfoShortPath",
        "summary": "MCP server discovery card (short path)",
        "description": "The same JSON discovery card as GET /.well-known/mcp, naming the server and how to POST to it.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "Discovery card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/api-catalog": {
      "get": {
        "operationId": "getApiCatalog",
        "summary": "API catalog (RFC 9727)",
        "description": "The linkset cataloguing the APIs on this origin — the website API and the docs MCP server — each with its service-desc (this OpenAPI document) and service-doc (the developer portal). Served as application/linkset+json. Every content page also advertises it with a `Link: <…>; rel=\"api-catalog\"` header.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "The catalog.",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent-skills/index.json": {
      "get": {
        "operationId": "getAgentSkillsIndex",
        "summary": "Agent skills discovery index",
        "description": "The Agent Skills Discovery index (v0.2.0): every published skill with its type, description, artifact URL and the SHA-256 digest of the exact bytes served at that URL.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "The skills index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent-skills/{skill}/SKILL.md": {
      "get": {
        "operationId": "getAgentSkillDocument",
        "summary": "One agent skill artifact",
        "description": "The SKILL.md for one published skill. These are the exact bytes the index digest covers — fetch the artifact, hash it, and compare before trusting it.",
        "tags": [
          "Agent"
        ],
        "parameters": [
          {
            "name": "skill",
            "in": "path",
            "required": true,
            "description": "Skill name, as published in the index.",
            "schema": {
              "type": "string",
              "enum": [
                "usectrl-dev-agent-access",
                "control-center-mcp-tools",
                "control-center-self-hosting"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The skill document.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/.well-known/mcp/server-card.json": {
      "get": {
        "operationId": "getMcpServerCard",
        "summary": "MCP server card",
        "description": "The SEP-2127 server card for the docs MCP server: its identity, the streamable-HTTP remotes it answers on and the protocol versions it speaks. The reserved extensionless path /.well-known/mcp/server-card serves the same document.",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "The server card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap-index.xml": {
      "get": {
        "operationId": "getSitemapIndex",
        "summary": "XML sitemap index",
        "description": "Every published page, for crawlers and agents.",
        "tags": [
          "Feeds"
        ],
        "responses": {
          "200": {
            "description": "Sitemap index.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/rss.xml": {
      "get": {
        "operationId": "getRssFeed",
        "summary": "Changelog RSS feed",
        "description": "Release notes as RSS 2.0.",
        "tags": [
          "Feeds"
        ],
        "responses": {
          "200": {
            "description": "RSS feed.",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/mcp": {
      "post": {
        "operationId": "callDocsMcpServer",
        "summary": "Docs MCP server (Streamable HTTP)",
        "description": "A Model Context Protocol endpoint exposing this site’s content as tools — list_pages, get_page_markdown, search_pages. Speaks JSON-RPC 2.0 over POST with plain JSON responses; notifications get 202. Also reachable at /mcp.",
        "tags": [
          "Agent"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "MCP clients send `application/json, text/event-stream`; this server always answers application/json.",
            "schema": {
              "type": "string",
              "default": "application/json, text/event-stream"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response (initialize, ping, tools/list, tools/call).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            }
          },
          "202": {
            "description": "Notification accepted (empty body)."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      },
      "get": {
        "operationId": "docsMcpServerInfo",
        "summary": "MCP server discovery card",
        "description": "A small JSON card naming the server and how to POST to it. (SSE streaming is not offered.)",
        "tags": [
          "Agent"
        ],
        "responses": {
          "200": {
            "description": "Discovery card.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/{path}": {
      "get": {
        "operationId": "getUnpublishedPath",
        "summary": "Any unpublished path",
        "description": "Every unpublished path returns a real 404 — never a 200 app shell. The body negotiates: HTML for browsers, markdown for `Accept: text/markdown`, a JSON error envelope for `Accept: application/json` and for any /api/* path.",
        "tags": [
          "Errors"
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "Content negotiation: `text/markdown` returns the markdown twin; anything else returns HTML.",
            "schema": {
              "type": "string",
              "enum": [
                "text/html",
                "text/markdown"
              ],
              "default": "text/html"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "description": "Any path not published by this site.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint",
              "status",
              "docs",
              "sitemap"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine code, e.g. not_found."
              },
              "message": {
                "type": "string",
                "description": "What happened, in one sentence."
              },
              "hint": {
                "type": "string",
                "description": "How to recover: where the route list lives."
              },
              "status": {
                "type": "integer",
                "description": "HTTP status, repeated for clients that only read the body."
              },
              "docs": {
                "type": "string",
                "format": "uri",
                "description": "This OpenAPI document."
              },
              "sitemap": {
                "type": "string",
                "format": "uri",
                "description": "Every published route."
              }
            }
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "required": [
          "jsonrpc",
          "method"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "method": {
            "type": "string",
            "enum": [
              "initialize",
              "ping",
              "tools/list",
              "tools/call",
              "notifications/initialized"
            ],
            "description": "The MCP methods this server implements."
          },
          "params": {
            "type": "object"
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "properties": {
          "jsonrpc": {
            "type": "string",
            "const": "2.0"
          },
          "id": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ]
          },
          "result": {
            "type": "object",
            "description": "Method result (initialize result, tools array, call content)."
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer",
                "description": "JSON-RPC error code (-32601 method not found, -32602 invalid params)."
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "Not found. Body negotiates on Accept: JSON envelope (application/json), markdown recovery map (text/markdown), or the HTML 404 page.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          },
          "text/markdown": {
            "schema": {
              "type": "string"
            },
            "example": "# 404 — not found\n\n…\n## Where to look next\n…"
          },
          "text/html": {
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Malformed JSON-RPC envelope.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JsonRpcResponse"
            }
          }
        }
      }
    }
  }
}