# 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.

14 October 2026 · Technical · Explainer · 7 min read · https://bridge-terminal.com/atlas/blog/mcp-servers-claude-code-explained/

## 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.

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:

| Scope | Loads in | Shared with team | Stored in |
| --- | --- | --- | --- |
| `local` (default) | Current project only | No | `~/.claude.json` |
| `project` | Current project only | Yes, via version control | `.mcp.json` in the project root |
| `user` | All your projects | No | `~/.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.

## Context, output limits and tool search

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](https://bridge-terminal.com/atlas/).

## 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.

## About Atlas: Claude Code sessions and secrets in Atlas

In Atlas, every engineer is its own Claude Code session with a written role and its own working folder. If you paste a secret into chat, Atlas puts it in a secret store first, and engineers never see cloud sign-ins. Sending anything outside is never decided for you. Atlas does not yet manage which MCP servers each engineer connects to. — https://bridge-terminal.com/atlas/

## Sources

- [Connect Claude Code to tools via MCP - Claude Code Docs](https://code.claude.com/docs/en/mcp)
- [Control MCP server access for your organization - Claude Code Docs](https://code.claude.com/docs/en/managed-mcp)
- [What is the Model Context Protocol (MCP)?](https://modelcontextprotocol.io/docs/getting-started/intro)

_Researched and drafted with Claude, then checked against the sources above. Atlas is an independent product, not affiliated with Anthropic or OpenAI._
