Claude Code MCP Servers: Setup, Config & Cron-Safe Template
Claude Code MCP servers are external programs or hosted endpoints that give Claude Code extra tools, such as a browser, GitHub, Sentry or a database. You add one with claude mcp add, check it with claude mcp list and remove it with claude mcp remove <name>. In the words of the official MCP docs, "MCP servers give Claude Code access to your tools, databases, and APIs." Most guides stop at the interactive setup. This one also covers what changes when nobody is at the keyboard: which servers a cron run loads, how to scope their permissions, which timeouts apply, and what happens when a server goes down partway through a job.
Which option is right for you?
Choose the scope and transport that fit how you work, then open the matching page. Each row gives a one-line reason.
| Your situation | What to pick first | First page to open |
|---|---|---|
| Beginner, never added a server | One hosted HTTP server at the default local scope. It needs no install or sign-in | Connect to MCP servers (quickstart) |
| Daily interactive work across many repos | --scope user for the 1–3 servers you use everywhere, because they load in every project | MCP reference: scopes |
| Small team sharing one repo | --scope project (.mcp.json committed), so teammates get the same config | Quickstart: Edit .mcp.json directly |
| Cron / headless jobs | A separate JSON file passed with --mcp-config plus --strict-mcp-config, so the job loads only what you list | Run Claude Code programmatically |
| Tight token budget | Fewer servers, because every connected server's tool names load into each session | Quickstart note on context |
For a cron job, keep the automation's server list out of your personal config. The rest of this guide explains why.
What is a Claude Code MCP server?
A Claude Code MCP server is a process or hosted URL that exposes extra tools to Claude Code over the Model Context Protocol. Claude Code calls those tools like its built-in ones. The quickstart describes it as letting Claude Code use tools "beyond its built-in set, such as searching an issue tracker, querying a database, or controlling a web browser."
Servers come in two shapes:
- Local (stdio): Claude Code starts the program as a subprocess on your machine. The Playwright server is one example. Use this shape for anything that needs local resources such as a browser, the filesystem or a database socket (quickstart).
- Remote (HTTP): the vendor hosts the server and you register its URL. Anthropic's remote MCP announcement pitches this as the lower-maintenance option because you have no local server to manage.
Each tool appears to Claude under a prefixed name, mcp__<server>__<tool>. That name matters later, because permission rules match against it (permissions docs).
So, can Claude Code use MCP servers? Yes, in every surface. The CLI, the desktop app, VS Code and cloud sessions can all connect. Connectors you add at claude.ai also load in the CLI when you sign in with that account (quickstart: Connect from other surfaces).
How do you install Claude Code MCP servers?
For most servers, installing is the same step as registering. You run claude mcp add, and either Claude Code fetches the package through npx the first time it starts the server, or you point it at a hosted URL.
Prerequisites, per the quickstart:
- Install and authenticate Claude Code.
- Open a terminal in a project directory. An empty directory works.
- For
npx-based local servers, install Node.js. The Playwright server, for example, requires Node.js 18 or later.
Then run the add command in your shell, not inside a claude session:
# Remote example from the docs: no auth needed
claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp
# Local example from the docs: Playwright browser server
claude mcp add playwright -- npx -y @playwright/mcp@latest
Common install mistakes and fixes:
- "Added" but
✘ Failed to connect. The Added message only means the entry was saved. On the first check,npxmay still be downloading the package, so wait and runclaude mcp listagain (quickstart). - Startup times out. The default startup timeout is 30 seconds. Raise it with
MCP_TIMEOUT=60000 claude. The value is in milliseconds (quickstart troubleshooting). - Need to diagnose a local server. Run the server command yourself, for example
npx -y @playwright/mcp@latest. If it starts and waits for input, the server works and the problem is in your Claude Code entry.
If you already set up servers in the Claude Desktop chat app, claude mcp add-from-claude-desktop copies them into the CLI on macOS or WSL (quickstart).
How do you configure Claude Code MCP servers (config file)?
Claude Code stores MCP server configuration in ~/.claude.json or a project's .mcp.json, depending on scope. ~/.claude.json holds the local and user scopes, and .mcp.json in the project root holds the project scope. The file depends on the --scope you pick (quickstart).
| Scope | File | Who gets it |
|---|---|---|
local (default) | ~/.claude.json, under this project's entry | Only you, only this project |
project | .mcp.json in project root | Everyone who clones the repo |
user | ~/.claude.json, top-level mcpServers | Only you, all projects |
On Windows, ~/.claude.json resolves to %USERPROFILE%\.claude.json. If CLAUDE_CONFIG_DIR is set, Claude Code reads the file from that directory instead (quickstart). When one name exists in several scopes, precedence runs local, then project, then user, then plugins, then claude.ai connectors (MCP reference).
Here is a hand-written .mcp.json example. The first two entries come from the docs. The ${...} variables and the timeout field are documented options:
{
"mcpServers": {
"claude-code-docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp"
},
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
},
"internal-api": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": { "Authorization": "Bearer ${API_KEY}" },
"timeout": 600000
}
}
}
The details that matter, all from the MCP reference:
${VAR}and${VAR:-default}expand incommand,argsandenvfor stdio servers, and inurlandheadersfor HTTP servers. Keep tokens in the environment, not in a committed file.- Some credentials always read as empty in remote URLs and headers, on purpose:
ANTHROPIC_API_KEY,ANTHROPIC_AUTH_TOKEN,NPM_TOKENand a few others. If your header comes out blank, this is likely why. - An entry with a
urlbut notypeis an error. Add"type": "http". - A per-server
timeoutin milliseconds overridesMCP_TOOL_TIMEOUTfor that server only.
Pitfall: editing the wrong file. Claude Code does not read ~/.claude/.mcp.json, ~/.claude/mcp.json, ~/.claude/config/mcp.json or %APPDATA%\Claude\mcp.json (quickstart troubleshooting). Edits to .mcp.json take effect only when a new session starts (quickstart troubleshooting). A malformed entry is skipped while the others still load, so run claude mcp list and look for the parse warning (quickstart troubleshooting).
How do you add and remove a Claude Code MCP server?
You add a Claude Code MCP server with claude mcp add (or add-json) and remove it with claude mcp remove <name>. Both commands print the file they modified (quickstart).
Add, by server type (MCP reference):
- Remote HTTP:
claude mcp add --transport http <name> <url> - Remote with a static token: append
--header "Authorization: Bearer <token>". The docs' GitHub example isclaude mcp add --transport http github https://api.githubcopilot.com/mcp/ --header "Authorization: Bearer YOUR_GITHUB_PAT". - Local stdio:
claude mcp add [options] <name> -- <command> [args...], for example--env AIRTABLE_API_KEY=YOUR_KEY. - Raw JSON:
claude mcp add-json <name> '<json>', which is also the only way to add a WebSocket (ws) server. - OAuth servers such as Sentry (
https://mcp.sentry.dev/mcp): add the URL, startclaude, run/mcp, select the server and choose Authenticate. You can also runclaude mcp login <name>from the shell.
The -- separator is the most common mistake. Your own options (--transport, --env, --scope) go before it, and the docs say "Everything after -- is passed to the server untouched" (MCP reference). If claude mcp get <name> shows a different command from the one you typed, remove the server and add it again with -- in place.
Remove or pause:
claude mcp remove claude-code-docs # default scope
claude mcp remove claude-code-docs --scope local # when it exists in several scopes
If the name exists in more than one scope, remove reports exists in multiple scopes, and you choose one with --scope (quickstart). To pause a server without deleting it, toggle it off in the /mcp panel. Claude Code records that choice per project in a disabledMcpServers list in ~/.claude.json (MCP reference). You can't change a server's scope in place. Remove it and add it again at the new scope (quickstart).
How do you connect Claude Code to local vs remote MCP servers?
Claude Code connects to local servers over stdio and to remote servers over HTTP. SSE still works but is deprecated, and WebSocket can only be configured through JSON (MCP reference). For unattended runs, the biggest difference between them is how each transport fails and recovers.
| Local (stdio) | Remote (HTTP) | |
|---|---|---|
| Runs where | Subprocess on your machine | Vendor's infrastructure |
| Auth | Env vars (--env) | Header token, OAuth, or headersHelper script |
| Default idle timeout per tool call | 1,800,000 ms (30 min) | 300,000 ms (5 min) |
| If it drops mid-session | In claude -p, retried on the next tool call | Up to 5 retries with exponential backoff starting at 1 s |
| If first connect fails | Marked failed; use /mcp Reconnect | Transient errors retried up to 3 times |
| Main risk unattended | Missing runtime (Node), slow first npx download | Network, expired token, vendor outage |
The idle timeout figures come from the environment variables reference (CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT, v2.1.187 or later). The retry behavior comes from the MCP reference. Authentication errors are different: Claude Code stops retrying and waits for you to sign in again. A cron job can't do that, which is why OAuth servers fit unattended runs poorly unless their credentials stay valid.
Quick connectivity check. For an HTTP server, run curl -I <url>. A 404 or 405 still means the server is up, because many MCP endpoints answer only POST. A 401 or 403 means you need to authenticate. No response at all points to the URL or the network (quickstart troubleshooting).
How do you use a Claude Code MCP server in a session?
You use a Claude Code MCP server by asking for the task in plain language. Claude picks the relevant tool on its own, and you approve the first call when prompted (quickstart).
- Run
claude mcp listand confirm the server shows✔ Connected. - Start
claudein the same project. Servers at local scope are tied to the directory where you added them. - Ask for something that needs the server, for example:
Use playwright to open https://example.com and tell me the page title. - Approve the permission prompt. Each tool call is labeled with the server name, such as
browser_navigatefromplaywright. - Run
/mcpat any time to see status and tool lists, reconnect a server or authenticate.
Naming the server in your prompt isn't required. The docs do it in the walkthrough so the test definitely goes through the new server rather than a built-in tool such as web fetch.
Watch the output size. Claude Code shows a warning when an MCP tool returns more than 10,000 tokens and caps output at 25,000 tokens by default. MAX_MCP_OUTPUT_TOKENS changes the cap (MCP reference). Large database or log queries hit that cap quickly. For ways to trim them, see how to see token usage and reduce it.
Status meanings you'll see (quickstart):
! Needs authentication: the server is reachable but needs a browser sign-in or a token.! Connected · tools fetch failed: the server connected but couldn't list its tools. Runclaude mcp get <name>for details.⏸ Pending approval: a project-scoped server you haven't approved yet.- The server connects but shows no tools: usually a missing required env var, such as an API key.
Claude Code MCP servers list: which ones are worth running?
For recurring solo-builder work, start with two or three servers that each cover a job you would otherwise script by hand. Each server you connect adds context cost and permission surface (quickstart).
| Server | Transport | Good for | Not for / limitation |
|---|---|---|---|
Claude Code docs (https://code.claude.com/docs/mcp) | HTTP, no auth | Your first test; looking up flags | Only searches docs, no real work |
GitHub (https://api.githubcopilot.com/mcp/) | HTTP + PAT | Triage issues and PRs on a schedule | The token's scope is the blast radius; use a fine-grained PAT |
Playwright (@playwright/mcp) | stdio, Node 18+ | Smoke-checking a deployed page | Needs a browser on the host, heavy on a small VPS |
Sentry (https://mcp.sentry.dev/mcp) | HTTP + OAuth | Morning error summaries | OAuth expiry can block cron runs |
| Filesystem / Git / Fetch / Time (reference servers) | stdio | Learning, narrow local tasks | Reference code only (see below) |
Sources: the quickstart for docs, Playwright and Sentry, the MCP reference for GitHub, and the modelcontextprotocol/servers repo for the reference set.
Two things many "best MCP servers" lists get wrong as of October 2026. First, the official repo now maintains seven reference servers: Everything, Fetch, Filesystem, Git, Memory, Sequential Thinking and Time. Second, it archived thirteen others, including GitHub, PostgreSQL, Slack, Puppeteer and SQLite, in servers-archived (servers repo). If a tutorial tells you to install the old GitHub or Postgres package from that repo, look for the vendor's own server instead.
Where do you find and vet Claude Code MCP servers on GitHub?
Find Claude Code MCP servers in the official MCP Registry, Anthropic's reviewed Anthropic Directory, or vendor GitHub repos. Vet each one before an automation depends on it.
The official repo says plainly that its servers are educational examples, "not as production-ready solutions" (modelcontextprotocol/servers). Anthropic's MCP page adds: "Verify you trust each server before connecting it." It also warns that servers which fetch external content carry prompt injection risk (MCP reference).
A short vetting checklist before a server goes into a scheduled job:
- Who publishes it? Prefer the vendor's own server (GitHub, Sentry, Microsoft's Playwright) over a third-party wrapper.
- What does the token allow? A server can only do what its credential permits. Create a dedicated token with read-only or single-repo scope where the vendor offers it.
- Is it pinned?
@latestinnpxargs can change under a cron job overnight. Pin a version in automation configs, for example@playwright/mcp@<version>, and update it on purpose. - Does it read untrusted content? Web fetchers, issue readers and inbox readers can carry injected instructions. Pair them with narrow allow rules (next section).
- Is it still maintained? A recent commit history and open-issue activity matter more than star count.
Also be careful with similar names: projects like steipete/claude-code-mcp run Claude Code itself as an MCP server for other agents (GitHub). That's the opposite direction from this guide.
How do you run Claude Code MCP servers headlessly and safely?
Give each headless job its own server file, allowlist named MCP tools, set short timeouts, and check server status in the output. A claude -p run has nobody to answer prompts.
Why your interactive setup is risky in cron
Without --bare, claude -p loads the MCP servers in the working directory's .mcp.json, and the headless docs note: "A -p session shows no workspace trust dialog and no per-server approval prompt." The approval that protects you interactively is skipped. Two flags close the gap:
--bareskips auto-discovery of MCP servers, hooks and CLAUDE.md, and connects only servers you pass with--mcp-config. The limitation: bare mode never reads OAuth or keychain credentials, so it needsANTHROPIC_API_KEYand won't use your Pro or Max login (headless docs).--strict-mcp-configwith--mcp-configloads only the servers in that file and ignores other MCP configuration (CLI reference). Use this one if you run on a subscription. One open report says it does not override a project'sdisabledMcpServerslist (issue #14490), so don't disable your automation's servers in/mcp.
Permission scoping
From v2.1.302, a -p run starts in Manual mode when nothing else sets a mode. Any call that needs approval is denied unless an allow rule, a PermissionRequest hook or a permission prompt tool approves it (headless docs). Use allow rules to list exactly which MCP tools the job may call:
mcp__githuballows every tool from thegithubserver.mcp__github__get_issueallows a single tool.
The rule format is described in the permissions docs. Prefer naming single tools for jobs that write anything. Also add --permission-prompts none (v2.1.259 or later). With it, Claude is told nobody can approve, so it stops retrying denied calls, and any MCP elicitation request that no hook answers is cancelled (headless docs). For a complete rule set, see the headless permissions template.
Timeouts that fail fast
| Variable | Default | What it bounds |
|---|---|---|
MCP_TIMEOUT | 30 s | Server startup; with --mcp-config in -p, the first turn waits up to this |
CLAUDE_CODE_MCP_STARTUP_WAIT_MS | (uses the startup wait) | How long the first non-interactive turn waits for servers that are still connecting (v2.1.274+) |
CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT | 5 min network / 30 min stdio | A tool call with no response or progress |
Per-server timeout in JSON | none | Overall tool time for that server |
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS | 120,000 ms | When a long MCP call moves to the background |
Sources: headless docs, env vars, MCP reference.
The last row matters most for cron. After 2 minutes, a long MCP call moves to the background. The headless docs say that when a -p run ends, for a call that automatic backgrounding moved, "the call's result is lost". Setting CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS=0 turns automatic backgrounding off (env vars). Also set CLAUDE_CODE_MCP_ALLOWLIST_ENV=1. Stdio servers then get only a safe baseline environment plus their configured env, instead of inheriting every secret in your shell (env vars).
What happens when a server is unreachable
The run does not crash on its own. An entry that fails validation is skipped and the run "continues and exits cleanly" (headless docs). A server that never connects means its tools are simply missing, so Claude may finish the task without them and still exit 0. Your script has to check for that. The system/init event in stream-json output lists mcp_servers (each with name and status) and mcp_server_errors. A redirected stderr shows no warning, so read these fields instead. Exit code 143 means the process got SIGTERM (headless docs).
The following example wrapper adapts documented flags. Check the status strings your version emits before relying on the filter.
#!/usr/bin/env bash
set -euo pipefail
cd /srv/myproject
export MCP_TIMEOUT=15000
export CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT=120000
export CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS=0
export CLAUDE_CODE_MCP_ALLOWLIST_ENV=1
timeout 20m claude -p "Summarize issues labeled bug opened in the last 24h" \
--mcp-config ./automation.mcp.json --strict-mcp-config \
--allowedTools "mcp__github__list_issues,mcp__github__get_issue" \
--permission-prompts none \
--output-format stream-json --verbose > run.jsonl
# Fail the job if any server is not connected (example filter)
if jq -e 'select(.type=="system" and .subtype=="init")
| (.mcp_server_errors // []) + [.mcp_servers[] | select(.status!="connected")]
| length > 0' run.jsonl >/dev/null; then
echo "MCP server missing; result not trusted" >&2; exit 2
fi
Scheduling, retries and alerting belong in your cron layer. See the cron job setup guide and catching silent failures. For every -p flag and the auth trade-offs, see the headless mode guide.
Next steps
Do this today:
- Run
claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp, thenclaude mcp list. That takes about two minutes and confirms your setup works. - Create
automation.mcp.jsoncontaining only the servers your cron job needs, with pinned versions and${VAR}tokens. - Run the wrapper above once by hand and inspect the
system/initline inrun.jsonlbefore you schedule it.
If you'd rather not run servers yourself: use vendor-hosted remote servers from the Anthropic Directory, so the vendor handles uptime and updates. You still configure scopes and tokens. Claude Code itself requires a paid plan: Pro is $20/month billed monthly ($17/month on annual billing), and Max starts at $100/month (as of October 2026; check the official pricing page). Pro suits one person running a few scheduled jobs. It's a poor fit if you need --bare everywhere, because bare mode needs an API key billed separately through the Claude Console (headless docs).
Related guides on this site:
- Claude Code Headless Mode: Flags, Auth and Cost (2026)
- Claude Code Permissions Best Practices: Headless Template
- Claude Code Cron Job Setup: Run Automations Overnight
- AI Agent Monitoring in Claude Code: Catch Silent Failures
FAQ
What happens if an MCP server becomes unreachable mid-run in Claude Code?
For HTTP servers, Claude Code retries up to 5 times with exponential backoff starting at 1 second. For stdio servers in claude -p, it retries on the next tool call (MCP reference). If the server stays down, that server's tools fail but the run can still exit 0. Check mcp_servers in the system/init event and treat a missing server as a failed job.
Can Claude Code use multiple MCP servers at once?
Yes. List as many as you need under mcpServers in one file. Each server's tool names and instructions load into the context window, though, so remove ones you don't use (quickstart). Tool search reduces that cost when you have many tools (MCP reference).
Where is the Claude Code MCP servers config file on each OS?
Local and user scopes live in ~/.claude.json on macOS and Linux, and in %USERPROFILE%\.claude.json on Windows. Project scope is .mcp.json in the repo root. Run claude mcp get <name> to see which scope holds a server (quickstart).
Is it safe to run Claude Code MCP servers in a cron job without review?
It's reasonably safe only when the job loads a fixed server list (--strict-mcp-config or --bare), allows named MCP tools only, and uses narrowly scoped tokens. Without those, a -p run connects whatever .mcp.json the directory contains, with no approval prompt (headless docs). Servers that read web pages or issues can also carry prompt injection.
Sources
- Claude Code Docs: MCP reference
- Claude Code Docs: Connect to MCP servers (quickstart)
- Claude Code Docs: Run Claude Code programmatically (headless)
- Claude Code Docs: Environment variables
- Claude Code Docs: Configure permissions
- Claude Code Docs: CLI reference
- Anthropic: Remote MCP support in Claude Code
- GitHub: modelcontextprotocol/servers
- GitHub: modelcontextprotocol/servers-archived
- MCP Registry
- Anthropic Directory
- GitHub issue #14490: --strict-mcp-config and disabledMcpServers
- GitHub: steipete/claude-code-mcp
- Claude pricing
Spotted something out of date or wrong? Tell us at shigoto.ai.note@gmail.com. Guides are re-checked against official sources on a rolling schedule.