Harness Notes

JSON

MCP

6 records ยท Updated 2026-10-15

How to connect MCP servers to each harness and what their tools can do once connected. The protocol table at the end shows which parts of the MCP specification each client supports.

Setting up a server

QuestionCodex CLIchecked at 0.162.1Claude Codechecked at 2.1.299Cursor Agentchecked at 2026.10.12-d47ca18OpenCodechecked at 2.0.28pichecked at 1.2.0
Add a server

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.

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>.

Source

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.

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.

Source

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.

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.

Source

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).

Source

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.

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.

Source
Transports

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.

Source

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.

"type": "sdk" in-process servers can only be registered by an SDK host application such as the Agent SDK or the desktop app.

Source

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.

Source

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.

Source

Partly

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.

Source
Where configs live, and project trust

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.

Trusting the project is the only gate: Codex has no separate per-server approval prompt for project-defined servers.

Source

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.

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).

Source

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.

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.

Source

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>.

Source

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.

There is no managed or enterprise-level MCP config file.

Source
Sign in or pass credentials

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.

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.

Source

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.

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.

Source

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.

Over SSH, the CLI prints port-forwarding instructions for the OAuth callback.

Interpolation works in command, args, env, url, headers and auth.

Source

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.

Source

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.

OAuth is only used for HTTP servers without an Authorization header.

pi mcp logout <server> deletes stored credentials; pi mcp remove keeps them.

Source

Using its tools

QuestionCodex CLIchecked at 0.162.1Claude Codechecked at 2.1.299Cursor Agentchecked at 2026.10.12-d47ca18OpenCodechecked at 2.0.28pichecked at 1.2.0
Approve, allow or block tools

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.

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.

Source

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.

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>.

Source

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.

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.

Source

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.

Source

Partly

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.

Source
Many servers or tools

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.

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.

Source

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.

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.

Source

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.

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.

Source

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.

Denying the execute permission turns Code Mode off.

Source

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.

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.

Source
Output size and timeouts

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.

When a tool call times out, the model gets an error result instead of tool output.

Source

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).

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.

Source

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.

None of these limits can be configured in mcp.json.

Image content is passed to the model as an image.

Source

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.

Source

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.

The connection handshake uses the same per-server timeout; HTTP connects retry twice on network errors and 408/429/5xx.

Source
Resources

Partly

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.

Source

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.

MCP Apps UI resources (ui:// or text/html;profile=mcp-app) are hidden from @ suggestions and the list tool.

Source

Partly

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.

The editor documents resources as "read and referenced"; the CLI exposes them only to the agent.

Source

Partly

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.

Source

Partly

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.

MCP Apps resources (ui:// or text/html;profile=mcp-app) are omitted.

Resource subscriptions are not used.

Source
Prompts

Not supported

No. Codex never lists or fetches MCP server prompts, so they don't show up as slash commands or anywhere else in the UI.

Source

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.

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.

Source

Partly

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.

Source

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.

Source

Not supported

No. Pi does not list or use MCP server prompts, so they do not appear as slash commands or anywhere else.

Source
When a server asks you or the model

Partly

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.

Source

Partly

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.

If a server stops connecting after the v2.1.287 URL-elicitation change, add "bareElicitationCapability": true to its config entry.

Source

Not supported

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.

Source

Partly

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.

Source

Partly

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.

Source

Running servers

QuestionCodex CLIchecked at 0.162.1Claude Codechecked at 2.1.299Cursor Agentchecked at 2026.10.12-d47ca18OpenCodechecked at 2.0.28pichecked at 1.2.0
Status, enable, reconnect, debug

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.

codex doctor includes an MCP configuration check.

Setting log_dir writes codex-tui.log, which includes server log messages and connection errors.

Source

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.

Remote servers reconnect automatically, with 5 attempts and exponential backoff; stdio servers do not.

Source

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.

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.

Source

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.

Source

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.

--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.

Source
Run the harness as an MCP server

Not supported

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.

Source

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.

Since v2.1.271, a running tool call sends a progress update every 30 seconds.

Source

Not supported

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.

Source

Not supported

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.

Source

Not supported

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.

Source

Protocol features

FeatureCodex CLIprotocol 2025-06-18Claude Codeprotocol 2026-07-28, with fallback to older serversCursor Agentprotocol 2025-11-25OpenCodeprotocol 2025-11-25; 2026-07-28 opt-in per serverpiprotocol 2025-11-25
Roots

Let a server discover the client-approved filesystem roots; this is not the server process working directory.

deprecated in the current spec

Not supported

The initialize request advertises only elicitation (plus OpenAI extensions); there is no roots capability or roots/list handler.

Source

Supported

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+).

Source

Not supported

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.

Source

Supported

Answers roots/list with the project directory; only on legacy-era connections.

Source

Supported

Advertises the roots capability and answers roots/list with the session directory; the list does not change during a session (no roots list_changed).

Source
Sampling

Let a server request an LLM interaction through the host, with user review and model preferences.

deprecated in the current spec

Not supported

No sampling capability is advertised and sampling/createMessage is not handled.

Source

Not documented

The MCP docs do not describe sampling/createMessage support.

Not supported

Sampling is not in Cursor's support table, and the CLI does not declare the sampling capability.

Source

Not supported

No sampling capability is declared.

Source

Not supported

The client declares only roots; sampling/createMessage gets a method-not-found error.

Source
Sampling with tools

Let the sampling loop invoke tools recursively; do not confuse this with ordinary server tool calls.

deprecated in the current spec

Not supported

Source

Not documented

Not supported

There is no sampling, so there is no sampling with tools either.

Source

Not supported

Source

Not supported

Source
Elicitation (generic)

Record clients that document elicitation without establishing which interaction modes they implement.

Supported

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.

Source

Supported

Interactive dialog; the Elicitation and ElicitationResult hooks can answer or override it.

Source

Partly

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.

Source

Supported

Requests appear as forms in OpenCode's UI.

Source

Not supported

No elicitation capability or handler.

Source
Form elicitation

Let a server request structured user input with accept, decline, and cancel outcomes.

Supported

Source

Supported

Source

Partly

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.

Source

Supported

Schema fields become form fields; accept or cancel is returned.

Source

Not supported

Source
URL elicitation

Let a server send the user through an external interaction and safely resume afterward.

Supported

The TUI shows a link view for validated external URLs.

Source

Supported

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.

Source

Not supported

The CLI does not advertise URL mode and declines URL-mode requests.

Source

Supported

Shown as an external-link form; legacy notifications/elicitation/complete settles it.

Source

Not supported

Source
Prompts

Expose reusable, argument-aware server prompts through the client UI.

Not supported

The client never calls prompts/list or prompts/get; server prompts are not exposed as commands.

Source

Supported

Listed as /server:prompt (MCP) and runnable as /mcp__server__prompt with whitespace-split arguments.

Source

Partly

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.

Source

Supported

Prompts become /<server>:<prompt> commands.

Source

Not supported

Pi never lists or gets server prompts; it uses only tools and resources.

Source
Resources

List and read server-provided context independently from tool execution.

Supported

Model-driven through built-in list_mcp_resources and read_mcp_resource tools; no @-mention picker.

Source

Supported

@server:uri mentions plus built-in list/read resource tools for Claude.

Source

Supported

In the CLI the agent lists and reads resources itself (List MCP Resources / Fetch MCP Resource tool calls). You cannot @-mention them.

Source

Supported

Available to the agent through list_mcp_resources and read_mcp_resource.

Source

Supported

Exposed to the model as list_mcp_resources and read_mcp_resource tools; MCP Apps (ui://) resources are omitted.

Source
Resource templates

Discover and fill parameterized resource URIs.

Supported

The model lists templates with list_mcp_resource_templates and reads a filled URI with read_mcp_resource.

Source

Partly

Claude Code fetches resources/templates/list for @-mention autocomplete; the docs don't describe how template parameters are filled.

Source

Not supported

Only concrete resources from resources/list are offered. Templates are never listed.

Source

Supported

Templates are listed alongside resources; the agent expands uriTemplate before reading.

Source

Supported

Listed through the list_mcp_resource_templates tool.

Source
Argument completion

Complete prompt arguments and resource-template parameters without an LLM call.

Not supported

Source

Not documented

No documented completion/complete support for prompt or template arguments.

Not supported

The CLI never asks servers for argument completions.

Source

Not supported

The connection exposes no completion call.

Source

Not supported

Pi never sends completion/complete.

Source
Progress

Correlate monotonic progress with a request; UI display and timeout extension are separate behaviors.

Partly

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.

Source

Supported

Progress is shown on the tool call and its background task, and resets the idle timeout but not the per-server wall-clock timeout.

Source

Not supported

In CLI 2026.10.12, tool calls carry no progress token, so server progress is neither shown nor used to extend timeouts.

Source

Partly

Progress keeps long calls alive; it is not displayed.

Source

Supported

Progress is shown as tool updates and resets the request timeout.

Source
Cancellation

Cooperatively cancel in-flight protocol requests and propagate intent to the handler.

Partly

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.

Source

Partly

Stopping a backgrounded MCP call from /tasks cancels it; the docs warn the server may still finish the work.

Source

Not supported

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.

Source

Supported

Requests carry an abort signal that cancels the in-flight request.

Source

Supported

Aborting or timing out a call sends notifications/cancelled; incoming cancellations abort server-to-client requests.

Source
Protocol logging

Deliver correlated server logs through MCP rather than relying on process stderr.

deprecated in the current spec

Partly

notifications/message is mapped to Codex's own log levels; logging/setLevel is never sent and nothing is shown in the UI.

Source

Not documented

Docs mention a per-server debug log but not MCP logging/setLevel or notifications/message.

Not supported

The CLI neither sets a log level nor handles notifications/message. Stdio stderr is only surfaced in startup errors.

Source

Not supported

No notifications/message handler; stdio stderr goes to the debug log instead.

Source

Supported

Server log notifications are appended to ~/.pi/agent/mcp.log (rotated at 5 MB); Pi does not send logging/setLevel.

Source
Subscriptions

Receive correlated updates over a long-lived request.

Not supported

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.

Source

Partly

On the v2 runtime, servers on revision 2026-07-28 deliver list_changed over a held-open stream; resource content subscriptions aren't documented.

Source

Not supported

The CLI does not subscribe to resources. It does refresh tools when a server sends notifications/tools/list_changed.

Source

Partly

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.

Source

Not supported

Pi never sends resources/subscribe.

Source
Multi-round-trip requests

Pause a request for sampling, elicitation, or roots input and retry it with opaque request state.

Partly

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.

Source

Not documented

Not supported

The client speaks protocol revisions up to 2025-11-25, which predate multi-round-trip requests.

Source

Partly

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.

Source

Not supported

Newest negotiated revision is 2025-11-25, which predates multi-round-trip requests.

Source
Tasks

Durable polling, status, result, and cancellation state from the 2025-11-25 experimental protocol era.

earlier experimental spec

Not supported

No tasks capability is advertised and no tasks/* requests are made.

Source

Not documented

The 'MCP task' in /tasks is Claude Code's own backgrounding of slow tool calls, not the protocol's Tasks utility.

Not supported

The client declares no tasks capability. Tools that require task-based execution fail.

Source

Not supported

No tasks capability is declared.

Source

Not supported

No tasks capability is declared.

Source

Notes and sources

Codex CLI
Claude Code
Cursor Agent
OpenCode
pi