Atlas
TechnicalExplainer

MCP Servers in Claude Code: Connect Databases and Tools

How MCP servers work in Claude Code: add local and remote servers, choose a scope, handle OAuth and secrets, limit context use and lock them down for a team.

The short version

  • An MCP server is a connector that lets Claude Code reach things outside your project, such as a database, an issue tracker or an internal API, and call its tools like built-in ones.
  • You add a server with claude mcp add and pick a scope: local (default, just you, this project), user (just you, all projects) or project (shared with the team through a committed .mcp.json).
  • Never commit real tokens in .mcp.json. Use ${VAR} or ${VAR:-default} placeholders, which Claude Code expands in command, args, env, url and headers.
  • Tool search is on by default on supported models: only tool names and server instructions load at session start, so adding servers has minimal impact on the context window.
  • Treat each MCP server like a new dependency. Project servers load without asking in claude -p, Agent SDK and cloud sessions, and admins can restrict servers with managed-mcp.json or allowlists and denylists.
On this page
  1. The short version
  2. What an MCP server actually is
  3. Remote and local servers
  4. Scopes: who gets the server
  5. The .mcp.json file and keeping secrets out of git
  6. Authentication with OAuth
  7. Managing and debugging servers
  8. Context, output limits and tool search
  9. Security: approval, prompt injection and team controls
  10. Where to start
  11. Questions people ask

MCP servers give an AI coding agent access to things outside your repository, such as a database, an issue tracker or an internal API. In Claude Code you add one with claude mcp add and choose whether it is private to you or shared with the team through a .mcp.json file. Claude can then call that server's tools the same way it calls its built-in ones. This guide covers how that works, the commands you need, and the settings that matter once you have more than one or two servers.

What an MCP server actually is

The Model Context Protocol (MCP) is described by its maintainers as "an open-source standard for connecting AI applications to external systems." An application that supports MCP can connect to data sources (local files, databases), tools (search engines, calculators) and workflows (specialized prompts).

A server can expose three kinds of things to Claude Code:

  • Tools: functions Claude can call, such as "run this query" or "create an issue". In Claude Code their full names look like mcp__<server>__<tool>.
  • Resources: data you pull into a prompt with an @ mention, for example @github:issue://123 or @postgres:schema://users.
  • Prompts: workflows that appear as commands. Claude Code lists them as /servername:promptname (MCP), and you can also type the long form, for example /mcp__github__pr_review 456.

Because the protocol is open, one server can work with many clients. The MCP project lists Claude, ChatGPT, Visual Studio Code and Cursor among the clients that support it. Each client has its own configuration format, so the commands below apply only to Claude Code.

Remote and local servers

Remote HTTP servers run elsewhere and you reach them by URL. Claude Code's documentation recommends HTTP for remote servers:

bash
claude mcp add --transport http notion https://mcp.notion.com/mcp

If the server takes a static token, pass it as a header:

bash
claude mcp add --transport http secure-api https://api.example.com/mcp \
  --header "Authorization: Bearer your-token"

The older SSE transport is deprecated. Claude Code tries HTTP first and switches to SSE when a server does not accept it; that automatic switch needs v2.1.265 or later. On older versions, pass --transport sse for SSE-only servers.

Local stdio servers are programs Claude Code starts on your machine. The -- separates Claude Code's own options (--transport, --env, --scope) from the command that runs the server, and everything after it is passed to the server untouched:

bash
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
  -- npx -y airtable-mcp-server

Claude Code sets CLAUDE_PROJECT_DIR in a stdio server's environment to the project root, so a local server can tell which project it is working in.

For browsers, Claude Code also has a built-in Claude in Chrome server, which admin controls treat separately (see the security section below).

Scopes: who gets the server

Every server has a scope, set with --scope. It decides who sees the server and where it is stored:

ScopeLoads inShared with teamStored in
local (default)Current project onlyNo~/.claude.json
projectCurrent project onlyYes, via version control.mcp.json in the project root
userAll your projectsNo~/.claude.json
bash
# Shared with everyone who clones the repo
claude mcp add --transport http shared-server --scope project https://example.com/mcp

# Available in all your projects
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic

If the same name is defined in more than one place, precedence is local, then project, then user, then plugin-provided servers, then claude.ai connectors. A server an organization provides through the managedMcpServers managed setting ranks above all of these. The winning entry is used whole; fields are not merged across scopes.

A sensible split: project for servers the whole team needs on this codebase, user for personal tools you want everywhere, and local for experiments or anything holding your own credentials.

The .mcp.json file and keeping secrets out of git

A project-scoped server is written to .mcp.json, which you commit:

json
{
  "mcpServers": {
    "shared-server": {
      "type": "http",
      "url": "https://example.com/mcp"
    }
  }
}

Do not commit real tokens here. Use environment variable expansion: ${VAR} reads a variable, and ${VAR:-default} falls back to a default when it is unset. Expansion works in command, args, env, url and headers:

json
{
  "mcpServers": {
    "api-server": {
      "type": "http",
      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
      "headers": {
        "Authorization": "Bearer ${API_KEY}"
      }
    }
  }
}

Two details catch people out:

  • An unset variable with no default is left as the literal ${VAR} text. The config still loads, and Claude Code reports a missing-variable warning.
  • In a remote server's url and headers, certain credential variables always read as empty, and a :-default on them is ignored. Examples include ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, AWS_BEARER_TOKEN_BEDROCK, HTTPS_PROXY and NPM_TOKEN. If a server needs one of those values, copy it into a variable with your own name.

For short-lived tokens or SSO, headersHelper runs a command that prints a JSON object of headers. It runs fresh on each connection, is not cached, and is abandoned after 10 seconds. If a tool call returns 401 or 403, Claude Code re-runs the helper and retries the call once.

Authentication with OAuth

Many hosted servers use OAuth instead of static tokens. Add the server, then sign in:

bash
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

Inside Claude Code, run /mcp and complete the browser login. From the shell:

bash
claude mcp login sentry
claude mcp login sentry --no-browser   # print the URL instead of opening a browser

claude mcp login prints the URL on its own when no local browser is available, which helps over SSH. claude mcp logout <name> clears stored credentials. If a server needs a pre-registered redirect URI, fix the port with --callback-port. claude -p and Agent SDK runs cannot run the OAuth flow, so sign in from an interactive session first. Removing a remote server also deletes the OAuth tokens and client registration stored for it.

Managing and debugging servers

bash
claude mcp list              # all servers and their status
claude mcp get notion        # details for one server
claude mcp remove notion     # remove it

claude mcp list shows states such as ✔ Connected, ! Needs authentication, ✘ Failed to connect and ⏸ Pending approval. Inside a session, /mcp lets you sign in, turn a server off without losing its configuration, and reconnect it; /mcp reconnect all retries every failed server.

If a slow server will not start, raise the startup timeout (in milliseconds):

bash
MCP_TIMEOUT=10000 claude

A "timeout" field in a server's .mcp.json entry sets that server's tool timeout in milliseconds and overrides MCP_TOOL_TIMEOUT for it.

If you already set servers up in Claude Desktop, claude mcp add-from-claude-desktop imports them on macOS and WSL. In the other direction, claude mcp serve runs Claude Code itself as a stdio MCP server for other clients.

Every tool definition costs context. Claude Code handles this with tool search, on by default on supported models: only tool names and server instructions load at session start, and full definitions load when Claude needs them. You can tune it with ENABLE_TOOL_SEARCH:

bash
ENABLE_TOOL_SEARCH=auto:5 claude   # load upfront while definitions total under 5% of context
ENABLE_TOOL_SEARCH=false claude    # load everything upfront

Claude Code turns tool search off when ANTHROPIC_BASE_URL points to a non-first-party host, because most proxies do not forward the blocks it needs; setting ENABLE_TOOL_SEARCH explicitly overrides that.

To keep a server's tools always visible, set "alwaysLoad": true on it. Each upfront tool uses context, and startup waits for that server's tools (up to the 5-second connect timeout), so reserve this for the few tools Claude needs on every turn.

Tool output is capped as well. Claude Code warns when a tool returns more than 10,000 tokens, and the default maximum is 25,000 tokens. You can raise it:

bash
MAX_MCP_OUTPUT_TOKENS=50000 claude

Separately, a successful text result longer than 50,000 characters is saved to a file and replaced with a file reference, whatever MAX_MCP_OUTPUT_TOKENS is set to. Database servers hit these limits most, because a full schema or large query result easily goes over. A server author can raise the threshold for one tool, such as get_schema, with the anthropic/maxResultSizeChars annotation, up to 500,000 characters.

Security: approval, prompt injection and team controls

The documentation says to verify you trust each server before connecting it, and warns that servers fetching external content can expose you to prompt injection. A server can read data and act on your behalf, so review it as you would a new dependency.

Built-in safeguards:

  • Project servers need approval. In interactive sessions, Claude Code asks before using servers from a cloned .mcp.json. Reset those choices with claude mcp reset-project-choices.
  • Headless runs do not ask. In claude -p, Agent SDK and cloud sessions, project servers load without a prompt. To block one, add it to disabledMcpjsonServers in settings. This matters if you run Claude Code in CI.
  • Per-tool approval. A server author can mark a tool with anthropic/requiresUserInteraction so it prompts on every call, even in acceptEdits, auto and bypassPermissions modes. In dontAsk mode the call is denied.

For organizations, administrators can control MCP centrally:

  • A managed-mcp.json file at a system path (/Library/Application Support/ClaudeCode/ on macOS, /etc/claude-code/ on Linux and WSL, C:\Program Files\ClaudeCode\ on Windows) takes exclusive control. Users cannot add or use other servers, including plugin servers. An empty mcpServers map blocks every server except the few that still load under exclusive control.
  • allowedMcpServers and deniedMcpServers in managed settings filter what users configure. Match on serverUrl or serverCommand. The docs say a serverName entry "is not a security control", because a user can call any server github.
  • With managed-mcp.json deployed, Claude in Chrome is blocked in terminal sessions unless allowClaudeInChromeWithManagedMcp is set in the device's own managed settings.

Where to start

Add one remote server over HTTP, sign in with /mcp, and check claude mcp list before adding more. Put team-wide servers in .mcp.json with ${VAR} placeholders, and keep personal credentials in local or user scope. Leave tool search on, and raise output limits only for servers that need it, which usually means databases. Before anything runs unattended, decide which project servers a headless run may load. A CLAUDE.md file is a good place to tell the agent when to use each server.

For more on running several Claude Code sessions as a team, see the Atlas home page.

Questions people ask

What is an MCP server in Claude Code?

It is a connector, built on the open Model Context Protocol, that gives Claude Code access to something outside your repository, such as a database, an issue tracker or an internal API. A server can expose tools Claude calls, resources you @-mention and prompts that appear as commands.

How do I add an MCP server to Claude Code?

Use claude mcp add. For a remote server, run something like claude mcp add --transport http notion https://mcp.notion.com/mcp. For a local program, use --transport stdio and put the command that starts the server after --.

What is the difference between local, project and user scope for MCP servers?

Local scope (the default) loads only in the current project and is not shared. Project scope is stored in .mcp.json in the project root and shared through version control. User scope loads in all your projects but is not shared. Local and user servers are stored in ~/.claude.json.

How do I keep API keys out of .mcp.json?

Use environment variable expansion such as ${API_KEY} or ${VAR:-default} in command, args, env, url or headers instead of committing a real token. An unset variable with no default stays as literal text and Claude Code shows a missing-variable warning. For short-lived tokens, headersHelper can generate headers at connection time.

How can an organization control which MCP servers people use?

Administrators can deploy a managed-mcp.json file at a system path for exclusive control, so users cannot add or use other servers. They can also set allowedMcpServers and deniedMcpServers in managed settings, matching on serverUrl or serverCommand rather than serverName, which is not a security control.

Sources

  1. Connect Claude Code to tools via MCP - Claude Code Docs
  2. Control MCP server access for your organization - Claude Code Docs
  3. What is the Model Context Protocol (MCP)?

Researched and drafted with Claude, then checked against the sources above. Atlas is an independent product, not affiliated with Anthropic or OpenAI. Claude and Claude Code are trademarks of Anthropic; Codex is a product of OpenAI.