For AI agents: a documentation index is available at https://www.plungeai.com/docs/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://www.plungeai.com/docs/agents.md. One ozk_ key opens every plane, models included.

Documentation Index: fetch the complete documentation index at /llms.txt. Use this file to discover all available pages before exploring further.

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:

FileEcosystemShape
.mcp.jsonClaude Code (project)mcpServers { … }
~/.claude.jsonClaude Code (user)mcpServers { … }
.cursor/mcp.jsonCursor (project)mcpServers { … }
opencode.json (mcp {})OpenCodemcp { … }, local and remote
<plugin>/.mcp.jsonan installed pluginmcpServers { … }
oceancode.json (mcp {})OceanCodemcp { … } — 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_OK

or 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/list and resources/read are 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 question seam 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

Planned: TI-34

The docs assistant is not available yet. You can hand these docs to your own assistant instead.