OceanCode
MCP servers
An MCP server is an external process (or HTTP endpoint) that contributes tools, resources and
prompts to a run. oceancode reads the same server-config files the other tools use, so a server
you configured for Claude Code, Cursor or OpenCode is picked up as-is.
Where servers are configured
Servers are read from several files at once and merged by precedence:
| File | Ecosystem | Shape |
|---|---|---|
.mcp.json | Claude Code (project) | mcpServers { … } |
~/.claude.json | Claude Code (user) | mcpServers { … } |
.cursor/mcp.json | Cursor (project) | mcpServers { … } |
opencode.json (mcp {}) | OpenCode | mcp { … }, local and remote |
<plugin>/.mcp.json | an installed plugin | mcpServers { … } |
oceancode.json (mcp {}) | OceanCode | mcp { … } — declared servers win over discovered ones of the same name |
Precedence, highest first: local > project > user > plugin. A server defined closer to you
overrides a same-named server from a wider scope. Every server from every file is folded into
the one manager at boot, so /mcp, GET /mcp and oceancode mcp list all show the same set —
but a name declared at two tiers runs once: the copy that lost its name (qualified
<tier>:<name>, say user:cloudflare-dev for a ~/.claude.json copy of the project's
.mcp.json server) is folded held disabled — listed, never spawned, its tools never offered a
second time under a user_cloudflare-dev_* prefix — and mcp list reads shadowed on it. Only
when the winning copy cannot run (held untrusted or disabled) does the next copy run in its place.
Before 2026-10-13 both copies were started.
Held until trusted
A server that arrived with a checkout (the project's .mcp.json) or with a plugin can run code
on your machine, so it is listed but held — status untrusted — until you trust it. Nothing is
dialed or spawned for a held server. Three ways to release one, all persisted in
~/.oceancode/trust.json under the project's absolute path:
oceancode trust repo on # trust the repo tier: its .mcp.json servers and its hooks
oceancode trust mcp <name> on # trust one server (beats the repo flag); `off` holds it again; `clear` removes the override
oceancode trust show # repo=<bool>, one `mcp <name>=<bool>` per override, one `disabled <name>` per held-disabled server, then TRUST_OKor trust it from the pager's /mcps tab. Trust pins what was approved: the first time a trusted
repo or plugin server is seen (or when you trust it), its command (stdio) or URL is recorded as a
hash in trust.json (mcp_hashes). If the checkout or plugin later changes that command or URL,
the server is held untrusted again until you re-approve it with oceancode trust mcp <name> on or
t in /mcps. Environment and headers are not pinned. Once it runs, each of its calls still passes
the mcp permission rules and asks by default
(12 · Permissions).
A server Claude Code has switched off for this
project (disabledMcpServers / disabledMcpjsonServers in ~/.claude.json, seeded by
oceancode plugin import --from claude-code) is held disabled at every tier and reports
disabled. User-tier servers (~/.claude.json) are trusted by default.
Enabled and trusted are independent: oceancode mcp disable <name> (or the pager's /mcps tab) switches a
server off — disconnecting it and recording the hold in trust.json — without changing its trust,
and enable switches it back on; a server that is enabled but still untrusted stays held and
reports untrusted, and connect refuses to dial it until it is trusted. The engine reads a
trust.json change made from the CLI at its next boot; the pager and the HTTP routes apply it
live.
oceancode mcp enable|disable is the MCP arm of the one enable interface skills, plugins and MCP
servers share (skill enable|disable, plugin enable|disable, and enable-all/disable-all on
each) — see Enabling and disabling skills. MCP
keeps its own disabled_mcp hold model rather than the skills' four-tier fold; the verbs are the
same shape so there is one thing to learn. An explicit enable is remembered per project as
enabled_mcp in ~/.oceancode/trust.json and beats a config entry's enabled: false, so a server
your project config ships off can be switched on from the picker or the CLI and stays on.
Any ${VAR} or ${VAR:-default} in a server's command, args, env or headers is expanded from
your environment when the server starts; an unresolved ${VAR} is left literal rather than
blanked, so a misconfigured variable is visible instead of silently empty.
Like hooks, MCP servers execute on your behalf, so they run only from a trusted source (see 09 · Capabilities and plugins).
Resources, prompts and elicitation
An MCP server offers more than tools:
- Resources — the server's
resources/listandresources/readare surfaced so a server can hand documents into a run. - Prompts — each server prompt appears as a slash command named
/mcp__<server>__<prompt>. - Elicitation — a server that asks the user a question mid-call is routed to the same
questionseam the rest of the app uses, so the prompt shows up in your UI and the answer goes back to the server.
Meta-dispatch for large tool sets
When many servers are connected, the flat tool catalog gets unwieldy for the model — and some
providers reject a tools array longer than 128. Past 128 connected MCP tools the engine always
replaces the flat catalog with two meta-tools — search_tool (find a tool by keyword) and
use_tool (invoke one by id). Setting OC_MCP_META_TOOLS=1 does the same from 64 tools up.
See 02 · Configuration.
Managing servers — oceancode mcp
# A stdio server (a local command):
oceancode mcp add <name> --command <cmd> [--arg <a>]... [--env K=V]...
# A remote server (an HTTP endpoint):
oceancode mcp add <name> --url <url> [--header K=V]...
oceancode mcp list # name stdio|remote tier trusted|untrusted enabled|disabled|shadowed source
oceancode mcp enable <name> # / disable <name> — switch any server off or on (config-declared or discovered; held disabled in ~/.oceancode/trust.json, honoured at boot)
oceancode mcp remove <name>
oceancode mcp login <name> # / logout <name> — OAuth for a server that needs it
oceancode mcp doctor # probe every server and report reachable / failed (a shadowed copy is not dialed; it reads shadowed)list walks every config file above for the current directory (--dir <d>, --home <h> to
point elsewhere) and shows, per server, its tier, whether it may run and whether it is enabled.
add writes a Claude-Code-shaped .mcp.json, so the server is immediately visible to any tool
that reads that file. Pass exactly one of --command (stdio) or --url (remote). --root <dir>
and --home <dir> override where the config and home are read.
doctor gives each server a short connect budget and reports it reachable or failed quickly,
so one unreachable server does not hang the check.
In Ocean pager, /mcps opens the MCP tab of the capabilities picker (add, enable/disable and
trust go through the engine); see 19 · Ocean pager.
A server whose handshake is still in flight reads connecting (the status list is
connected / connecting / needs-auth / failed / disabled / untrusted); a status read
gives the startup pass at most two seconds and then answers with the live rows (the handshake
itself may take up to 30 s, the timeout default). Disconnecting, disabling or untrusting a
server is bounded to about two seconds even when the server process left a child holding its
output pipe open.
A prompt's first model request waits up to OC_MCP_WAIT_SECONDS (default 5; 0 never waits;
sub-agents never wait) for the servers configured at boot to finish connecting, so their tools are
already in that request. The tool list is then fixed for the rest of the prompt: a server that
connects, or lists new tools (tools/list_changed), while a prompt runs reaches the model on the
next prompt, because a changed tool list at the front of the request would make the provider
re-write its whole prompt cache. Toggling a server, connecting or disconnecting it by hand, trust or
any capability still applies on the very next step.
Over HTTP a client reads GET /mcp (each entry carries trusted, enabled, provenance and
kind beside status), GET /mcp/{name}/tools, GET /mcp/{name}/prompts,
GET /mcp/{name}/resources, and posts POST /mcp/{name}/trust {"on"},
POST /mcp/{name}/enable {"on"}, POST /mcp/{name}/connect|disconnect, POST /mcp/{name}/auth
and DELETE /mcp/{name}/auth.
See also
- 09 · Capabilities and plugins — discovery, tiers, and the trust gate.
- 10 · Hooks — the other capability that runs your code.
- 02 · Configuration —
OC_MCP_META_TOOLSand themcpconfig key. - 07 · Headless and server —
oceancode trustandoceancode mcp list.