MCP servers in Claude Code: setup, scopes, and security

MCP is how Claude Code reaches things that are not files: your issue tracker, your database, your monitoring. It is also the largest hole people knowingly cut in an otherwise careful permission model.

By the Continuum team. We build a workbench that runs Claude Code, Codex, and their peers, so the model rates quoted here are the ones our own cost analytics ship with.

The short version

Add a server with claude mcp add <name> -- <command> for a local stdio process, or claude mcp add --transport http <name> <url> for a remote one. Choose a scope: local (you, this project, the default), project (written to a committed .mcp.json), or user (you, everywhere). Check what actually connected with claude mcp list or /mcp. The critical security point: the permission system governs what the agent does directly, not what a tool server reaches on its behalf.

What you need to know
  • Three scopes: local (default), project (committed .mcp.json), user (everywhere).
  • Transports: stdio, http, sse, plus ws via claude mcp add-json only.
  • The sandbox does not cover MCP servers. A server runs with its own credentials and reach.
  • Tool search is on by default as of August 2026, so extra servers no longer flood your context.
  • claude mcp list shows health; /mcp shows tool counts and runs OAuth sign-in.

Adding a server

Two shapes. A local stdio server is a process on your machine and everything after the -- is the command that runs it. A remote server is a URL and needs an explicit --transport.

The three scopes and both common transports.
# local stdio server: just me, just this project (the default scope)
claude mcp add db -- npx -y @bytebase/dbhub --dsn "$READONLY_DATABASE_URL"

# the whole team, written to a committed .mcp.json
claude mcp add --transport http --scope project linear https://mcp.linear.app/mcp

# me, in every project
claude mcp add --transport http --scope user sentry https://mcp.sentry.dev/mcp

# a server that needs a header credential
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer $GITHUB_PAT"

# a transport --transport does not accept (ws), via JSON
claude mcp add-json events \
  '{"type":"ws","url":"wss://mcp.example.com/socket"}'

Which scope to use, and where it is written.

ScopeStored inUse for
local (default)Your ~/.claude.json, keyed per projectAnything with a personal credential
project.mcp.json at the repo root, committedServers the whole team should have
userYour ~/.claude.json, top levelPersonal tools you want everywhere

Keep credentials out of the committed file

.mcp.json supports environment expansion, so a shared config can reference a secret each developer supplies themselves. Both ${VAR} and ${VAR:-default} work, in command, args, env, url, and headers.

.mcp.json, safe to commit.
{
  "mcpServers": {
    "db": {
      "command": "npx",
      "args": ["-y", "@bytebase/dbhub", "--dsn", "${READONLY_DATABASE_URL}"]
    },
    "docs": {
      "type": "http",
      "url": "${DOCS_MCP_URL:-https://mcp.example.com/v1}"
    }
  }
}

The security model, stated plainly

Claude Code has a permission system that governs what the agent does directly: which files it may edit, which commands it may run. That system does not extend through an MCP server.

  1. Scope the credential, not the prompt. Give the database server a read-only role. That is a boundary; an instruction is not.
  2. Read the server code, or at least know who wrote it. A stdio server runs as you, with your files and your network.
  3. Prefer project scope for shared servers, so additions arrive in a pull request rather than each person quietly adding their own.
  4. Deny the tools you never want. MCP permission rules use the server name: mcp__puppeteer matches every tool on that server, mcp__puppeteer__puppeteer_navigate matches one.
  5. Be careful with anything that fetches external content. Anthropic’s own docs flag this: a server that pulls arbitrary URLs turns outside content into a possible instruction channel.
  6. Audit periodically. claude mcp list. Servers accumulate and nobody removes them.
Denying by server or by tool, in .claude/settings.json.
{
  "permissions": {
    "deny": [
      "mcp__puppeteer",
      "mcp__db__execute_sql"
    ],
    "allow": [
      "mcp__db__query"
    ]
  }
}
A dashed boundary containing Claude Code with its Read, Edit and Bash tools where permission rules apply, and one MCP tool call crossing that boundary into an MCP server that reaches a database, an issue tracker and the open internet on its own credential WHERE THE RULES STOP allow, ask and deny rules decide every call in here Claude Code Read Edit Bash mcp__db the permission system ends here one tool call leaves outside the permission system the MCP server runs with its own credential your database your issue tracker the open internet Rules constrain what the agent does, never what the server does next.

Debugging a server that will not connect

01

Check the health line

claude mcp list prints a status next to each server. The command succeeding does not mean the servers did.

# configured servers plus a health status each
claude mcp list

# one server in full
claude mcp get sentry

# from inside a session: tool counts, disable toggle, OAuth
/mcp
02

Match the status to the cause

What each status means. Statuses as of August 2026.

StatusMeansDo this
ConnectedWorkingNothing
Needs authenticationServer returned 401 or 403claude mcp login <name>, or Re-authenticate in /mcp
Failed to connectProcess died, bad URL, or a rejected header credentialRun the command by hand; check the token
Pending approvalProject server from .mcp.json not yet approvedRun claude interactively and approve it
RejectedListed in disabledMcpjsonServersRemove it from that settings array
cachedRemote server, tool list reused from a previous sessionNothing; it connects on first tool call
03

Run the server by hand

For a stdio server, this is almost always where the answer is. The process either fails to start, or it starts and pollutes the protocol channel.

npx -y @bytebase/dbhub --dsn "$READONLY_DATABASE_URL"

# raise the 30s startup timeout while you investigate
MCP_TIMEOUT=60000 claude

The failures, roughly in order of frequency.

SymptomCauseFix
Server missing from /mcpProcess failed to startRun the command by hand
Starts, then disconnectsWrote to stdoutstdio owns stdout as the protocol channel; log to stderr
Auth errors on a stdio serverEnv var not visible to the processPass it with --env, or export it
Needs authentication on a remote serverOAuth not completed, or a stale refresh tokenclaude mcp login <name>
Works for you, not the teamLocal scopeRe-add with --scope project
Server ignored on a fresh cloneWorkspace not trusted yetRun claude in it and accept the trust dialog
npx hangsPackage resolution over the networkInstall it and use an absolute path
Tool call aborts with no error from the serverIdle timeout5 min remote, 30 min stdio; tune CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT
Server name refused outrightReserved nameworkspace, claude-in-chrome, computer-use and two others are reserved

Timeouts, output limits, and the context question

MCP has more clocks than most people realise, and a slow server hits a different one depending on how it is failing.

MCP limits and where to change them. As of August 2026.

LimitDefaultControl
Server startup30 secondsMCP_TIMEOUT (milliseconds)
Tool call, wall clockAbout 28 hoursPer-server timeout in .mcp.json, or MCP_TOOL_TIMEOUT
First response byte, remote only60 secondsRaised by setting the per-server timeout to 60s or more
Idle with no progress5 min remote, 30 min stdioCLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT, or 0 to disable
Tool output warning10,000 tokensFixed
Tool output cap25,000 tokensMAX_MCP_OUTPUT_TOKENS

Tool search changed the token maths

For a long time the honest advice was that every connected server contributed its tool definitions to context on every turn, so servers you forgot about were a permanent tax. As of August 2026 that is no longer the default. Tool search is on by default: only tool names and server instructions load at session start, and full schemas load when Claude searches for them.

ENABLE_TOOL_SEARCH values.

ValueBehaviour
(unset)All MCP tools deferred, loaded on demand. The default.
trueForce deferral, including through a proxy that may not support it
autoLoad upfront if the schemas fit in 10% of the context window, defer the rest
auto:NSame, with your own percentage, such as auto:5
falseLoad every schema upfront. The old behaviour.
  • Add servers for work you actually do repeatedly, not for capability you might want.
  • Prefer local or user scope for personal experiments so you do not impose them on the team.
  • Write real server instructions if you author a server. With tool search on, that text is how Claude decides to go looking for your tools. Descriptions and instructions are truncated at 2KB each.

Sharing servers with a team

Project scope is the point at which MCP stops being a personal convenience and becomes shared infrastructure, which means it needs the same review as code.

01

Add at project scope and commit

claude mcp add --scope project ... writes .mcp.json at the repo root. Review the diff like any other config change: the file is exactly as public as your repository.

02

Expect an approval prompt on every teammate’s first run

Claude Code asks before using project-scoped servers in interactive sessions. Reset those choices with claude mcp reset-project-choices. Approvals are read only from settings files that are not checked into the repo, and only after the workspace trust dialog is accepted, so a cloned repository cannot approve its own servers.

03

Decide what happens in headless runs

claude -p, Agent SDK sessions, and cloud sessions cannot show that prompt, so they load project-scoped servers without asking. To keep one out everywhere, add it to disabledMcpjsonServers; to drop project settings entirely, use --setting-sources.

04

Pin the approvals you do want

Set enabledMcpjsonServers to a list, or enableAllProjectMcpServers to true, in a settings file that is not committed. Those keys are ignored in an untrusted folder by design.

Questions people ask

Run claude mcp add <name> -- <command> for a local stdio server, or claude mcp add --transport http <name> <url> for a remote one. Add --scope project to commit it as .mcp.json for the team, or --scope user to have it in every project.

local is you in this project and is stored in your own config; project writes .mcp.json at the repo root and is shared through version control; user applies to all your projects. Put anything with a personal credential in local.

Only at the call boundary. You can allow or deny individual tools with mcp__server__tool rules, but the server itself runs with its own credentials and reach, so a read-only agent with a write-capable database server can still write. Scope the credential.

Most often because it wrote to stdout. The stdio transport uses stdout as the protocol channel, so any stray print corrupts the stream. Log to stderr. Run the server command by hand to see the real error.

claude mcp list from the shell shows a health status per server, and claude mcp get <name> shows one in full. Inside a session, /mcp shows tool counts, lets you toggle a server off, and runs the OAuth flow.

Not by default as of August 2026. Tool search defers schemas, so only tool names and server instructions load at session start. Set ENABLE_TOOL_SEARCH=false to go back to loading everything upfront, and note that a non-first-party ANTHROPIC_BASE_URL falls back to that automatically.

For OAuth servers, run claude mcp login <name> from the shell, or open /mcp and complete the browser flow. For token-based servers, pass --header "Authorization: Bearer ..." when adding. Claude Code does not validate the credential at add time, so a bad token shows up later as a failed connection.

.mcp.json is project scope at the repo root and is meant to be committed. ~/.claude.json holds your local-scope servers keyed per project and your user-scope servers at the top level, and is never shared.

Sources

Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.

  1. Claude Code: connect to tools via MCP
  2. Model Context Protocol specification
  3. Claude Code permissions reference
  4. Claude Code settings reference
Try it

What is it
costing you?

Continuum shows the token split per session, so standing overhead from tool definitions becomes visible instead of assumed.

free app · your subscriptions · local-first