ConfigurationMCP servers

Use your repository's MCP servers

Let the agents use the MCP servers your repository already declares, with credentials that never enter their sandbox.

Overview

If your repository declares MCP servers in .mcp.json, SHIP's agents can use them too. For example, the Planner can read your issue tracker, and the Builder can read the docs of a library. You don't change the file. You bind each server once, on the project: choose which agents may use it, approve its tools, and add its credential.

You can do everything on this page from four places. In the console, open the project from Your projects, and find the servers under MCP servers. The API (/v1/mcp/projects/{projectId}), the MCP server and the CLI (ship mcp) do the same.

The MCP servers section of a project page: the file the servers come from, then a card per server with how it runs, its credential, the tools each agent receives, and its status.
A project's MCP servers. Each card says how the server runs, which credential it holds (never its value), and what each agent receives.
note

Credentials never enter an agent's sandbox. The agents reach each bound server through SHIP. SHIP adds the credential to each request that leaves the sandbox, and removes it from each response. So the sandbox holds nothing that someone can read and use again somewhere else.

Follow a guide

Each guide below gives all the steps for one kind of server, in the console, the CLI and the MCP server:

Where server definitions come from

SHIP reads your repository's MCP file from the default branch at the start of each mission. SHIP accepts both the mcpServers key and the servers key:

{
  "mcpServers": {
    "linear": { "type": "http", "url": "https://mcp.linear.app/mcp" },
    "context7": { "type": "http", "url": "https://mcp.context7.com/mcp" },
    "sentry": { "command": "npx", "args": ["-y", "@sentry/mcp-server@latest"] }
  }
}

The default path is .mcp.json. If your file is at a different path, such as .cursor/mcp.json or .vscode/mcp.json, set the path in one of two places:

  • in ship.yml, committed with the rest of your configuration:

    mcp:
      config: .cursor/mcp.json
  • or on the project in SHIP: Change file on the project's page, ship mcp file .cursor/mcp.json, or PATCH /v1/mcp/projects/{projectId}.

If you set the path in both places, the path in ship.yml applies. The project's page then shows the path from ship.yml and has no control to change it. SHIP reads ship.yml from your default branch, so a pull request can't make its own agents use a different file. If ship.yml names a file that doesn't exist, the page says so. SHIP doesn't use another file instead.

SHIP never edits this file and never needs ${VAR} placeholders in it. If it already has them, their names pre-fill the credential form.

Bind a server

If the repository declares a server but nobody binds it, no agent can use it. A binding sets three things:

  • Agents. Which of the Planner, Builder, Reviewer and QA agent may use it. The console labels this role QA, and the CLI and ship.yml name it qa.
  • Tools. SHIP lists the server's tools when you bind it, and you approve the ones the agents may call. A tool the server adds later stays hidden until you approve it.
  • Credential. How SHIP authenticates to the server. This depends on how the server runs (see below).

Choose how a server runs

How it runsForCredentialAgents
Remote, through SHIPA server with a url, or the vendor's hosted endpoint for a command serverRequest headers, or an OAuth sign-inAny. The Reviewer and the QA agent get only read-only tools
Isolated runtimeAn npm server (npx, pnpm dlx, bunx) that needs a secretEnvironment variables, sent only to the hosts you allowAny. The Reviewer and the QA agent get only read-only tools
Inside the sandboxA server that needs no secret, from npm, Python (uvx) or the repositoryNonePlanner and Builder

Remote servers

SHIP reaches a server with a url over Streamable HTTP. Its credential is one of these:

  • Headers, such as an API key header or a bearer token, which SHIP stores encrypted.
  • OAuth: select Connect and sign in with the provider. SHIP renews the authorization. If the provider revokes it, the server shows Reconnect, and the agents get a message that it needs attention.

When you bind the server, SHIP pins the credential to the server's URL. If the repository later moves the same server to a different host, the binding stops until you confirm the new host. So a change to the file can never send a credential to a different host.

You can't bind a server that has only the older HTTP+SSE transport. If the vendor also hosts a Streamable HTTP endpoint, bind that one.

Servers that run locally

You can bind a server that starts with a command, such as npx some-mcp-server, in two ways:

  • In the sandbox, for servers that need no secret. It runs next to the agent, exactly as the repository declares it. The sandbox has Node (npx, bunx) and Python (uvx, with Python 3.12 preinstalled), so most published servers start without any setup.
  • Isolated, for npm servers that need a secret. SHIP pins the exact package version when you bind it, builds it once, and runs it in an isolated runtime outside the sandbox. The server sees only a stand-in value for its secret. SHIP puts the real value only in requests to the hosts that you list. SHIP blocks every other network request.

A Python server, a native binary or a script from the repository can't run isolated. If it needs a secret, bind the vendor's hosted endpoint instead, under the same name. A server that starts with Docker can't run in the sandbox either. For such a server, the hosted endpoint is the only way to bind it.

From a terminal, the same steps are:

ship mcp list --project prj_123
ship mcp bind github --roles planner,builder,qa --header-file Authorization=github-header.txt
ship mcp tools github --refresh
ship mcp tools github --approve get_issue,search_code

The header file holds the header's whole value, such as Bearer <token>. The secret then never appears in your shell history. For each server that isn't ready, ship mcp list ends with the command to run next.

What each agent can use

The Reviewer and the QA agent never change your repository, so they get only the tools that the server marks as read-only. If the server doesn't annotate a tool, you can attest that the tool is read-only when you approve it. You can't give them a tool that the server marks as one that writes. SHIP never gives a server that runs in the sandbox to the Reviewer or the QA agent, because SHIP can't enforce read-only access there.

The tools dialog for a GitHub server: each tool with a checkbox and a read-only, unannotated, writes or destructive tag, and which tools the reviewer and QA receive.
Approving tools. Read-only tools reach the reviewer and QA; a tool that writes reaches only the planner and builder.

To limit access more for one repository, list the servers (and, if you want, the tools) for each agent in ship.yml:

agents:
  reviewer:
    mcp:
      - context7
      - server: sentry
        tools: [get_issue_details]

ship.yml and the per-issue override can only narrow what the binding allows. They can never add a server or a tool the binding doesn't grant.

See every credential in one place

Vault → MCP servers lists each MCP credential in your projects: which server it belongs to, which agents use it, how it runs and its status. It shows the kind of credential and the names of its headers or variables. It never shows their values. To change a credential, open its project. ship mcp bindings and GET /v1/mcp/bindings give the same list.

The Vault's MCP inventory: a table per project listing each server's status, agents, credential kind and field names, how it runs, and when it changed.
The org's MCP credentials by project. Values are never shown, here or to the agents.

Supported agent harnesses

Each agent harness that supports MCP gets the same servers. SHIP writes them in the configuration format of that harness, outside your working tree. Each harness also ignores the MCP files that are committed to your repository, so a pull request can't make an agent start a server.

HarnessMCP servers
claude-codeSupported
codexSupported
open-codeSupported
kilo-codeSupported
piNot yet. A role on pi that has MCP servers fails with a message that names the harness

When something is wrong

A server that can't be used never fails quietly. Before an agent starts, SHIP checks each server that the agent should get. If one can't be used, SHIP stops the mission with a message that names the server and the cause:

  • you must reconnect it,
  • its package is not prepared yet,
  • the repository moved it to another host, or
  • the role's harness can't use MCP.

Fix the server on the project's page. Then restart the mission. The fix applies to the next agent, and nothing else in the mission changes.

SHIP records on the mission each tool call that an agent makes through SHIP. This includes the calls that SHIP refuses. The record of each attempt also lists the servers that its agent had. In the console, the timeline of a run shows each MCP tool call as server - tool. For claude-code runs, the timeline also shows which servers connected when the agent started. Fix a server that doesn't work covers each case.

How is this page?

On this page