{
  "schemaVersion": 1,
  "updatedAt": "2026-10-15",
  "currentProtocolRevision": "2026-07-28",
  "supportLevels": ["native", "partial", "unsupported", "unknown"],
  "eraEvidence": {
    "current": ["mcp-current-spec"],
    "deprecated": ["mcp-current-spec", "mcp-deprecated-spec"],
    "legacy-experimental": ["mcp-legacy-tasks-spec"]
  },
  "features": [
    {
      "id": "roots",
      "title": "Roots",
      "provider": "client",
      "era": "deprecated",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/roots",
      "value": "Let a server discover the client-approved filesystem roots; this is not the server process working directory."
    },
    {
      "id": "sampling",
      "title": "Sampling",
      "provider": "client",
      "era": "deprecated",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/sampling",
      "value": "Let a server request an LLM interaction through the host, with user review and model preferences."
    },
    {
      "id": "samplingTools",
      "title": "Sampling with tools",
      "provider": "client",
      "era": "deprecated",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/sampling",
      "value": "Let the sampling loop invoke tools recursively; do not confuse this with ordinary server tool calls."
    },
    {
      "id": "elicitation",
      "title": "Elicitation (generic)",
      "provider": "client",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation",
      "value": "Record clients that document elicitation without establishing which interaction modes they implement."
    },
    {
      "id": "elicitationForm",
      "title": "Form elicitation",
      "provider": "client",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation",
      "value": "Let a server request structured user input with accept, decline, and cancel outcomes."
    },
    {
      "id": "elicitationUrl",
      "title": "URL elicitation",
      "provider": "client",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation",
      "value": "Let a server send the user through an external interaction and safely resume afterward."
    },
    {
      "id": "prompts",
      "title": "Prompts",
      "provider": "server",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/server/prompts",
      "value": "Expose reusable, argument-aware server prompts through the client UI."
    },
    {
      "id": "resources",
      "title": "Resources",
      "provider": "server",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/server/resources",
      "value": "List and read server-provided context independently from tool execution."
    },
    {
      "id": "resourceTemplates",
      "title": "Resource templates",
      "provider": "server",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/server/resources",
      "value": "Discover and fill parameterized resource URIs."
    },
    {
      "id": "completion",
      "title": "Argument completion",
      "provider": "server",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/completion",
      "value": "Complete prompt arguments and resource-template parameters without an LLM call."
    },
    {
      "id": "progress",
      "title": "Progress",
      "provider": "both",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/progress",
      "value": "Correlate monotonic progress with a request; UI display and timeout extension are separate behaviors."
    },
    {
      "id": "cancellation",
      "title": "Cancellation",
      "provider": "both",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/cancellation",
      "value": "Cooperatively cancel in-flight protocol requests and propagate intent to the handler."
    },
    {
      "id": "logging",
      "title": "Protocol logging",
      "provider": "server",
      "era": "deprecated",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/logging",
      "value": "Deliver correlated server logs through MCP rather than relying on process stderr."
    },
    {
      "id": "subscriptions",
      "title": "Subscriptions",
      "provider": "both",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/subscriptions",
      "value": "Receive correlated updates over a long-lived request."
    },
    {
      "id": "multiRoundTrip",
      "title": "Multi-round-trip requests",
      "provider": "both",
      "era": "current",
      "reference": "https://modelcontextprotocol.io/specification/2026-07-28/basic/index",
      "value": "Pause a request for sampling, elicitation, or roots input and retry it with opaque request state."
    },
    {
      "id": "tasksLegacy",
      "title": "Tasks",
      "provider": "both",
      "era": "legacy-experimental",
      "reference": "https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks",
      "value": "Durable polling, status, result, and cancellation state from the 2025-11-25 experimental protocol era."
    }
  ],
  "contracts": [
    {
      "harness": "claude-code",
      "variant": "documented-current",
      "default": true,
      "protocolRevision": "2026-07-28, with fallback to older servers",
      "clientMode": "interactive CLI, headless (-p) and Agent SDK sessions",
      "evidence": [
        "claude-mcp-docs",
        "claude-changelog",
        "mcp-claude-code-code-claude-com-docs-en-managed-mcp",
        "memory-claude-code-code-claude-com-docs-en-settings-reference",
        "claude-permissions-docs",
        "compaction-3",
        "claude-hooks-docs",
        "claude-commands-docs",
        "claude-cli-reference-docs"
      ],
      "references": {
        "roots": "https://code.claude.com/docs/en/mcp#option-3-add-a-local-stdio-server",
        "elicitation": "https://code.claude.com/docs/en/mcp#respond-to-mcp-elicitation-requests",
        "elicitationForm": "https://code.claude.com/docs/en/mcp#respond-to-mcp-elicitation-requests",
        "elicitationUrl": "https://code.claude.com/docs/en/mcp#respond-to-mcp-elicitation-requests",
        "prompts": "https://code.claude.com/docs/en/mcp#use-mcp-prompts-as-commands",
        "resources": "https://code.claude.com/docs/en/mcp#use-mcp-resources",
        "resourceTemplates": "https://code.claude.com/docs/en/changelog#2-1-116",
        "progress": "https://code.claude.com/docs/en/mcp#automatic-backgrounding-of-long-tool-calls",
        "cancellation": "https://code.claude.com/docs/en/mcp#automatic-backgrounding-of-long-tool-calls",
        "subscriptions": "https://code.claude.com/docs/en/mcp#notification-streams-on-the-v2-runtime"
      },
      "support": {
        "roots": "native",
        "sampling": "unknown",
        "samplingTools": "unknown",
        "elicitation": "native",
        "elicitationForm": "native",
        "elicitationUrl": "native",
        "prompts": "native",
        "resources": "native",
        "resourceTemplates": "partial",
        "completion": "unknown",
        "progress": "native",
        "cancellation": "partial",
        "logging": "unknown",
        "subscriptions": "partial",
        "multiRoundTrip": "unknown",
        "tasksLegacy": "unknown"
      },
      "notes": [
        "Dynamic list changes are documented for tools, prompts, and resources.",
        "The reviewed documentation does not establish sampling, completion, content subscriptions, current subscriptions/MRTR, tasks, or a protocol-log UI."
      ],
      "featureNotes": {
        "roots": "Answers roots/list with the launch directory plus every --add-dir / additionalDirectories path, and sends notifications/roots/list_changed when that set changes (v2.1.203+).",
        "sampling": "The MCP docs do not describe sampling/createMessage support.",
        "elicitation": "Interactive dialog; the Elicitation and ElicitationResult hooks can answer or override it.",
        "elicitationUrl": "On 2026-07-28 connections since v2.1.281 and on 2025-11-25 connections since v2.1.287; URLs over roughly 8,000 escaped characters can only be declined.",
        "prompts": "Listed as /server:prompt (MCP) and runnable as /mcp__server__prompt with whitespace-split arguments.",
        "resources": "@server:uri mentions plus built-in list/read resource tools for Claude.",
        "resourceTemplates": "Claude Code fetches resources/templates/list for @-mention autocomplete; the docs don't describe how template parameters are filled.",
        "completion": "No documented completion/complete support for prompt or template arguments.",
        "progress": "Progress is shown on the tool call and its background task, and resets the idle timeout but not the per-server wall-clock timeout.",
        "cancellation": "Stopping a backgrounded MCP call from /tasks cancels it; the docs warn the server may still finish the work.",
        "logging": "Docs mention a per-server debug log but not MCP logging/setLevel or notifications/message.",
        "subscriptions": "On the v2 runtime, servers on revision 2026-07-28 deliver list_changed over a held-open stream; resource content subscriptions aren't documented.",
        "tasksLegacy": "The 'MCP task' in /tasks is Claude Code's own backgrounding of slow tool calls, not the protocol's Tasks utility."
      },
      "answers": {
        "add": {
          "status": "supported",
          "answer": "Run `claude mcp add --transport http <name> <url>` for a remote server or `claude mcp add [--env KEY=value] <name> -- <command> [args...]` for a local stdio server; use `claude mcp add-json <name> '<json>'` for a raw JSON entry and `claude mcp add-from-claude-desktop` to import from Claude Desktop (macOS and WSL). Entries go under `mcpServers` in `~/.claude.json` (local and user scope) or `.mcp.json` at the project root (project scope), with `type`, `command`/`args`/`env` or `url`/`headers`. Names may contain only letters, numbers, hyphens and underscores, and an entry with a `url` but no `type` is rejected.",
          "reference": "https://code.claude.com/docs/en/mcp#installing-mcp-servers",
          "evidence": ["claude-mcp-docs"],
          "notes": [
            "Put `--` before a stdio server's command so its flags aren't parsed by Claude Code.",
            "Plugins can also bundle servers in a plugin-root `.mcp.json` or inline in `plugin.json`."
          ]
        },
        "transports": {
          "status": "supported",
          "answer": "Claude Code supports stdio, Streamable HTTP (`\"type\": \"http\"`, alias `streamable-http`), SSE (`\"type\": \"sse\"`, deprecated) and WebSocket (`\"type\": \"ws\"`). From v2.1.265, `--transport http` falls back to SSE automatically when the server doesn't accept HTTP. WebSocket can only be configured through JSON (`.mcp.json` or `claude mcp add-json`) and authenticates with headers only, not OAuth.",
          "reference": "https://code.claude.com/docs/en/mcp#installing-mcp-servers",
          "evidence": ["claude-mcp-docs"],
          "notes": [
            "`\"type\": \"sdk\"` in-process servers can only be registered by an SDK host application such as the Agent SDK or the desktop app."
          ]
        },
        "scopes": {
          "status": "supported",
          "answer": "Local scope (the default) and user scope live in `~/.claude.json`, and project scope lives in `.mcp.json` at the repository root. Admins can add `managed-mcp.json` for exclusive control, or `managedMcpServers` in managed settings. When the same name is defined more than once, the highest-precedence entry wins whole, with no field merging, in the order managed, local, project, user, plugin, claude.ai connector. Interactive sessions ask you to approve `.mcp.json` servers (reset with `claude mcp reset-project-choices`), and committed `enableAllProjectMcpServers` or `enabledMcpjsonServers` approvals are ignored until you trust the folder.",
          "reference": "https://code.claude.com/docs/en/mcp#mcp-installation-scopes",
          "evidence": [
            "claude-mcp-docs",
            "mcp-claude-code-code-claude-com-docs-en-managed-mcp",
            "memory-claude-code-code-claude-com-docs-en-settings-reference"
          ],
          "notes": [
            "`claude -p`, Agent SDK and cloud sessions load `.mcp.json` servers without asking; use `disabledMcpjsonServers` or `--strict-mcp-config` to keep one out.",
            "`managed-mcp.json` lives at `/Library/Application Support/ClaudeCode/` (macOS), `/etc/claude-code/` (Linux/WSL) or `C:\\Program Files\\ClaudeCode\\` (Windows)."
          ]
        },
        "auth": {
          "status": "supported",
          "answer": "For OAuth 2.0 on HTTP and SSE servers, run `/mcp` in a session or `claude mcp login <name>` in your shell (`--no-browser` over SSH). Claude Code supports dynamic client registration and CIMD, pre-registered clients via `--client-id`, `--client-secret` and `--callback-port` (or an `oauth` object in JSON), plus `oauth.scopes` and `oauth.authServerMetadataUrl`; tokens are stored and refreshed automatically. Static credentials go in `--header`/`headers`, dynamic ones come from a `headersHelper` command, and `.mcp.json` expands `${VAR}` and `${VAR:-default}` in `command`, `args`, `env`, `url` and `headers`.",
          "reference": "https://code.claude.com/docs/en/mcp#authenticate-with-remote-mcp-servers",
          "evidence": ["claude-mcp-docs"],
          "notes": [
            "In a remote server's `url` and `headers`, Claude Code's own and cloud-provider credential variables such as `ANTHROPIC_API_KEY` always expand to empty.",
            "`claude -p` and the Agent SDK can't run the OAuth flow, so sign in interactively first.",
            "A project or local `headersHelper` runs only after you trust the folder."
          ]
        },
        "approval": {
          "status": "supported",
          "answer": "MCP tool calls go through the normal permission prompt unless a rule or mode approves them. Add rules under `permissions.allow`, `ask` or `deny`: `mcp__server` or `mcp__server__*` covers a whole server, and `mcp__server__tool` covers one tool. A deny rule such as `mcp__*` removes the tools from context entirely. To block servers rather than tools, use `allowedMcpServers` and `deniedMcpServers` (by name, command or URL), `disabledMcpjsonServers`, or turn a server off in `/mcp`.",
          "reference": "https://code.claude.com/docs/en/permissions#mcp",
          "evidence": [
            "claude-permissions-docs",
            "mcp-claude-code-code-claude-com-docs-en-managed-mcp",
            "claude-mcp-docs"
          ],
          "notes": [
            "An allow glob must start with a literal `mcp__<server>__` prefix; an unanchored `mcp__*` allow rule is ignored.",
            "Tools marked `_meta[\"anthropic/requiresUserInteraction\"]: true`, and claude.ai connector tools your organization sets to `ask`, prompt on every call even in `bypassPermissions` mode.",
            "Plugin server tools are named `mcp__plugin_<plugin>_<server>__<tool>`."
          ]
        },
        "manyTools": {
          "status": "supported",
          "answer": "Tool search is on by default: only tool names and server instructions load at startup, and Claude loads full definitions on demand through the `ToolSearch` tool, so there is no fixed tool cap. Change this with `ENABLE_TOOL_SEARCH` (`true`, `false`, `auto` or `auto:N` for a percentage-of-context threshold), keep a server's tools always loaded with `\"alwaysLoad\": true` in its entry, or set `\"alwaysLoad\": false` to defer everything. Tool search turns itself off when `ANTHROPIC_BASE_URL` points at a non-first-party host and on older models.",
          "reference": "https://code.claude.com/docs/en/mcp#scale-with-mcp-tool-search",
          "evidence": ["claude-mcp-docs", "claude-permissions-docs"],
          "notes": [
            "Server instructions and upfront tool descriptions are cut at 4,096 characters, and deferred tool descriptions at 16,384 (`CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH` overrides both).",
            "Tools whose full name exceeds 128 characters, or whose schema is invalid, are left out.",
            "To filter tools, use deny rules such as `mcp__server__tool`; per-subagent servers and tools can be set in the agent's frontmatter."
          ]
        },
        "output": {
          "status": "supported",
          "answer": "Tool output above 10,000 tokens shows a warning. Results over `MAX_MCP_OUTPUT_TOKENS` (default 25,000), or text results over 50,000 characters, are saved to a file in the session's `tool-results` directory and replaced with the file path; a tool can raise its own character limit to 500,000 with `_meta[\"anthropic/maxResultSizeChars\"]`. `MCP_TIMEOUT` sets the server startup timeout (default 30 s), `MCP_TOOL_TIMEOUT` or a per-server `timeout` sets the wall-clock limit per call (default about 28 hours), and a call with no response or progress for 5 minutes (remote) or 30 minutes (stdio) aborts with an error (`CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`). A main-conversation call still running after 2 minutes moves to a background task (`CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS`).",
          "reference": "https://code.claude.com/docs/en/mcp#mcp-output-limits-and-warnings",
          "evidence": ["claude-mcp-docs", "compaction-3"],
          "notes": [
            "HTTP and SSE requests also have a per-request timer of at least 60 seconds to the first response byte.",
            "A response or WebSocket message over 16 MiB fails.",
            "Error text over about 11,000 characters is trimmed to its first and last 5,000 characters."
          ]
        },
        "resources": {
          "status": "supported",
          "answer": "Type `@` to see resources from connected servers alongside files, and reference one as `@server:protocol://path`; it is fetched and attached to your message. Claude also gets built-in tools to list and read MCP resources when a server supports them.",
          "reference": "https://code.claude.com/docs/en/mcp#use-mcp-resources",
          "evidence": ["claude-mcp-docs"],
          "notes": [
            "MCP Apps UI resources (`ui://` or `text/html;profile=mcp-app`) are hidden from `@` suggestions and the list tool."
          ]
        },
        "prompts": {
          "status": "supported",
          "answer": "Server prompts appear in the `/` menu as `/server:prompt (MCP)` and also run as `/mcp__server__prompt`. Arguments go after the command, separated by spaces, and the prompt's result is injected into the conversation.",
          "reference": "https://code.claude.com/docs/en/mcp#use-mcp-prompts-as-commands",
          "evidence": ["claude-mcp-docs"],
          "notes": [
            "Arguments are split on whitespace, so each one must be a single token.",
            "Prompts from a server named `anthropic-skills` are hidden because that name is reserved."
          ]
        },
        "serverAsks": {
          "status": "partial",
          "answer": "Elicitation is supported in both modes: form requests open a dialog, and URL requests ask before opening a link in your browser. The `Elicitation` hook can answer either automatically. Servers can also see your roots: `roots/list` returns the launch directory plus any `--add-dir` directories, and Claude Code sends `list_changed` when they change. The docs don't describe sampling, so servers shouldn't count on calling the model through Claude Code.",
          "reference": "https://code.claude.com/docs/en/mcp#respond-to-mcp-elicitation-requests",
          "evidence": ["claude-mcp-docs", "claude-hooks-docs"],
          "notes": [
            "If a server stops connecting after the v2.1.287 URL-elicitation change, add `\"bareElicitationCapability\": true` to its config entry."
          ]
        },
        "manage": {
          "status": "supported",
          "answer": "Use `claude mcp list` (status for each server), `claude mcp get <name>` (details plus an `Issue:` line on failure) and `claude mcp remove <name>` in the shell. Inside a session, `/mcp` opens a panel to view tools, authenticate, reconnect, disable or clear auth. You can also run `/mcp reconnect <server|all>`, `/mcp enable <server|all>` or `/mcp disable <server|all>` directly. Toggles are saved per project in `~/.claude.json` as `disabledMcpServers`, and `claude --debug=mcp` or `--debug-file` shows connection logs.",
          "reference": "https://code.claude.com/docs/en/mcp#managing-your-servers",
          "evidence": ["claude-mcp-docs", "claude-commands-docs", "claude-cli-reference-docs"],
          "notes": [
            "Remote servers reconnect automatically, with 5 attempts and exponential backoff; stdio servers do not."
          ]
        },
        "serve": {
          "status": "supported",
          "answer": "Yes. `claude mcp serve` runs Claude Code as a stdio MCP server that exposes its own tools, such as file read/edit and Bash, to another client, for example with `\"command\": \"claude\", \"args\": [\"mcp\", \"serve\"]` in Claude Desktop. The connecting client is responsible for confirming each tool call.",
          "reference": "https://code.claude.com/docs/en/mcp#use-claude-code-as-an-mcp-server",
          "evidence": ["claude-mcp-docs"],
          "notes": ["Since v2.1.271, a running tool call sends a progress update every 30 seconds."]
        }
      },
      "observedVersion": "2.1.299"
    },
    {
      "harness": "codex",
      "variant": "current",
      "default": true,
      "protocolRevision": "2025-06-18",
      "clientMode": "interactive TUI, codex exec, and the app server behind the desktop app and IDE extension",
      "sourceRevision": "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d",
      "evidence": [
        "mcp-codex-codex-rs-codex-mcp-src-rmcp-client-rs",
        "delegation-codex-codex-rs-core-src-config-mod-rs",
        "mcp-codex-codex-rs-codex-mcp-src-elicitation-rs",
        "mcp-codex-codex-rs-tui-src-bottom-pane-app-link-view-rs",
        "mcp-codex-codex-rs-rmcp-client-src-rmcp-client-rs",
        "mcp-codex-codex-rs-core-src-tools-handlers-mcp-resource-spec-rs",
        "mcp-codex-codex-rs-rmcp-client-src-logging-client-handler-rs",
        "mcp-codex-codex-rs-rmcp-client-src-elicitation-client-service-rs",
        "mcp-codex-codex-rs-rmcp-client-src-tool-input-rs",
        "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
        "mcp-codex-codex-rs-cli-src-mcp-cmd-rs",
        "mcp-codex-codex-rs-config-src-mcp-types-rs",
        "instructions-codex-learn-chatgpt-com-docs-config-file-config-advanced",
        "instructions-codex-learn-chatgpt-com-docs-enterprise-managed-configuration",
        "mcp-codex-codex-rs-core-src-mcp-tool-call-rs",
        "mcp-codex-codex-rs-core-src-mcp-tool-exposure-rs",
        "mcp-codex-codex-rs-core-src-tools-spec-plan-rs",
        "compaction-6",
        "codex-slash-source-0-162-1",
        "mcp-codex-codex-rs-cli-src-doctor-rs",
        "mcp-codex-learn-chatgpt-com-docs-config-file-config-basic",
        "mcp-codex-learn-chatgpt-com-docs-changelog"
      ],
      "references": {
        "roots": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/rmcp_client.rs#L1106-L1129",
        "sampling": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/rmcp_client.rs#L1106-L1129",
        "samplingTools": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/rmcp_client.rs#L1106-L1129",
        "elicitation": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/config/mod.rs#L1885-L1893",
        "elicitationForm": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/elicitation.rs#L480-L492",
        "elicitationUrl": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/tui/src/bottom_pane/app_link_view.rs#L82-L120",
        "prompts": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/rmcp_client.rs#L696-L819",
        "resources": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/tools/handlers/mcp_resource_spec.rs#L24-L96",
        "resourceTemplates": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/tools/handlers/mcp_resource_spec.rs#L35-L62",
        "completion": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/rmcp_client.rs#L696-L819",
        "progress": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/logging_client_handler.rs#L63-L72",
        "cancellation": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/elicitation_client_service.rs#L298-L330",
        "logging": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/logging_client_handler.rs#L98-L140",
        "subscriptions": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/logging_client_handler.rs#L74-L92",
        "multiRoundTrip": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/tool_input.rs#L39-L165",
        "tasksLegacy": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/rmcp_client.rs#L1106-L1129"
      },
      "support": {
        "roots": "unsupported",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "native",
        "elicitationForm": "native",
        "elicitationUrl": "native",
        "prompts": "unsupported",
        "resources": "native",
        "resourceTemplates": "native",
        "completion": "unsupported",
        "progress": "partial",
        "cancellation": "partial",
        "logging": "partial",
        "subscriptions": "unsupported",
        "multiRoundTrip": "partial",
        "tasksLegacy": "unsupported"
      },
      "notes": [
        "Progress, logging, and MRTR are conformance-path evidence; this does not establish identical UI behavior in every Codex front end.",
        "Deprecated roots and sampling remain unknown on this current-revision path; their explicit omission belongs to the separate legacy contract."
      ],
      "featureNotes": {
        "roots": "The initialize request advertises only elicitation (plus OpenAI extensions); there is no roots capability or roots/list handler.",
        "sampling": "No sampling capability is advertised and sampling/createMessage is not handled.",
        "elicitation": "Form and URL modes are advertised by default (stable auth_elicitation feature). Requests are auto-declined when approval_policy is never or granular.mcp_elicitations is false.",
        "elicitationUrl": "The TUI shows a link view for validated external URLs.",
        "prompts": "The client never calls prompts/list or prompts/get; server prompts are not exposed as commands.",
        "resources": "Model-driven through built-in list_mcp_resources and read_mcp_resource tools; no @-mention picker.",
        "resourceTemplates": "The model lists templates with list_mcp_resource_templates and reads a filled URI with read_mcp_resource.",
        "progress": "Server progress notifications are accepted and written to Codex's log only; model tool calls carry no progress token and nothing is shown in the UI or extends the timeout.",
        "cancellation": "Server-sent cancellation closes a pending prompt, and Codex cancels its own long-lived event-stream requests; general tool-call cancellation is not wired to notifications/cancelled.",
        "logging": "notifications/message is mapped to Codex's own log levels; logging/setLevel is never sent and nothing is shown in the UI.",
        "subscriptions": "resources/subscribe is never sent; update and list_changed notifications are only logged. A separate events/stream extension is used only for the built-in ChatGPT apps server.",
        "multiRoundTrip": "Only for tools/call, and only with the under-development mcp_2026_07_28 feature (off by default) against a server that negotiates 2026-07-28.",
        "tasksLegacy": "No tasks capability is advertised and no tasks/* requests are made."
      },
      "answers": {
        "add": {
          "status": "supported",
          "answer": "Run `codex mcp add <name> -- <command> [args]` for a stdio server (with `--env KEY=VALUE`), or `codex mcp add <name> --url <url>` for a Streamable HTTP server. Either way, the server is written as a `[mcp_servers.<name>]` table in `~/.codex/config.toml`. You can also edit that file or a project `.codex/config.toml` by hand, or use Settings > MCP servers in the desktop app or IDE extension, which share the same config.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#add-an-mcp-server",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "mcp-codex-codex-rs-cli-src-mcp-cmd-rs"
          ],
          "notes": [
            "`codex mcp add` always writes to the user-level config, never to a project file.",
            "Plugins can bundle servers in `.mcp.json`; user config controls them under `plugins.<plugin>.mcp_servers.<server>`."
          ]
        },
        "transports": {
          "status": "supported",
          "answer": "Codex supports stdio servers (`command`, `args`, `env`, `env_vars`, `cwd`) and Streamable HTTP servers (`url`). It has no separate config type for the legacy HTTP+SSE transport or for WebSocket. Setting `experimental_environment = \"remote\"` starts a stdio server through a remote executor.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#supported-mcp-features",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "mcp-codex-codex-rs-config-src-mcp-types-rs"
          ]
        },
        "scopes": {
          "status": "supported",
          "answer": "Servers live in `~/.codex/config.toml` (user) or in `.codex/config.toml` files in a project. Project files are loaded from the project root down to the working directory, with the closest file winning, and only once you trust the project. Admins can set an allowlist in `requirements.toml` (`[mcp_servers.<id>] identity = { command = ... }` or `{ url = ... }`). Any server that isn't on it is disabled, and an empty `mcp_servers` table disables all servers.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#connect-codex-to-an-mcp-server",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "instructions-codex-learn-chatgpt-com-docs-config-file-config-advanced",
            "instructions-codex-learn-chatgpt-com-docs-enterprise-managed-configuration"
          ],
          "notes": [
            "Trusting the project is the only gate: Codex has no separate per-server approval prompt for project-defined servers."
          ]
        },
        "auth": {
          "status": "supported",
          "answer": "For HTTP servers, you can set `bearer_token_env_var`, static `http_headers`, `env_http_headers`, or an `http_headers_helper` command that prints headers as JSON. For OAuth, run `codex mcp login <name>` (with `--scopes` and `--no-browser` available). Codex supports CIMD and DCR client registration plus pre-registered clients via `--oauth-client-id`/`--oauth-client-secret`, and `codex mcp add` starts the login automatically when it detects OAuth. Stdio servers get secrets through `env` or by forwarding variables listed in `env_vars`.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#streamable-http-servers",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "mcp-codex-codex-rs-cli-src-mcp-cmd-rs"
          ],
          "notes": [
            "`mcp_oauth_credentials_store` (`auto`, `file`, `keyring`) chooses where OAuth tokens are stored; `codex mcp logout <name>` removes them.",
            "`auth = \"chatgpt\"` reuses your ChatGPT session, but only for trusted first-party ChatGPT servers."
          ]
        },
        "approval": {
          "status": "supported",
          "answer": "Each server takes a `default_tools_approval_mode` and each tool a `tools.<tool>.approval_mode`: `auto` (the default), `prompt`, `writes` or `approve`. `auto` asks unless the tool is annotated read-only (or explicitly non-destructive and closed-world), and `writes` asks for any tool not marked read-only. At the prompt you can allow once, allow for the session, allow and remember (which saves `approval_mode = \"approve\"` to config), or cancel. `enabled_tools` and `disabled_tools` hide tools completely.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#other-configuration-options",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "mcp-codex-codex-rs-core-src-mcp-tool-call-rs"
          ],
          "notes": [
            "With `approval_policy = \"never\"`, a call that needs approval is denied, unless the sandbox has full write access, in which case it runs without a prompt."
          ]
        },
        "manyTools": {
          "status": "supported",
          "answer": "On models that support tool search, all MCP tools are deferred behind a built-in `tool_search` tool, and the model loads them on demand, so a large catalog doesn't fill the context. You can trim each server with `enabled_tools` (allow list) and `disabled_tools` (deny list, applied after the allow list), or turn a server off with `enabled = false`.",
          "reference": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/mcp_tool_exposure.rs#L85-L89",
          "evidence": [
            "mcp-codex-codex-rs-core-src-mcp-tool-exposure-rs",
            "mcp-codex-codex-rs-core-src-tools-spec-plan-rs",
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp"
          ],
          "notes": [
            "Tool search can't be turned off: the old `tool_search` and `tool_search_always_defer_mcp_tools` switches are retired and rejected.",
            "Tool input schemas larger than `tool_input_schema_max_bytes` (default 5,000 bytes) are compacted."
          ]
        },
        "output": {
          "status": "supported",
          "answer": "Set `startup_timeout_sec` (or `startup_timeout_ms`) and `tool_timeout_sec` per server. In 0.162.1 the built-in defaults are 30 s for startup and 300 s per tool call, while the docs still say 10 s and 60 s. Codex waits `mcp_optional_startup_grace_ms` (default 1000) for optional servers before the first turn, and a `required = true` server that fails to start aborts startup. Tool output is cut to the model's truncation budget unless you set `tools.<tool>.output_token_limit` or the global `tool_output_token_limit`.",
          "reference": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/codex-mcp/src/rmcp_client.rs#L106-L107",
          "evidence": [
            "mcp-codex-codex-rs-codex-mcp-src-rmcp-client-rs",
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "compaction-6"
          ],
          "notes": [
            "When a tool call times out, the model gets an error result instead of tool output."
          ]
        },
        "resources": {
          "status": "partial",
          "answer": "Yes, but only the model uses them. Codex gives the model built-in `list_mcp_resources`, `list_mcp_resource_templates` and `read_mcp_resource` tools for reading server resources. There is no @-mention or picker for attaching a resource yourself, though `/mcp verbose` lists each server's resources and templates.",
          "reference": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/tools/handlers/mcp_resource_spec.rs#L24-L96",
          "evidence": [
            "mcp-codex-codex-rs-core-src-tools-handlers-mcp-resource-spec-rs",
            "mcp-codex-codex-rs-rmcp-client-src-rmcp-client-rs"
          ]
        },
        "prompts": {
          "status": "unsupported",
          "answer": "No. Codex never lists or fetches MCP server prompts, so they don't show up as slash commands or anywhere else in the UI.",
          "reference": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/rmcp-client/src/rmcp_client.rs#L696-L819",
          "evidence": ["mcp-codex-codex-rs-rmcp-client-src-rmcp-client-rs"]
        },
        "serverAsks": {
          "status": "partial",
          "answer": "Elicitation works: Codex advertises both form and URL modes, shows form prompts in the TUI and opens validated URLs in a link view. Elicitations are declined automatically when `approval_policy = \"never\"` or `approval_policy.granular.mcp_elicitations = false`. Sampling and roots aren't supported: Codex doesn't advertise either capability.",
          "reference": "https://github.com/openai/codex/blob/092d3acd6bec3e3a14bdc7e7a2810ab628ab759d/codex-rs/core/src/config/mod.rs#L1885-L1893",
          "evidence": [
            "delegation-codex-codex-rs-core-src-config-mod-rs",
            "mcp-codex-codex-rs-codex-mcp-src-rmcp-client-rs",
            "mcp-codex-codex-rs-codex-mcp-src-elicitation-rs",
            "compaction-6"
          ]
        },
        "manage": {
          "status": "supported",
          "answer": "Use `codex mcp list` and `codex mcp get <name>` (both accept `--json`) to see configured servers, `/mcp` in the TUI to see live servers and tools, `/mcp verbose` for full details including resources, and `/mcp login <name>` to sign in. To disable a server without deleting it, set `enabled = false`; `codex mcp remove <name>` deletes it. The desktop app and IDE extension have Restart buttons, and the TUI picks up config changes when you start a new session.",
          "reference": "https://learn.chatgpt.com/docs/extend/mcp#other-cli-commands",
          "evidence": [
            "mcp-codex-learn-chatgpt-com-docs-extend-mcp",
            "codex-slash-source-0-162-1",
            "mcp-codex-codex-rs-cli-src-doctor-rs",
            "mcp-codex-learn-chatgpt-com-docs-config-file-config-basic"
          ],
          "notes": [
            "`codex doctor` includes an MCP configuration check.",
            "Setting `log_dir` writes `codex-tui.log`, which includes server log messages and connection errors."
          ]
        },
        "serve": {
          "status": "unsupported",
          "answer": "No. `codex mcp-server` and the standalone `codex-mcp-server` binary were deprecated on 2026-08-24 and removed on 2026-09-05. Other clients should integrate through the experimental `codex app-server` instead.",
          "reference": "https://learn.chatgpt.com/docs/changelog#codex-2026-09-05",
          "evidence": ["mcp-codex-learn-chatgpt-com-docs-changelog"]
        }
      },
      "observedVersion": "0.162.1"
    },
    {
      "harness": "codex",
      "variant": "legacy-client-source",
      "default": false,
      "protocolRevision": "2025-06-18",
      "clientMode": "native MCP client",
      "sourceRevision": "0ae94fdd49b05ee7faa4d984d06a68492cb32b54",
      "evidence": ["codex-mcp-client-source", "codex-appserver-source", "mcp-current-spec"],
      "references": {
        "roots": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/codex-mcp/src/rmcp_client.rs#L1011-L1017",
        "sampling": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/codex-mcp/src/rmcp_client.rs#L1011-L1017",
        "samplingTools": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/codex-mcp/src/rmcp_client.rs#L1011-L1017",
        "elicitation": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/app-server/README.md?plain=1#L1926-L1937",
        "elicitationForm": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/app-server/README.md?plain=1#L1926-L1937",
        "elicitationUrl": "https://github.com/openai/codex/blob/0ae94fdd49b05ee7faa4d984d06a68492cb32b54/codex-rs/app-server/README.md?plain=1#L1926-L1937",
        "multiRoundTrip": "https://modelcontextprotocol.io/specification/2026-07-28/basic/index#messages"
      },
      "support": {
        "roots": "unsupported",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "native",
        "elicitationForm": "native",
        "elicitationUrl": "native",
        "prompts": "unknown",
        "resources": "unknown",
        "resourceTemplates": "unknown",
        "completion": "unknown",
        "progress": "unknown",
        "cancellation": "unknown",
        "logging": "unknown",
        "subscriptions": "unknown",
        "multiRoundTrip": "unsupported",
        "tasksLegacy": "unknown"
      },
      "notes": [
        "The legacy capability constructor advertises elicitation but not roots or sampling.",
        "Multi-round-trip requests belong to the later 2026-07-28 protocol architecture."
      ]
    },
    {
      "harness": "cursor-agent",
      "variant": "documented-current",
      "default": true,
      "protocolRevision": "2025-11-25",
      "clientMode": "interactive CLI, headless print mode and ACP sessions share one MCP client",
      "evidence": [
        "mcp-skills-refresh-cursor-mcp",
        "cursor-cli-mcp-docs",
        "cursor-cli-parameters-docs",
        "cursor-cli-changelog",
        "mcp-cursor-agent-cursor-com-help-customization-mcp",
        "cursor-permissions-docs",
        "mcp-cursor-agent-cursor-com-docs-reference-permissions",
        "mcp-cursor-agent-cursor-com-docs-agent-security-run-modes",
        "mcp-cursor-agent-cursor-com-blog-dynamic-context-discovery",
        "cursor-acp-docs"
      ],
      "references": {
        "roots": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "sampling": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "samplingTools": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "elicitation": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "elicitationForm": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "elicitationUrl": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "prompts": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "resources": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "resourceTemplates": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "completion": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "progress": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "cancellation": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "logging": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "subscriptions": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "multiRoundTrip": "https://cursor.com/docs/mcp#protocol-and-extension-support",
        "tasksLegacy": "https://cursor.com/docs/mcp#protocol-and-extension-support"
      },
      "support": {
        "roots": "unsupported",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "partial",
        "elicitationForm": "partial",
        "elicitationUrl": "unsupported",
        "prompts": "partial",
        "resources": "native",
        "resourceTemplates": "unsupported",
        "completion": "unsupported",
        "progress": "unsupported",
        "cancellation": "unsupported",
        "logging": "unsupported",
        "subscriptions": "unsupported",
        "multiRoundTrip": "unsupported",
        "tasksLegacy": "unsupported"
      },
      "notes": [
        "The first-party table says generic elicitation is supported but does not split form from URL mode, so both granular modes remain unknown until tested."
      ],
      "featureNotes": {
        "roots": "In CLI 2026.10.12 the MCP client does not declare the roots capability, so servers cannot list roots. The docs table lists Roots as supported, which describes the editor.",
        "sampling": "Sampling is not in Cursor's support table, and the CLI does not declare the sampling capability.",
        "samplingTools": "There is no sampling, so there is no sampling with tools either.",
        "elicitation": "Cursor documents elicitation, and the editor lets you answer it. The CLI advertises form elicitation but has no way to show the form, so it declines every request.",
        "elicitationForm": "In CLI 2026.10.12 the client advertises `elicitation.form`, but every form request gets an automatic `decline` because the CLI has no form prompt.",
        "elicitationUrl": "The CLI does not advertise URL mode and declines URL-mode requests.",
        "prompts": "The CLI lists a server's prompts in its `/mcp` detail view but cannot run them; there are no prompt slash commands. The editor documents prompts as supported.",
        "resources": "In the CLI the agent lists and reads resources itself (List MCP Resources / Fetch MCP Resource tool calls). You cannot @-mention them.",
        "resourceTemplates": "Only concrete resources from `resources/list` are offered. Templates are never listed.",
        "completion": "The CLI never asks servers for argument completions.",
        "progress": "In CLI 2026.10.12, tool calls carry no progress token, so server progress is neither shown nor used to extend timeouts.",
        "cancellation": "In CLI 2026.10.12, tool calls are sent without an abort signal, so stopping the agent does not send `notifications/cancelled` to the server.",
        "logging": "The CLI neither sets a log level nor handles `notifications/message`. Stdio stderr is only surfaced in startup errors.",
        "subscriptions": "The CLI does not subscribe to resources. It does refresh tools when a server sends `notifications/tools/list_changed`.",
        "multiRoundTrip": "The client speaks protocol revisions up to 2025-11-25, which predate multi-round-trip requests.",
        "tasksLegacy": "The client declares no tasks capability. Tools that require task-based execution fail."
      },
      "answers": {
        "add": {
          "status": "supported",
          "answer": "There is no `agent mcp add` command. Edit `mcp.json` by hand (`~/.cursor/mcp.json` or `.cursor/mcp.json`) with a top-level `mcpServers` object keyed by server name. Local servers use `command`, `args`, `env` and `envFile`; remote servers use `url` and `headers`. Plugins installed with `/plugin` and team-marketplace servers also add MCP servers.",
          "reference": "https://cursor.com/docs/mcp#using-mcpjson",
          "evidence": [
            "mcp-skills-refresh-cursor-mcp",
            "cursor-cli-mcp-docs",
            "cursor-cli-parameters-docs",
            "cursor-cli-changelog"
          ],
          "notes": [
            "The CLI and the editor read the same `mcp.json` files, so a server added in one works in both.",
            "The installed binary is `cursor-agent`; the docs call it `agent`."
          ]
        },
        "transports": {
          "status": "supported",
          "answer": "The CLI supports stdio (`command`), Streamable HTTP (`url`) and legacy SSE. For a `url` server it tries Streamable HTTP first and falls back to SSE. You can also pin `\"type\": \"sse\"` or `\"type\": \"http\"`. WebSocket is not supported.",
          "reference": "https://cursor.com/docs/mcp#how-it-works",
          "evidence": ["mcp-skills-refresh-cursor-mcp", "cursor-cli-mcp-docs"]
        },
        "scopes": {
          "status": "supported",
          "answer": "User servers live in `~/.cursor/mcp.json` and project servers in `.cursor/mcp.json`; both are loaded, and if a name appears in both, the project entry wins. When the same remote server appears in several scopes, the CLI runs it once, and you choose the winning scope in the server's Configure Scope tab in `/mcp`. Team servers come from the dashboard or team marketplace. Project servers need approval before they load (an \"MCP Server Approval Required\" prompt, `agent mcp enable <name>`, or `--approve-mcps`), but servers in `~/.cursor/mcp.json` load without a prompt.",
          "reference": "https://cursor.com/help/customization/mcp#how-do-i-install-an-mcp-server-manually",
          "evidence": [
            "mcp-cursor-agent-cursor-com-help-customization-mcp",
            "mcp-skills-refresh-cursor-mcp",
            "cursor-cli-mcp-docs",
            "cursor-cli-changelog"
          ],
          "notes": [
            "The CLI also finds `.cursor/mcp.json` in parent directories, up to the project root.",
            "Team MCP servers configured in the dashboard are not available in ACP mode."
          ]
        },
        "auth": {
          "status": "supported",
          "answer": "For OAuth servers, run `agent mcp login <name>` or choose Login in `/mcp`. The browser flow returns to `http://localhost:8787/callback`, and Logout in `/mcp` clears the stored tokens. If the provider has no dynamic client registration, add an `auth` object with `CLIENT_ID`, optional `CLIENT_SECRET` and `scopes`. For token auth, put secrets in `headers` or `env` with `${env:NAME}` interpolation, or use `envFile` for stdio servers.",
          "reference": "https://cursor.com/docs/cli/mcp#login-to-mcp-server",
          "evidence": [
            "cursor-cli-mcp-docs",
            "mcp-skills-refresh-cursor-mcp",
            "cursor-cli-changelog"
          ],
          "notes": [
            "Over SSH, the CLI prints port-forwarding instructions for the OAuth callback.",
            "Interpolation works in `command`, `args`, `env`, `url`, `headers` and `auth`."
          ]
        },
        "approval": {
          "status": "supported",
          "answer": "By default MCP tool calls ask for approval, and the prompt can allowlist that tool. To pre-allow tools, add `Mcp(server:tool)` entries (with `*` wildcards) to `permissions.allow` or `permissions.deny` in `~/.cursor/cli-config.json` or `.cursor/cli.json`; deny wins. The CLI also reads `mcpAllowlist` from `permissions.json`. In Auto-review mode (`--auto-review`), allowlisted calls run and the rest go to a classifier; `--force` / `--yolo` runs everything that isn't denied.",
          "reference": "https://cursor.com/docs/cli/reference/permissions#mcp-tools",
          "evidence": [
            "cursor-permissions-docs",
            "mcp-cursor-agent-cursor-com-docs-reference-permissions",
            "mcp-cursor-agent-cursor-com-docs-agent-security-run-modes",
            "cursor-cli-changelog",
            "mcp-skills-refresh-cursor-mcp"
          ],
          "notes": [
            "Server-level approval is separate: `agent mcp disable <name>` stops a server from loading at all.",
            "Enterprise admins can limit which servers and tools may run from the dashboard MCP Allowlist, and the CLI enforces it."
          ]
        },
        "manyTools": {
          "status": "supported",
          "answer": "Cursor loads MCP tools on demand. The agent gets only tool names plus a way to look up full tool definitions when needed, so many servers don't flood the prompt. There is no documented tool-count cap. To trim the set, disable whole servers with `agent mcp disable` or in `/mcp`; there is no per-tool on/off switch in the CLI.",
          "reference": "https://cursor.com/blog/dynamic-context-discovery#4-efficiently-loading-only-the-mcp-tools-needed",
          "evidence": [
            "mcp-cursor-agent-cursor-com-blog-dynamic-context-discovery",
            "cursor-cli-mcp-docs",
            "cursor-cli-changelog"
          ],
          "notes": [
            "When a tool seems to be missing, the agent refreshes the server's tool list. A call to a nonexistent tool returns the list of available tools."
          ]
        },
        "output": {
          "status": "supported",
          "answer": "Large MCP text output is saved to a file instead of being truncated. In CLI 2026.10.12, text over 40,000 bytes goes to a file under Cursor's per-project `agent-tools` folder (up to about 49 MB), and the agent reads it from there. A stdio server gets 60 seconds to start and initialize, and each MCP request, including a tool call, times out after 60 seconds; progress notifications don't extend it. A timeout or crash shows as a failed tool call, and other servers keep working.",
          "reference": "https://cursor.com/blog/dynamic-context-discovery#1-turning-long-tool-responses-into-files",
          "evidence": [
            "mcp-cursor-agent-cursor-com-blog-dynamic-context-discovery",
            "mcp-skills-refresh-cursor-mcp",
            "cursor-cli-changelog"
          ],
          "notes": [
            "None of these limits can be configured in `mcp.json`.",
            "Image content is passed to the model as an image."
          ]
        },
        "resources": {
          "status": "partial",
          "answer": "Only the agent can use server resources in the CLI. It lists them and fetches one by URI, optionally saving it to a path inside the workspace, and these reads follow the same approval rules as other MCP calls. You cannot @-mention a resource, and resource templates are not offered.",
          "reference": "https://cursor.com/docs/mcp#protocol-and-extension-support",
          "evidence": ["mcp-skills-refresh-cursor-mcp"],
          "notes": [
            "The editor documents resources as \"read and referenced\"; the CLI exposes them only to the agent."
          ]
        },
        "prompts": {
          "status": "partial",
          "answer": "The CLI shows a server's prompts in its `/mcp` detail view but has no way to run them. MCP prompts don't become slash commands, and the agent can't fetch them. Prompt support in Cursor's docs refers to the editor.",
          "reference": "https://cursor.com/docs/mcp#protocol-and-extension-support",
          "evidence": ["mcp-skills-refresh-cursor-mcp", "cursor-cli-mcp-docs"]
        },
        "serverAsks": {
          "status": "unsupported",
          "answer": "Not in the CLI. It advertises form elicitation but has no prompt for it, so every elicitation request is declined, and URL-mode requests are declined too. It offers no sampling and no roots. The editor documents elicitation and roots as supported.",
          "reference": "https://cursor.com/docs/mcp#protocol-and-extension-support",
          "evidence": ["mcp-skills-refresh-cursor-mcp"]
        },
        "manage": {
          "status": "supported",
          "answer": "`agent mcp list` (or `/mcp` in a session) opens a pager of servers grouped by User / Project / Team, showing status, transport and the error for failed servers. Each server's detail view lets you browse tool schemas, Login/Logout, Enable/Disable and Configure Scope. `agent mcp list-tools <name>` prints a server's tools and arguments, and `agent mcp enable|disable <name>` toggles a server. Changes apply to the running session.",
          "reference": "https://cursor.com/docs/cli/mcp#list-configured-servers",
          "evidence": ["cursor-cli-mcp-docs", "cursor-cli-changelog"],
          "notes": [
            "There is no separate reconnect command; to restart a server, disable and re-enable it.",
            "The \"MCP Logs\" output panel exists only in the editor."
          ]
        },
        "serve": {
          "status": "unsupported",
          "answer": "No. Cursor CLI cannot run as an MCP server. Its server mode is ACP (`agent acp`), which lets editors such as Zed or JetBrains drive the agent, and MCP servers those editors pass in over ACP are loaded.",
          "reference": "https://cursor.com/docs/cli/mcp#mcp-vs-acp",
          "evidence": ["cursor-cli-mcp-docs", "cursor-acp-docs", "cursor-cli-changelog"]
        }
      },
      "observedVersion": "2026.10.12-d47ca18"
    },
    {
      "harness": "opencode",
      "variant": "1.x",
      "default": false,
      "protocolRevision": "version-negotiated",
      "clientMode": "interactive TUI, `opencode run` and the HTTP server, all sharing one MCP client per project",
      "support": {
        "roots": "native",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "unsupported",
        "elicitationForm": "unsupported",
        "elicitationUrl": "unsupported",
        "prompts": "native",
        "resources": "native",
        "resourceTemplates": "native",
        "completion": "unsupported",
        "progress": "partial",
        "cancellation": "native",
        "logging": "native",
        "subscriptions": "unsupported",
        "multiRoundTrip": "unsupported",
        "tasksLegacy": "unsupported"
      },
      "references": {
        "roots": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L75-L81",
        "sampling": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "samplingTools": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "elicitation": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "elicitationForm": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "elicitationUrl": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "prompts": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/command/index.ts#L105-L130",
        "resources": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/session/tools.ts#L136-L139",
        "resourceTemplates": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/session/tools.ts#L222-L230",
        "completion": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/catalog.ts#L121-L143",
        "progress": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/catalog.ts#L53-L67",
        "cancellation": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/catalog.ts#L53-L67",
        "logging": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L457-L490",
        "subscriptions": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L461-L471",
        "multiRoundTrip": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50",
        "tasksLegacy": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L50"
      },
      "featureNotes": {
        "roots": "Answers `roots/list` with the project directory only.",
        "sampling": "`sampling` is commented out of the client capabilities.",
        "elicitation": "`elicitation` is commented out of the client capabilities.",
        "prompts": "Server prompts become slash commands with positional `$1`, `$2` arguments.",
        "resources": "`@`-mention in the TUI plus `list_mcp_resources` and `read_mcp_resource` tools for the agent.",
        "resourceTemplates": "Listed to the agent by `list_mcp_resource_templates`; the agent fills the URI and reads it.",
        "completion": "The client never sends `completion/complete`.",
        "progress": "Progress notifications only reset the request timeout; they are not shown.",
        "cancellation": "Aborting a turn aborts the tool call's signal, which sends `notifications/cancelled`.",
        "logging": "Server log messages are written to OpenCode's log at the matching level, not shown in the UI.",
        "subscriptions": "Only `notifications/tools/list_changed` is handled; no resource subscriptions.",
        "tasksLegacy": "`tasks` is commented out of the client capabilities."
      },
      "evidence": [
        "mcp-opencode-packages-opencode-src-mcp-index-ts",
        "memory-opencode-packages-opencode-src-command-index-ts",
        "mcp-opencode-packages-opencode-src-session-tools-ts",
        "mcp-opencode-packages-opencode-src-mcp-catalog-ts",
        "opencode-mcp-docs",
        "opencode-cli-stable-docs",
        "opencode-1-19-0-source",
        "mcp-opencode-packages-core-src-v1-config-mcp-ts",
        "instructions-opencode-opencode-ai-docs-config",
        "mcp-opencode-packages-opencode-src-mcp-auth-ts",
        "mcp-opencode-opencode-ai-docs-tools",
        "opencode-permissions-docs",
        "delegation-opencode-packages-opencode-src-agent-agent-ts",
        "instructions-opencode-packages-opencode-src-effect-runtime-flags-ts",
        "mcp-opencode-packages-opencode-src-tool-truncate-ts",
        "mcp-opencode-packages-core-src-v1-config-config-ts",
        "mcp-opencode-packages-tui-src-component-prompt-autocomplete-tsx",
        "steering-opencode-packages-opencode-src-session-prompt-ts",
        "mcp-opencode-packages-tui-src-app-tsx"
      ],
      "answers": {
        "add": {
          "status": "supported",
          "answer": "Run `opencode mcp add` for an interactive wizard, or `opencode mcp add <name> --url <url> [--header K=V]` / `opencode mcp add <name> [--env K=V] -- <command...>` non-interactively. Servers live under the `mcp` key of `opencode.json(c)`, keyed by name, with `\"type\": \"local\"` plus `command` (array) or `\"type\": \"remote\"` plus `url`.",
          "reference": "https://opencode.ai/docs/mcp-servers/#enable",
          "evidence": [
            "opencode-mcp-docs",
            "opencode-cli-stable-docs",
            "opencode-1-19-0-source",
            "mcp-opencode-packages-core-src-v1-config-mcp-ts"
          ],
          "notes": [
            "The non-interactive form always writes to the global config; the wizard asks Current project or Global when run inside a git repo."
          ]
        },
        "transports": {
          "status": "supported",
          "answer": "Local servers use stdio. Remote servers try Streamable HTTP first and fall back to the legacy HTTP+SSE transport automatically. WebSocket is not supported.",
          "reference": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L269-L292",
          "evidence": ["mcp-opencode-packages-opencode-src-mcp-index-ts", "opencode-mcp-docs"]
        },
        "scopes": {
          "status": "supported",
          "answer": "Configs merge in order: remote `.well-known/opencode` defaults, global `~/.config/opencode/opencode.json`, `OPENCODE_CONFIG`, project `opencode.json` (searched up to the git root) and `.opencode/opencode.json`, `OPENCODE_CONFIG_CONTENT`, then managed files (`/Library/Application Support/opencode/`, `/etc/opencode/`) and macOS MDM preferences. Later sources override earlier ones per key. Project servers start without any trust or approval prompt.",
          "reference": "https://opencode.ai/docs/config/#precedence-order",
          "evidence": ["instructions-opencode-opencode-ai-docs-config", "opencode-mcp-docs"]
        },
        "auth": {
          "status": "supported",
          "answer": "Remote servers get automatic OAuth: on a 401 OpenCode discovers the auth server, tries dynamic client registration, and you finish with `opencode mcp auth <name>`, which opens the browser (callback `http://127.0.0.1:19876/mcp/oauth/callback`). Pre-registered clients use `oauth.clientId`, `clientSecret`, `scope`, `callbackPort` or `redirectUri`. For API keys set `\"oauth\": false` and send `headers`; local servers take `environment`, and `{env:NAME}` substitution works in config values.",
          "reference": "https://opencode.ai/docs/mcp-servers/#oauth",
          "evidence": [
            "opencode-mcp-docs",
            "mcp-opencode-packages-core-src-v1-config-mcp-ts",
            "mcp-opencode-packages-opencode-src-mcp-auth-ts"
          ],
          "notes": [
            "Tokens are stored in `~/.local/share/opencode/mcp-auth.json`; `opencode mcp logout <name>` removes them."
          ]
        },
        "approval": {
          "status": "supported",
          "answer": "MCP tools run without asking by default because the base permission is `\"*\": \"allow\"`. Each tool is a permission key named `<server>_<tool>`, so `\"permission\": {\"myserver_*\": \"ask\"}` or `\"deny\"` controls a whole server, and agents can override per agent. The older `tools` booleans with globs (e.g. `\"myserver_*\": false`) still work but are deprecated in favour of `permission`.",
          "reference": "https://opencode.ai/docs/tools/#configure",
          "evidence": [
            "mcp-opencode-opencode-ai-docs-tools",
            "opencode-permissions-docs",
            "opencode-mcp-docs",
            "mcp-opencode-packages-opencode-src-session-tools-ts",
            "delegation-opencode-packages-opencode-src-agent-agent-ts"
          ],
          "notes": [
            "Reading resources goes through the `read` permission with patterns like `mcp:<server>:<uri>`."
          ]
        },
        "manyTools": {
          "status": "partial",
          "answer": "Every connected server's tools are sent to the model; there is no tool search or deferred loading. Trim the list by disabling servers (`\"enabled\": false`), denying tools with `<server>_*` globs, or enabling a server only for specific agents. An experimental Code Mode (`OPENCODE_EXPERIMENTAL_CODE_MODE=1`) replaces direct MCP tools with a single `execute` scripting tool.",
          "reference": "https://opencode.ai/docs/mcp-servers/#per-agent",
          "evidence": [
            "opencode-mcp-docs",
            "mcp-opencode-packages-opencode-src-session-tools-ts",
            "instructions-opencode-packages-opencode-src-effect-runtime-flags-ts"
          ]
        },
        "output": {
          "status": "supported",
          "answer": "MCP tool text is truncated at 2000 lines or 50 KB (`tool_output.max_lines` / `max_bytes`); the full output is saved to a file and the model gets a preview plus the path. The per-server `timeout` (default 30 s in source) covers connecting and listing tools; tool calls use `timeout` or `experimental.mcp_timeout`, else 60 s, and the timer resets while the server sends progress. Binary resource blobs over 10 MB, or of unsupported types, are dropped with a note.",
          "reference": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/session/tools.ts#L464-L469",
          "evidence": [
            "mcp-opencode-packages-opencode-src-session-tools-ts",
            "mcp-opencode-packages-opencode-src-tool-truncate-ts",
            "mcp-opencode-packages-opencode-src-mcp-index-ts",
            "mcp-opencode-packages-opencode-src-mcp-catalog-ts",
            "mcp-opencode-packages-core-src-v1-config-config-ts"
          ],
          "notes": [
            "The docs say the `timeout` default is 5000 ms, but the 1.19.0 source uses 30000 ms."
          ]
        },
        "resources": {
          "status": "supported",
          "answer": "Yes. Type `@` in the TUI prompt to pick an MCP resource by name; its contents are read and attached to your message. The agent also gets `list_mcp_resources`, `list_mcp_resource_templates` and `read_mcp_resource` tools whenever a connected server supports resources.",
          "reference": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/tui/src/component/prompt/autocomplete.tsx#L366-L397",
          "evidence": [
            "mcp-opencode-packages-tui-src-component-prompt-autocomplete-tsx",
            "steering-opencode-packages-opencode-src-session-prompt-ts",
            "mcp-opencode-packages-opencode-src-session-tools-ts"
          ]
        },
        "prompts": {
          "status": "supported",
          "answer": "Yes. Each server prompt appears as a slash command named after the prompt, and positional arguments fill the prompt's arguments in order (`$1`, `$2`, ...). Only the text parts of the returned messages are used.",
          "reference": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/command/index.ts#L105-L130",
          "evidence": ["memory-opencode-packages-opencode-src-command-index-ts"]
        },
        "serverAsks": {
          "status": "partial",
          "answer": "Only roots: OpenCode answers `roots/list` with the project directory. Elicitation and sampling are not advertised, so servers cannot ask you for input or use the model.",
          "reference": "https://github.com/anomalyco/opencode/blob/733b2c627e5aec39cb33cc22373bdce33053ef2c/packages/opencode/src/mcp/index.ts#L39-L81",
          "evidence": ["mcp-opencode-packages-opencode-src-mcp-index-ts"]
        },
        "manage": {
          "status": "supported",
          "answer": "`opencode mcp list` shows each server's status (connected, disabled, failed, needs auth, needs client registration), and `/mcps` in the TUI toggles servers on and off for the running instance. `\"enabled\": false` disables a server persistently. For OAuth problems, `opencode mcp auth list` shows token status and `opencode mcp debug <name>` tests connectivity and OAuth discovery.",
          "reference": "https://opencode.ai/docs/mcp-servers/#debugging",
          "evidence": [
            "opencode-mcp-docs",
            "opencode-cli-stable-docs",
            "mcp-opencode-packages-tui-src-app-tsx"
          ],
          "notes": [
            "Server logs are written to OpenCode's log; run with `--print-logs` to see them on stderr."
          ]
        },
        "serve": {
          "status": "unsupported",
          "answer": "No. OpenCode does not run as an MCP server. `opencode serve` exposes its own HTTP API and `opencode acp` speaks the Agent Client Protocol.",
          "reference": "https://opencode.ai/docs/cli/#serve",
          "evidence": ["opencode-cli-stable-docs"]
        }
      },
      "observedVersion": "1.19.0",
      "sourceRevision": "733b2c627e5aec39cb33cc22373bdce33053ef2c"
    },
    {
      "harness": "opencode",
      "variant": "2.x",
      "default": true,
      "protocolRevision": "2025-11-25; 2026-07-28 opt-in per server",
      "clientMode": "the shared background server, which owns tool execution for the TUI, `opencode mini`, the desktop/web app and `opencode run`; one MCP client per project location",
      "support": {
        "roots": "native",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "native",
        "elicitationForm": "native",
        "elicitationUrl": "native",
        "prompts": "native",
        "resources": "native",
        "resourceTemplates": "native",
        "completion": "unsupported",
        "progress": "partial",
        "cancellation": "native",
        "logging": "unsupported",
        "subscriptions": "partial",
        "multiRoundTrip": "partial",
        "tasksLegacy": "unsupported"
      },
      "references": {
        "roots": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L187-L206",
        "sampling": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L186-L192",
        "samplingTools": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L186-L192",
        "elicitation": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L231-L302",
        "elicitationForm": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L268-L295",
        "elicitationUrl": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L238-L267",
        "prompts": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/plugin/command.ts#L55-L80",
        "resources": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/tool/plugin/mcp-resource.ts#L17-L97",
        "resourceTemplates": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L367-L400",
        "completion": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L114-L138",
        "progress": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L352-L363",
        "cancellation": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L319-L363",
        "logging": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L184-L214",
        "subscriptions": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L154-L161",
        "multiRoundTrip": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L238-L242",
        "tasksLegacy": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/client.ts#L186-L192"
      },
      "featureNotes": {
        "roots": "Answers `roots/list` with the project directory; only on legacy-era connections.",
        "sampling": "No `sampling` capability is declared.",
        "elicitation": "Requests appear as forms in OpenCode's UI.",
        "elicitationForm": "Schema fields become form fields; accept or cancel is returned.",
        "elicitationUrl": "Shown as an external-link form; legacy `notifications/elicitation/complete` settles it.",
        "prompts": "Prompts become `/<server>:<prompt>` commands.",
        "resources": "Available to the agent through `list_mcp_resources` and `read_mcp_resource`.",
        "resourceTemplates": "Templates are listed alongside resources; the agent expands `uriTemplate` before reading.",
        "completion": "The connection exposes no completion call.",
        "progress": "Progress keeps long calls alive; it is not displayed.",
        "cancellation": "Requests carry an abort signal that cancels the in-flight request.",
        "logging": "No `notifications/message` handler; stdio stderr goes to the debug log instead.",
        "subscriptions": "On 2026-07-28 connections the SDK keeps a `subscriptions/listen` stream for tool, prompt and resource list changes; resource-content subscriptions are not used.",
        "multiRoundTrip": "On 2026-07-28 connections the SDK retries a call after elicitation input; requires `protocol` set to `auto` or `2026-07-28`, and sampling is not offered.",
        "tasksLegacy": "No `tasks` capability is declared."
      },
      "evidence": [
        "mcp-opencode-packages-core-src-mcp-client-ts",
        "mcp-opencode-packages-core-src-mcp-index-ts",
        "memory-opencode-packages-core-src-plugin-command-ts",
        "mcp-opencode-packages-core-src-tool-plugin-mcp-resource-ts",
        "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
        "opencode-2-0-29-source",
        "mcp-opencode-packages-cli-src-commands-handlers-mcp-add-ts",
        "instructions-opencode-opencode-ai-v2-docs-config",
        "mcp-opencode-packages-core-src-config-plugin-mcp-ts",
        "mcp-opencode-packages-core-src-config-plugin-policy-ts",
        "mcp-opencode-packages-schema-src-mcp-ts",
        "mcp-opencode-opencode-ai-v2-docs-permissions",
        "mcp-opencode-packages-core-src-tool-mcp-ts",
        "mcp-opencode-opencode-ai-v2-docs-tools",
        "mcp-opencode-opencode-ai-v2-docs-attachments",
        "mcp-opencode-packages-core-src-mcp-stdio-ts",
        "mcp-opencode-opencode-ai-v2-docs-cli"
      ],
      "answers": {
        "add": {
          "status": "supported",
          "answer": "Run `opencode mcp add <name> --url <url>` for a remote server or `opencode mcp add <name> -- <command...>` for a local one; `--header name=value`, `--env name=value` and `--global` are available. It writes to the project `opencode.json(c)` unless `--global` is given. By hand, add the server under `mcp.servers.<name>` (V2 no longer puts server names directly under `mcp`).",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#setup",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "opencode-2-0-29-source",
            "mcp-opencode-packages-cli-src-commands-handlers-mcp-add-ts"
          ]
        },
        "transports": {
          "status": "supported",
          "answer": "Local servers use stdio and remote servers use Streamable HTTP with an absolute URL. The legacy HTTP+SSE fallback from 1.x is gone, and WebSocket is not supported.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#remote",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-packages-core-src-mcp-client-ts"
          ]
        },
        "scopes": {
          "status": "supported",
          "answer": "Servers can be defined in global `~/.config/opencode/opencode.json(c)`, project `opencode.json(c)` or `.opencode/opencode.json(c)` files found from the current directory up to the filesystem root, and the managed system directory or macOS MDM preferences, which win. A higher-precedence file replaces the whole server object with the same name rather than merging fields. Project servers connect without a trust prompt; administrators can block a server with a managed policy on `integration.use` for `mcp:<name>`.",
          "reference": "https://opencode.ai/v2/docs/config/#locations",
          "evidence": [
            "instructions-opencode-opencode-ai-v2-docs-config",
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-packages-core-src-config-plugin-mcp-ts",
            "mcp-opencode-packages-core-src-config-plugin-policy-ts"
          ]
        },
        "auth": {
          "status": "supported",
          "answer": "OAuth is on for every remote server unless `\"oauth\": false`: OpenCode discovers the auth server, uses PKCE, refreshes tokens and tries dynamic client registration. Sign in from `/mcps` or with `opencode mcp auth <name>`, and sign out with `opencode mcp logout <name>`; credentials stay out of project config. Pre-registered clients use snake_case `client_id`, `client_secret`, `scope`, `callback_port`, `redirect_uri` and `auth_server_metadata_url`; API keys go in `headers` or `environment` with `{env:NAME}` substitution.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#oauth",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-packages-schema-src-mcp-ts"
          ]
        },
        "approval": {
          "status": "supported",
          "answer": "MCP tools run without asking by default because every agent starts from an allow-all base policy. Add ordered `permissions` rules on the action `<server>_<tool>` (globs allowed, resource `*`) with effect `allow`, `ask` or `deny`, globally or under `agents.<id>.permissions`. Choosing Allow always saves a project-scoped allow rule.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#permissions",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-opencode-ai-v2-docs-permissions",
            "mcp-opencode-packages-core-src-tool-mcp-ts"
          ]
        },
        "manyTools": {
          "status": "supported",
          "answer": "Code Mode is the default: MCP tools are not put on the model's native tool list but grouped by server inside the `execute` JavaScript tool (e.g. `tools.context7.resolve_library_id(...)`), so many tools don't each cost a tool slot. Set `\"codemode\": false` on a server to expose its tools directly, deny tools with `<server>_*` permission rules, or set `\"disabled\": true`.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#permissions",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-opencode-ai-v2-docs-tools"
          ],
          "notes": ["Denying the `execute` permission turns Code Mode off."]
        },
        "output": {
          "status": "supported",
          "answer": "Timeouts are set under `mcp.timeout` with per-server overrides: `startup` 30 s (connect and initialize), `catalog` 30 s (listing tools, prompts, resources) and `execution` 12 hours (tool calls, prompts, resource reads). Tool results are truncated at `tool_output.max_lines` 2000 / `max_bytes` 51200, with the full output saved to a file for the agent. A call that passes `execution` fails with a timeout error.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#timeouts",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "instructions-opencode-opencode-ai-v2-docs-config",
            "mcp-opencode-packages-core-src-mcp-client-ts"
          ]
        },
        "resources": {
          "status": "partial",
          "answer": "The agent can list and read server resources with the built-in `list_mcp_resources` and `read_mcp_resource` tools, and images or PDFs come back as attachments. There is no `@`-mention picker for MCP resources in 2.x; prompt attachments only accept `file:` and `data:` URIs.",
          "reference": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/tool/plugin/mcp-resource.ts#L17-L97",
          "evidence": [
            "mcp-opencode-packages-core-src-tool-plugin-mcp-resource-ts",
            "mcp-opencode-opencode-ai-v2-docs-attachments"
          ]
        },
        "prompts": {
          "status": "supported",
          "answer": "Yes. Each prompt becomes a command named `/<server>:<prompt>` (names normalized to letters, digits, `_` and `-`), and space-separated arguments fill the prompt's arguments in order. The list refreshes when the server reports prompt changes.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#names",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "memory-opencode-packages-core-src-plugin-command-ts"
          ]
        },
        "serverAsks": {
          "status": "partial",
          "answer": "Servers can ask for input through elicitation: form requests open as a form you fill in, and URL requests open as an external link to complete. Servers get `roots` (the project directory) on classic connections, but sampling is not supported, so a server cannot call the model.",
          "reference": "https://github.com/anomalyco/opencode/blob/042d0832f5f3a73eaa039a58a7d565776f6d4290/packages/core/src/mcp/index.ts#L231-L302",
          "evidence": [
            "mcp-opencode-packages-core-src-mcp-index-ts",
            "mcp-opencode-packages-core-src-mcp-client-ts"
          ]
        },
        "manage": {
          "status": "supported",
          "answer": "`opencode mcp list` shows each server's state (connected, pending, disabled, failed, needs authentication). In OpenCode, `/mcps` lets you view, connect, disconnect and authenticate servers; for a lasting change set `\"disabled\": true` or delete the entry. `opencode mcp debug` from 1.x no longer exists, and connect errors include the stdio server's last stderr output.",
          "reference": "https://opencode.ai/v2/docs/mcp-servers/#management",
          "evidence": [
            "mcp-opencode-opencode-ai-v2-docs-mcp-servers",
            "mcp-opencode-packages-core-src-mcp-index-ts",
            "mcp-opencode-packages-core-src-mcp-stdio-ts"
          ]
        },
        "serve": {
          "status": "unsupported",
          "answer": "No. OpenCode 2.x is only an MCP client and has no MCP server mode. Other tools integrate through its background server's HTTP API instead.",
          "reference": "https://opencode.ai/v2/docs/cli/#background-service",
          "evidence": ["mcp-opencode-opencode-ai-v2-docs-cli"]
        }
      },
      "observedVersion": "2.0.29",
      "sourceRevision": "042d0832f5f3a73eaa039a58a7d565776f6d4290"
    },
    {
      "harness": "pi",
      "variant": "current",
      "default": true,
      "protocolRevision": "2025-11-25",
      "clientMode": "built-in mcp extension in interactive TUI, print/JSON/RPC modes; opt-in for SDK sessions",
      "support": {
        "roots": "native",
        "sampling": "unsupported",
        "samplingTools": "unsupported",
        "elicitation": "unsupported",
        "elicitationForm": "unsupported",
        "elicitationUrl": "unsupported",
        "prompts": "unsupported",
        "resources": "native",
        "resourceTemplates": "native",
        "completion": "unsupported",
        "progress": "native",
        "cancellation": "native",
        "logging": "native",
        "subscriptions": "unsupported",
        "multiRoundTrip": "unsupported",
        "tasksLegacy": "unsupported"
      },
      "references": {
        "roots": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L359-L367",
        "sampling": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "samplingTools": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "elicitation": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "elicitationForm": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "elicitationUrl": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "prompts": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L384-L392",
        "resources": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#use-resources",
        "resourceTemplates": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#use-resources",
        "completion": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232",
        "progress": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/tools.ts#L337-L349",
        "cancellation": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L561-L575",
        "logging": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L367",
        "subscriptions": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L384-L392",
        "multiRoundTrip": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/protocol/types.ts#L4-L9",
        "tasksLegacy": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/mcp/src/client.ts#L215-L232"
      },
      "featureNotes": {
        "roots": "Advertises the roots capability and answers roots/list with the session directory; the list does not change during a session (no roots list_changed).",
        "sampling": "The client declares only roots; sampling/createMessage gets a method-not-found error.",
        "elicitation": "No elicitation capability or handler.",
        "prompts": "Pi never lists or gets server prompts; it uses only tools and resources.",
        "resources": "Exposed to the model as list_mcp_resources and read_mcp_resource tools; MCP Apps (ui://) resources are omitted.",
        "resourceTemplates": "Listed through the list_mcp_resource_templates tool.",
        "completion": "Pi never sends completion/complete.",
        "progress": "Progress is shown as tool updates and resets the request timeout.",
        "cancellation": "Aborting or timing out a call sends notifications/cancelled; incoming cancellations abort server-to-client requests.",
        "logging": "Server log notifications are appended to ~/.pi/agent/mcp.log (rotated at 5 MB); Pi does not send logging/setLevel.",
        "subscriptions": "Pi never sends resources/subscribe.",
        "multiRoundTrip": "Newest negotiated revision is 2025-11-25, which predates multi-round-trip requests.",
        "tasksLegacy": "No tasks capability is declared."
      },
      "evidence": [
        "mcp-pi-packages-coding-agent-src-extensions-mcp-runtime-ts",
        "mcp-pi-packages-mcp-src-client-ts",
        "mcp-pi-packages-coding-agent-docs-mcp-md",
        "mcp-pi-packages-coding-agent-src-extensions-mcp-tools-ts",
        "mcp-pi-packages-mcp-src-protocol-types-ts",
        "pi-docs-1-2-0",
        "mcp-pi-packages-coding-agent-src-extensions-mcp-cli-ts",
        "mcp-pi-packages-coding-agent-src-core-mcp-servers-ts",
        "mcp-pi-packages-coding-agent-src-extensions-mcp-config-ts",
        "instructions-pi-packages-coding-agent-docs-security-md",
        "mcp-pi-packages-coding-agent-src-extensions-mcp-resources-ts",
        "mcp-pi-packages-coding-agent-src-extensions-mcp-index-ts"
      ],
      "answers": {
        "add": {
          "status": "supported",
          "answer": "Run `pi mcp add <name> -- <command> [args...]` for a stdio server or `pi mcp add <name> --url <url>` for a remote one; options include `--env KEY=VALUE`, `--cwd`, `--header KEY=VALUE`, `--bearer-token-env-var NAME`, `--exposure` and `--description`. You can also edit `mcp.json` directly, which uses the common `mcpServers` format with `command`/`args`/`env`/`cwd` or `url`/`headers`/`oauth` per entry. Run `/reload` in a running session after changing config outside it.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/cli.md#mcp-commands",
          "evidence": [
            "pi-docs-1-2-0",
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-cli-ts"
          ],
          "notes": [
            "`pi mcp add` does not connect; run `pi mcp list` to check the server.",
            "Entries from Claude Desktop, Claude Code or Cursor can be copied as-is; VS Code, Codex and OpenCode entries need small conversions."
          ]
        },
        "transports": {
          "status": "partial",
          "answer": "Stdio (`command`) and Streamable HTTP (`url`, or `type` of `http`/`streamable-http`) work. The legacy SSE transport is rejected with an error telling you to use the server's Streamable HTTP URL, and WebSocket is not supported.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#configuration-rules",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-core-mcp-servers-ts"
          ]
        },
        "scopes": {
          "status": "supported",
          "answer": "User servers live in `~/.pi/agent/mcp.json` and project servers in `.pi/mcp.json`; a project entry with the same name replaces the user entry, and a project entry with only `enabled`, `exposure` or `toolExposure` just overrides those fields of the user server. The project file is read only after you grant project trust (the startup prompt, `/trust`, or `--approve`), and project files cannot use `auth.provider`. Extensions can also add session-only servers with `pi.registerMcpServer()`; file-configured servers win on name clashes.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#configure-servers",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-config-ts",
            "instructions-pi-packages-coding-agent-docs-security-md"
          ],
          "notes": ["There is no managed or enterprise-level MCP config file."]
        },
        "auth": {
          "status": "supported",
          "answer": "Remote servers that answer 401 trigger OAuth: sign in from `/mcp`, `/mcp login <server>` or `pi mcp login <server>`, and Pi does dynamic client registration (or `oauth.clientId`/`clientSecret`, or `oauth.clientRegistration: \"cimd\"`), stores tokens in `~/.pi/agent/mcp-auth.json` and refreshes them. For static credentials use `headers` (e.g. `\"Authorization\": \"Bearer ${TOKEN}\"`) or `env`; values expand `${VAR}` and can run a command with a value of the form `!command`. In the user file only, `\"auth\": { \"provider\": \"<name>\" }` sends a `/login` provider's token instead.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#authenticate-with-oauth",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-config-ts",
            "pi-docs-1-2-0"
          ],
          "notes": [
            "OAuth is only used for HTTP servers without an Authorization header.",
            "`pi mcp logout <server>` deletes stored credentials; `pi mcp remove` keeps them."
          ]
        },
        "approval": {
          "status": "partial",
          "answer": "Pi has no approval prompt for MCP calls (or any tool calls); they run immediately. To restrict tools, set `exposure`/`toolExposure` to `hidden` (patterns like `\"delete_*\": \"hidden\"`), set `enabled: false`, use `--exclude-tools 'mcp__server__*'` or `--tools` with `mcp__` patterns, or disable MCP with `--no-mcp`. Confirmation gates require an extension: MCP calls pass through extension `tool_call` handlers, and server annotations like `readOnlyHint`/`destructiveHint` are available to them.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#permissions",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "instructions-pi-packages-coding-agent-docs-security-md",
            "pi-docs-1-2-0"
          ]
        },
        "manyTools": {
          "status": "supported",
          "answer": "By default (`exposure: \"codemode\"`) MCP tools are not declared to the model at all; it reaches them from `codemode` JavaScript scripts that use `searchTools()`, `describeTool()` or `ALL_TOOLS`. `deferred` exposure makes tools loadable through `tool_search`, `direct` declares them like built-in tools, and `hidden` blocks them; `toolExposure` sets this per tool with `*` patterns. Servers with indirect tools are summarised in an `mcp_servers` system prompt section using their `description`.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#control-tool-exposure",
          "evidence": ["mcp-pi-packages-coding-agent-docs-mcp-md", "pi-docs-1-2-0"],
          "notes": [
            "Tool names are `mcp__<server>__<tool>`, truncated with a hash suffix past 64 characters.",
            "No fixed limit on the number of servers or tools is documented."
          ]
        },
        "output": {
          "status": "supported",
          "answer": "Text results over 20 KB reach the model with the middle cut out around a truncation marker, and the full text is saved to a temp file named in the result; codemode scripts get the untruncated result. Each request has a per-server `timeout` in seconds (default 60) that progress notifications reset, and a timed-out call is cancelled and fails. Servers connect in the background; the first prompt waits up to 10 seconds only for servers with `direct` tools.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#control-tool-exposure",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-tools-ts"
          ],
          "notes": [
            "The connection handshake uses the same per-server timeout; HTTP connects retry twice on network errors and 408/429/5xx."
          ]
        },
        "resources": {
          "status": "partial",
          "answer": "Resources are available to the model, not as @-mentions: when a server offers them, Pi adds `list_mcp_resources`, `list_mcp_resource_templates` and `read_mcp_resource` tools. Text comes back as text, images as images, and other binary content is saved to a temp file whose path the model receives.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#use-resources",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-resources-ts"
          ],
          "notes": [
            "MCP Apps resources (`ui://` or `text/html;profile=mcp-app`) are omitted.",
            "Resource subscriptions are not used."
          ]
        },
        "prompts": {
          "status": "unsupported",
          "answer": "No. Pi does not list or use MCP server prompts, so they do not appear as slash commands or anywhere else.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L384-L392",
          "evidence": [
            "mcp-pi-packages-coding-agent-src-extensions-mcp-runtime-ts",
            "mcp-pi-packages-coding-agent-docs-mcp-md"
          ]
        },
        "serverAsks": {
          "status": "partial",
          "answer": "Servers can see your roots: Pi reports the session directory as the single root. Servers cannot ask you for input (no elicitation) and cannot use the model (no sampling); Pi declares neither capability.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/src/extensions/mcp/runtime.ts#L359-L367",
          "evidence": [
            "mcp-pi-packages-coding-agent-src-extensions-mcp-runtime-ts",
            "mcp-pi-packages-mcp-src-client-ts",
            "mcp-pi-packages-coding-agent-docs-mcp-md"
          ]
        },
        "manage": {
          "status": "supported",
          "answer": "Use `/mcp` in the TUI to see each server's state, tool count, exposure and source, inspect tools and errors, reconnect, sign in or out, change exposure, and enable or disable a server (globally or just for this project). From a shell, `pi mcp list [--json]` connects to every enabled server and prints state, tools and errors; outside the TUI `/mcp` prints status and `/mcp login|logout|reconnect <server>` act directly. Failed stdio servers show their stderr tail in `/mcp`, and server log messages go to `~/.pi/agent/mcp.log`.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/mcp.md#inspect-or-change-a-server",
          "evidence": [
            "mcp-pi-packages-coding-agent-docs-mcp-md",
            "pi-docs-1-2-0",
            "mcp-pi-packages-coding-agent-src-extensions-mcp-index-ts"
          ],
          "notes": [
            "`--no-mcp` turns MCP off for one run; `\"extensions\": [\"-builtin:mcp\"]` or `pi config` turns it off persistently.",
            "Installing an extension that registers `/mcp` (such as pi-mcp-adapter) replaces the built-in support."
          ]
        },
        "serve": {
          "status": "unsupported",
          "answer": "No. Pi cannot run as an MCP server; for programmatic use it offers its own JSON event stream (`--mode json`), RPC protocol (`--mode rpc`) and SDK instead.",
          "reference": "https://github.com/earendil-works/pi/blob/06a466935536f8c9bcacb2d5efc0fc021be1bdff/packages/coding-agent/docs/cli.md#invocation-and-output",
          "evidence": ["pi-docs-1-2-0"]
        }
      },
      "observedVersion": "1.2.0",
      "sourceRevision": "06a466935536f8c9bcacb2d5efc0fc021be1bdff"
    }
  ]
}
