MCP clients
capsol speaks MCP over Streamable HTTP. The dashboard hands you a stable URL per capsule. OAuth discovery + Dynamic Client Registration is the default remote-client path; manually copied bearer credentials are disabled by default.
Host matrix
Section titled “Host matrix”| Host | Config path | Root key | HTTP field | Notes |
|---|---|---|---|---|
| Claude Code | .mcp.json | mcpServers | url | type: "http" |
| Claude Desktop | UI: Settings → Connectors | — | — | Pro / Team only |
| Cursor | .cursor/mcp.json | mcpServers | url | Enable MCP toggle in Settings |
| VS Code Copilot | .vscode/mcp.json | servers | url | Not mcpServers — #1 copy bug |
| Codex CLI | ~/.codex/config.toml | mcp_servers | url | TOML, not JSON |
| Windsurf | ~/.codeium/windsurf/mcp_config.json | mcpServers | serverUrl | Not url |
| Zed | ~/.config/zed/settings.json | context_servers | url | Requires Zed 0.150+ |
| ChatGPT | UI: Settings → Connectors | — | — | Paid tier + Developer Mode |
| claude.ai (web) | UI: Settings → Connectors | — | — | Pro / Team / Enterprise |
capsol speaks Streamable HTTP only. Legacy SSE is not supported.
The universal URL
Section titled “The universal URL”Since 0.17 the bare /mcp endpoint is principal-scoped: one config line, ever.
https://registry.example.com/mcpThe credential — not the URL — decides what the connection can reach. A universal connection exposes the standard tools plus a tiny directory tool:
capsol_capsules(action="list")— every capsule in your grant set with id, name, role, scopes, and item count. Capsules granted to you later appear automatically; the client config never changes.capsol_capsules(action="mount", capsule="name")— set the session default socapsol_read/write/signalneed nocapsuleargument.- Or pass
capsule="<id|name|uri>"per call. Resolution order: explicit param → mounted default → your only capsule → acapsule_requirederror listing what you can access.
Every call is authorized against the grant for the resolved target capsule only — the URL is never the security boundary. During OAuth authorization the operator can select several capsules at once; the issued credential’s grant set spans them all and the token response points at /mcp.
/mcp/:capsuleId remains the documented least-privilege option for single-capsule connections and keeps working forever.
Copy blocks
Section titled “Copy blocks”Use these as starting points. Replace <capsule-id> — or use the universal /mcp URL above and skip per-capsule config entirely. Paste only the MCP URL; the client should discover /.well-known/oauth-protected-resource/mcp/<capsule-id>, register at /oauth/register, and complete PKCE.
{ "name": "capsol", "transport": "streamable-http", "url": "https://capsol.example.com/mcp/<capsule-id>", "auth": { "type": "oauth", "resource": "https://capsol.example.com/mcp/<capsule-id>", "protected_resource": "https://capsol.example.com/.well-known/oauth-protected-resource/mcp/<capsule-id>", "registration_endpoint": "https://capsol.example.com/oauth/register" }}{ "mcpServers": { "capsol": { "type": "http", "url": "https://capsol.example.com/mcp/<capsule-id>" } }}[mcp_servers.capsol]url = "https://capsol.example.com/mcp/<capsule-id>"{ "name": "capsol", "transport": "streamable-http", "url": "https://capsol.example.com/mcp/<capsule-id>"}Use the connector UI with:MCP URL: https://capsol.example.com/mcp/<capsule-id>Auth: OAuth discoveryclaude mcp add --transport http capsol \ https://capsol.example.com/mcp/<capsule-id>ChatGPT, Cursor builds with remote OAuth, and browser-hosted clients should use OAuth discovery from the capsule-specific protected-resource metadata. The first authorization page is a request-access form for unauthenticated users and agents; operators approve or deny the resulting OAuth grant in the dashboard. After approval, retry the MCP connection so the client receives the OAuth code. Autonomous agents that cannot start with OAuth should use agent enrollment and wait for grant approval.
Configure Settings → Hosted URLs before connecting remote clients through ngrok or a reverse proxy. Configure Settings → OAuth clients to restrict DCR native schemes, restrict web redirect hosts, require DCR client secrets, disable DCR, or enable/disable CIMD.
Protocol readiness
Section titled “Protocol readiness”capsol is built for MCP debugger/inspector probes:
- Unauthenticated MCP returns
401withWWW-Authenticate, protected-resource metadata, and the default collaborator scopecapsule:read capsule:append capsule:write signal:send. - OAuth metadata is available at both
/.well-known/oauth-authorization-serverand/.well-known/openid-configuration. - Dynamic Client Registration is exposed at
/oauth/register. - PKCE is
S256only;plainis not advertised or accepted. - MCP POSTs must use
Content-Type: application/jsonandAccept: application/json, text/event-stream. - Unexpected non-loopback
Originheaders return403. - Invalid JSON-RPC, response-only POSTs, and unknown client notifications return HTTP 4xx rather than being accepted as background notifications.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Fix |
|---|---|
Client only shows capsol_read | Reconnect so the client sees the current WWW-Authenticate scope: capsule:read capsule:append capsule:write signal:send. Existing approved read-only grants stay read-only until the operator approves broader scopes. |
| Redirect URI mismatch | For DCR clients, remove and re-add the MCP server so the client registers its actual redirect URI. Cursor native redirects such as cursor://anysphere.cursor-mcp/oauth/callback are supported. CIMD loopback redirects such as Claude Code’s http://localhost:<port>/callback are accepted when the metadata document registers http://localhost/callback or http://127.0.0.1/callback. |
CSP form-action error under ngrok/proxy | Set Settings → Hosted URLs → Public URL to the exact public HTTPS origin, then reconnect the MCP client. The authorization page omits a restrictive form-action so proxied form posts can return to the same document. |
| Missing OIDC discovery | capsol serves /.well-known/openid-configuration with the OAuth authorization-server metadata for clients and debuggers that probe it first. |
| CIMD unavailable | CIMD requires an HTTPS client_id metadata document, exact client_id match, valid redirect URIs, no blocked private-network redirects, and a document under the size limit. Use DCR fallback if the client cannot host CIMD metadata. |
| MCP origin validation fails | Browser clients must call from the registry origin or loopback during local debugging. Unexpected non-loopback Origin headers return 403. |
Claude Code
Section titled “Claude Code”Anthropic’s CLI coding agent. Reads .mcp.json at project root.
{ "mcpServers": { "capsol": { "type": "http", "url": "https://capsol.example.com/mcp/<capsule-id>" } }}One-command add: claude mcp add capsol --transport http --url <URL>. Verify inside the session: /mcp — capsol with a green dot.
Claude Code uses a CIMD client id and usually chooses an ephemeral loopback callback port. capsol treats a registered loopback redirect without a port as matching the runtime callback port, so http://localhost/callback from the metadata document matches http://localhost:62502/callback.
Gotchas: root key is mcpServers (camelCase, plural). .mcp.json is per-project. Node 22+. Docs: https://docs.claude.com/en/docs/claude-code/mcp ↗
Claude Desktop
Section titled “Claude Desktop”The macOS / Windows app. HTTP via Custom Connectors:
- Settings → Connectors → Add Custom Connector.
- Name:
capsol, Remote MCP URL:https://capsol.example.com/mcp/<capsule-id>. - Save. Enable in a new chat.
Gotchas: Requires Pro / Team. HTTPS only. Per-chat enable by default — pin for stickiness. Docs: https://support.anthropic.com/en/articles/10161696-using-custom-integrations-connectors ↗
Cursor
Section titled “Cursor”Config: .cursor/mcp.json at repo root, or ~/.cursor/mcp.json user-global.
{ "mcpServers": { "capsol": { "url": "https://capsol.example.com/mcp/<capsule-id>" } }}Verify: Chat pane → bottom-right tools icon → “MCP servers” → green dot on capsol. Docs: https://docs.cursor.com/en/context/mcp ↗
VS Code Copilot
Section titled “VS Code Copilot”VS Code reads MCP servers from .vscode/mcp.json. Schema differs from Claude Code and Cursor.
{ "servers": { "capsol": { "type": "http", "url": "https://capsol.example.com/mcp/<capsule-id>" } }}Gotchas: type must be explicit. Requires VS Code 1.93+ + Copilot Chat + agent mode (Settings → Copilot → Agent mode). Verify inside Copilot Chat agent mode: /mcp. Docs: https://code.visualstudio.com/docs/copilot/chat/mcp-servers ↗
Codex CLI
Section titled “Codex CLI”OpenAI’s Codex CLI. Config is TOML at ~/.codex/config.toml.
[mcp_servers.capsol]url = "https://capsol.example.com/mcp/<capsule-id>"Gotchas: path is ~/.codex/config.toml — not ~/.config/codex/, not ~/.codex.toml. No daemon to restart. Verify: codex mcp list. Docs: https://github.com/openai/codex ↗
Windsurf
Section titled “Windsurf”Codeium’s agent IDE. Config at ~/.codeium/windsurf/mcp_config.json (user-level only).
{ "mcpServers": { "capsol": { "serverUrl": "https://capsol.example.com/mcp/<capsule-id>" } }}Gotchas: no project-level path. No hot-reload — restart Windsurf after editing. Windows base: %USERPROFILE%\.codeium\windsurf\. Verify: Cascade pane → tools icon → capsol listed. Docs: https://docs.codeium.com/windsurf/mcp ↗
Zed reads context servers from its settings JSON.
{ "context_servers": { "capsol": { "source": "custom", "command": null, "url": "https://capsol.example.com/mcp/<capsule-id>" } }}Requires Zed 0.150+. Verify: assistant panel → context servers list. Docs: https://zed.dev/docs/assistant/context-servers ↗
ChatGPT
Section titled “ChatGPT”Connectors / Developer Mode. Requires Pro, Plus, Team, Enterprise, or Edu. Free tier cannot mount MCP servers.
- Settings → Data Controls → Developer Mode → on.
- Settings → Connectors → Create.
- Name:
capsol, MCP URL:https://capsol.example.com/mcp/<capsule-id>. - Save. Connector appears in the composer’s ”+” menu.
Gotchas: MCP URL must be HTTPS and publicly reachable — ChatGPT’s cloud does the fetch, not the browser. If rate limits are explicitly enabled, mint a dedicated connection for ChatGPT. ChatGPT exposes tools but not prompts — skills:// entries won’t appear as prompt macros. Docs: https://help.openai.com/en/articles/11487775-connectors-in-chatgpt ↗
claude.ai (web)
Section titled “claude.ai (web)”Custom Connectors — like Claude Desktop’s HTTP path, but in browser settings. Requires Claude Pro / Team / Enterprise.
- Settings → Profile → Connectors → Add Custom Connector.
- Name:
capsol, Remote MCP URL:https://capsol.example.com/mcp/<capsule-id>. - Save. New chat → tools icon → enable capsol.
Gotchas: HTTPS only. Enabling is per-conversation by default — pin for stickiness. claude.ai fans out parallel tool calls; if rate limits are enabled, mint a dedicated connection. Docs: https://support.anthropic.com/en/articles/10161696-using-custom-integrations-connectors ↗
Common pitfalls
Section titled “Common pitfalls”| Symptom | Cause |
|---|---|
| ”No MCP servers found.” | Wrong root key (mcpServers vs servers vs mcp_servers). |
| Server listed but all tool calls 401. | OAuth grant failed or the connection was revoked. Reconnect the client. |
| MCP debugger reports JSON-RPC 4xx. | The probe sent a response-only payload, unknown notification, or missing MCP Streamable HTTP headers. |
| MCP debugger reports invalid Origin. | Add the real hosted URL in Settings and avoid testing from non-loopback browser origins. |
| Tools listed, calls return “URI not allowed.” | Connection has scheme/URI scope — check the Access tab. |
curl /health works, client can’t connect. | Host is using HTTPS by policy. Put capsol behind TLS. |
| Dashboard URL works but MCP URL doesn’t. | Client only sees Streamable HTTP — confirm type: "http" is set. |
For custom agents (LangChain, Mastra, Vercel AI, Pydantic, etc.), see custom agents.