How-To · 15 min

Connect MCP servers

MCP runs in both directions here. Inward: connect any MCP server and its tools join Kaptain's catalog like built-ins. Outward: Kaptain itself is an MCP server named kaptain-engine, so your terminal CLIs get Kaptain's whole toolbelt.

Inward: add a server to Kaptain

Kaptain speaks all three MCP transports: stdio (a command it spawns), http (streamable-HTTP URL), and sse. You fill in a command or a URL — the transport follows from which one you filled. Install whatever the server itself needs first (Node/npx, Docker, a binary…) — Kaptain checks the launcher exists and refuses in plain language if it doesn't, before saving anything.

In the UI (Krew tab)

  1. Open the Krew view ▸ sidebar category MCP Servers.
  2. Add manually — name (lowercase id), command + arguments or remote URL, and one KEY=VALUE per line (env vars for a local server, headers for a remote one).
  3. Or + Add from JSON — paste the {"mcpServers": …} block straight from any vendor README; the format is compatible on purpose.
  4. Add & connect. The row shows live status, tool count, and errors on failure; per-row actions cover Enable/Disable, Reconnect, Remove, and OAuth sign-in where the server uses it.

Connected tools join the catalog under Native Tools, each with its own on/off switch.

The dialog, field by field — one dialog serves both kinds; you never pick a transport, it follows from what you fill in:

FieldWhat to put in it
Namea lowercase id, e.g. tavily — its tools appear under this name
Local commandthe program Kaptain runs (npx, uvx, a binary path); empty for a remote server
Argumentsspace-separated, e.g. -y some-mcp-server
Remote URLa hosted endpoint, e.g. https://example.com/mcp; empty for a local server
Env / headersone KEY=VALUE per line — env vars for a local server, request headers for a remote one; an API key goes here either way

Will models call these tools by themselves? Yes — once a server is connected, enabled, and discovered, its tools join the tool set of every tool-capable run; if the active model picks one, Kaptain calls the server. You can also ask outright: "Use the GitHub MCP tool to list open pull requests."

Scoping an agent: a kapsule can be restricted to a subset of tools via the tools list in its kapsule.json (plus use_kapsule_tools to grant everything its own MCP section exposes). That allowlist lives in the file, not the Agents view; an agent with no allowlist uses the globally enabled tools.

From the terminal

kaptain mcp add tavily --env TAVILY_API_KEY=${TAVILY_API_KEY} -- npx -y tavily-mcp
kaptain mcp add linear --url https://mcp.linear.app/mcp
kaptain mcp add-json      # paste a {"mcpServers":{…}} block, "-" = stdin
kaptain mcp list | enable | disable | remove <name>

Config lives in mcp_servers.json in the data folder — the same shape those README blocks use, so it's hand-editable too. The CLI updates a running Kaptain live; if none is running, the file takes effect on next start.

Keys and secrets

Approval gating

External tools get the same human gate as built-ins — Ask blocks on the popup, Read-only denies mutations, Auto/Full run. A kapsule can pre-trust one server with a mcp:<name> trusted scope; everything else still asks. Only connect servers you understand — a tool is as powerful as its server.

Outward: Kaptain as a server for your CLIs

Kaptain's whole toolbelt — KodeGraph, file ops, web research, delegation, skills, agents — is one MCP server named kaptain-engine, started with kaptain mcp. There are two ways your Claude, Codex or Gemini CLI meets it, and they are different:

Connect a CLI (one action)

Either press Register standalone in the CLI model's ⚙ popover next to the chat composer, or run one command:

kaptain mcp register claude
kaptain mcp register codex
kaptain mcp register gemini

What it writes, and where:

CLIHow Kaptain registersWhere the entry livesCheck it
Claude Codethe CLI's own command: claude mcp add -s user kaptain-engine -- kaptain mcp~/.claude.jsonmcpServers.kaptain-engineclaude mcp get kaptain-engine
Codexa config block~/.codex/config.toml[mcp_servers.kaptain-engine]codex mcp list
Gemini CLIa settings entryGemini's settings.jsonmcpServers.kaptain-enginethe CLI's /mcp command

Then, in that CLI on its own, ask for something that needs a Kaptain tool — "search this project with KodeGraph for where sessions are stored" — and watch the mcp__kaptain-engine__… call in its tool list. kaptain mcp install-status claude reports the registration from Kaptain's side; kaptain mcp health proves the server itself answers a tool call.

Updates and old entries

The registration points at your installed kaptain binary. After kaptain update, if a CLI reports the server missing, run kaptain mcp register <cli> again — it is safe to repeat. A refresh that does this for you on every update is in progress.

If you used an earlier Kaptain, your CLI config may still carry an old entry — commonly named kaptain-krew, or a kaptain-engine pointing at a binary that no longer exists. Remove those so the CLI has exactly one Kaptain:

claude mcp remove kaptain-krew           # Claude
# Codex: delete the [mcp_servers.kaptain-krew] block from ~/.codex/config.toml

Inside Kaptain you are protected either way: when Kaptain drives a CLI it silences its own duplicate entries for that session and leaves every other server you registered untouched.

Long tool calls: a Kaptain tool that runs for minutes (a build, a test suite, a vision pass) is no longer abandoned by the CLI. The wait is 15 minutes by default, set with KAPTAIN_CLI_TOOL_TIMEOUT_S (seconds).

External tools through Kaptain

Servers you connected to Kaptain (the Inward half above) are re-served to your CLIs as ext__<server>__<tool>, with Kaptain's approval gate in front. The proxy answers only while your Kaptain is running — Kaptain off means those tools vanish rather than fail strangely.

kaptain mcp unregister claude     # remove exactly what Kaptain added, nothing else

If it goes wrong

Agent-readable version: index.md · Every claim on this page was exercised on a real install before being written. Something missing that cost you time? That is a documentation bug — tell us.