Claude Code MCP Server Setup: Complete Guide
Claude Code MCP Server Setup: What You Actually Need to Know
If you're trying to get Claude Code working with an MCP server, you've probably already hit one of two walls: either the documentation is sparse on production details, or you've wired everything together and realized you have no control over what your agent can actually do once it's connected. This guide covers both — the mechanical claude code mcp server setup process and the governance layer you need before running agents against real systems.
Model Context Protocol (MCP) is Anthropic's open standard for connecting AI models to external tools and data sources. Claude Code, Anthropic's terminal-based coding agent, ships with native MCP support. That combination is genuinely powerful — but "powerful" without guardrails is just "dangerous at scale." By the end of this article you'll have a working MCP server connected to Claude Code, and you'll understand the permission and audit infrastructure required to run it responsibly.
What Is MCP and Why Claude Code Uses It
MCP defines a client-server protocol where an AI model (the client) communicates with external capability providers (the servers). Each MCP server exposes a set of tools — functions the model can call — along with resources and prompts. Claude Code acts as an MCP client, discovering and calling these tools during task execution.
Before MCP, connecting an LLM to external systems meant writing custom function-calling glue code for every integration. MCP standardizes that interface so a single server implementation can serve multiple AI clients. According to Anthropic's documentation, Claude Code can connect to multiple MCP servers simultaneously, composing capabilities from across them into a single agent session.
Common MCP server use cases with Claude Code include:
- File system access (reading/writing project files beyond the working directory)
- Database query execution
- Web search and scraping
- GitHub and version control operations
- Running shell commands in controlled environments
- Fetching external API data (weather, financial markets, B2B contact data)
For a deeper background on MCP itself, see our explainer on what is MCP (Model Context Protocol).
Claude Code MCP Server Setup: Step-by-Step
Claude Code manages MCP servers through a JSON configuration file. Here's how to set one up from scratch.
Step 1: Locate or Create the MCP Configuration File
Claude Code reads MCP server definitions from a configuration file. As of the current release, the file lives at:
- macOS/Linux:
~/.config/claude/claude_desktop_config.json(for the desktop app) or project-level.claude/settings.json - Project-scoped config:
.mcp.jsonin your project root (added in recent Claude Code versions)
Project-scoped configuration is preferred for team environments because it can be committed to version control, giving every developer the same tool set.
Step 2: Define Your MCP Server Entry
MCP servers are defined as either stdio (subprocess) or sse (HTTP Server-Sent Events) transports. The stdio transport is most common for local development:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
"env": {}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_yourtoken"
}
}
}
}
For an HTTP-based MCP server (SSE transport), use:
{
"mcpServers": {
"my-remote-server": {
"type": "sse",
"url": "https://your-mcp-server.example.com/sse",
"headers": {
"Authorization": "Bearer your-api-key"
}
}
}
}
Step 3: Verify the Server Loads in Claude Code
Start Claude Code in your project directory with claude. Run /mcp to list connected servers and their status. A green indicator means the server handshake succeeded and tools are available. If a server fails to connect, Claude Code shows the subprocess exit code — the most common causes are missing Node.js/Python runtimes, wrong paths, or missing environment variables.
Step 4: Test Tool Discovery
Ask Claude Code to list the tools it sees: "What tools do you have available from the filesystem server?" It should enumerate the available functions (e.g., read_file, write_file, list_directory). This confirms that tool schemas are being passed correctly during the MCP initialization handshake.
Step 5: Run a Scoped Test Task
Before pointing your agent at production systems, run a bounded task. For a filesystem server: "Read the README.md in this directory and summarize it." For a GitHub server: "List the open pull requests on this repo." Watch for unexpected tool calls — if the agent tries to call tools outside the scope of your request, that's a signal you need tighter permission controls.
MCP Server Options: Hosted vs. Self-Built vs. Managed
Not all MCP servers are equal. Here's a breakdown of the main approaches for teams connecting Claude Code to real capabilities:
| Approach | Setup Effort | Maintenance | Governance | Best For |
|---|---|---|---|---|
Open-source community servers (e.g., @modelcontextprotocol/*) |
Low | Self-managed | None built-in | Local dev, prototyping |
| Self-built stdio server | High | High | Custom | Proprietary internal tools |
| Self-hosted control plane (e.g., DashClaw, AgentControl) | Medium | Medium | Partial | Teams wanting infra control |
| Managed MCP + governance platform (e.g., Handler) | Low | None | Full (rules, audit, approvals) | Production agent deployments |
| Vendor-locked MCP governance (e.g., Speakeasy) | Low-Medium | Low | Partial (MCP-scoped only) | API producers managing MCP exposure |
The open-source community servers under @modelcontextprotocol are excellent for getting started. They cover filesystem, GitHub, Postgres, Brave Search, and a growing list of integrations. The gap is governance: there's no built-in mechanism to restrict which tools Claude Code can call, audit what it did, or require human approval before sensitive operations execute.
Self-hosted options like DashClaw and AgentControl give you a runtime control plane, but both require you to operate the infrastructure yourself. See our comparison of AgentControl alternatives for production-ready governance and the DashClaw alternative guide for a detailed breakdown of where self-hosted falls short under production load.
Claude Code MCP Server Setup for Production: The Governance Gap
Getting an MCP server running locally takes about 10 minutes. Getting it production-ready takes significantly longer — because the mechanical connection is the easy part.
Here's what breaks in production without deliberate governance design:
Credential Sprawl
Each MCP server needs credentials — GitHub tokens, database passwords, API keys. In a .mcp.json file, those are plaintext environment variable references. Developers hardcode them. Tokens get committed. Rotation is manual. According to GitGuardian's 2024 State of Secrets Sprawl report, 12.8 million secrets were detected in public GitHub repositories in 2023 alone — and MCP server configs are a new vector for exactly this kind of leak.
No Operation-Level Control
MCP tool access is binary: the server is connected or it isn't. There's no built-in way to say "Claude Code can call read_file but not write_file," or "database reads are fine but no DROP statements." Without operation-level rules, you're trusting the model's judgment for every action — which is fine in development and dangerous in production.
No Audit Trail
If Claude Code deletes a file, modifies a database record, or sends a network request through an MCP server, there's no built-in log. You won't know it happened unless you catch it in application-level logs after the fact. For regulated industries, this is a compliance blocker. For everyone else, it's a debugging nightmare. Our guide on AI agent audit trails covers what a proper audit trail for agents should include.
No Human-in-the-Loop
Some operations warrant a human approval step before execution — sending an email, deleting data, making a financial transaction. Standard MCP has no mechanism for this. The agent calls the tool; the tool executes. You need an approval layer sitting between the two.
Adding Governance to Your Claude Code MCP Setup
The right approach is to add a governance layer between Claude Code and your MCP servers — one that enforces rules at the operation level, not just at the network level.
What Operation-Level Governance Looks Like
Operation-level governance means defining rules per tool call, not per connection. Examples:
- Allow
filesystem.read_fileon/project/**, deny on/etc/** - Allow
github.list_pull_requests, require approval forgithub.merge_pull_request - Allow
database.querywithSELECTstatements, block any query containingDROPorDELETE - Rate-limit
web.searchto 100 calls per hour
This is the model that Handler implements. Handler acts as a managed MCP server and governance layer simultaneously — you connect Claude Code to Handler's MCP endpoint, define your rules in the Handler dashboard or via API, and Handler enforces them on every tool call. It also ships with 200+ pre-built integrations (web search, email, B2B data, financial markets, and more) so you're not building capability servers from scratch.
The difference from approaches like Speakeasy (which focuses on MCP governance for API producers) is scope: Handler governs agent actions across any connected service, not just MCP traffic, and it's not locked to a single vendor's API ecosystem. For a full comparison, see our Speakeasy MCP alternative guide.
Structuring Your MCP Config for Governance
If you're adding a governance proxy in front of your MCP servers, the Claude Code config change is minimal — you point to the proxy endpoint instead of the upstream server:
{
"mcpServers": {
"handler": {
"type": "sse",
"url": "https://mcp.usehandler.dev/sse",
"headers": {
"Authorization": "Bearer your-handler-api-key"
}
}
}
}
From Claude Code's perspective, it's talking to one MCP server. The governance layer handles routing to the correct underlying capability, enforcing your rules, logging every call, and surfacing approval requests when needed.
Managing Credentials Safely
Rather than embedding credentials in your MCP config file, use a secrets manager or environment variable injection at runtime. For team deployments:
- Store API keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler)
- Inject them as environment variables in your CI/CD pipeline, not in committed config files
- Use short-lived tokens with automatic rotation where the upstream service supports it
- Scope tokens to minimum required permissions — a GitHub token for reading PRs doesn't need
repo:write
Handler's credential management abstracts this: you store your upstream credentials in Handler once, and the MCP server uses Handler's own scoped tokens for each agent session — so you're not distributing raw API keys to every developer's config file.
Testing Your MCP Setup Before Going Live
A structured pre-production checklist saves you from the category of incident that's embarrassing to explain to stakeholders.
Functional Testing
- Verify every tool in the server's schema is callable and returns expected output
- Test error handling: what does Claude Code do when a tool returns an error?
- Confirm tool descriptions are accurate — LLMs rely on tool descriptions to decide when to call them
Permission Testing
- Attempt operations that should be blocked and confirm they're denied
- Verify rate limits trigger correctly under load
- Confirm approval flows work end-to-end (request → notification → approve/deny → execution or cancellation)
Audit Verification
- Execute a known set of tool calls and verify they all appear in your audit log
- Check that log entries include: timestamp, tool name, arguments, agent identity, result, and latency
- Test that denied operations log the denial with the rule that triggered it
For broader guidance on what production-ready governance looks like, the article on how to govern AI agents in production covers the full control plane architecture.
Common Claude Code MCP Server Setup Errors
These are the issues that cost teams the most debugging time:
| Error | Likely Cause | Fix |
|---|---|---|
Server shows as disconnected in /mcp |
Missing runtime (Node/Python), wrong command path, or missing env vars |
Run the command manually in terminal to see the raw error |
| Tools appear but calls always fail | Missing or invalid credentials in env block |
Verify the env var name matches what the server expects |
| Agent ignores available tools | Tool descriptions are vague or misleading | Improve tool description strings in your server implementation |
| Subprocess crashes on first call | Server dependencies not installed | Run npx -y or pre-install the package globally |
| SSE connection drops intermittently | Network timeout, missing keep-alive, or server memory leak | Add reconnection logic; check server health endpoint |
| Config file changes not picked up | Claude Code caches server config at startup | Restart Claude Code after any config change |
Frequently Asked Questions
What's the difference between stdio and SSE MCP transports in Claude Code?
stdio transport spawns a subprocess on your local machine — Claude Code starts the MCP server process and communicates over stdin/stdout. It's simple for local development but doesn't work for remote or shared servers. sse (Server-Sent Events) transport connects to an HTTP endpoint, making it suitable for hosted or team-shared MCP servers. For production deployments, SSE is almost always the right choice because it allows centralized governance, logging, and credential management.
Can I run multiple MCP servers with Claude Code at the same time?
Yes. Claude Code supports multiple concurrent MCP server connections. Define each server as a separate entry in your mcpServers config object. Claude Code will discover and aggregate tools from all connected servers, presenting them as a unified tool set. Name conflicts (two servers exposing a tool with the same name) are resolved by prefixing tool names with the server name.
How do I restrict which tools Claude Code can call on an MCP server?
Standard MCP has no built-in mechanism for this — if the server is connected, all its tools are available to the model. To restrict access at the tool or operation level, you need a governance layer. Options include building a custom proxy that filters tool calls before forwarding them, using a managed platform like Handler that enforces per-operation rules, or implementing tool-level access control in your own MCP server code.
Is it safe to commit my .mcp.json file to version control?
The config file structure is safe to commit. The credentials referenced in the env block are not. Use environment variable references (e.g., "GITHUB_TOKEN": "${GITHUB_TOKEN}") and inject actual values via your shell environment, CI/CD secrets, or a secrets manager. Never hardcode API keys, database passwords, or OAuth tokens in a committed file.
What should I do before connecting Claude Code to a production database via MCP?
At minimum: (1) use a read-only database user for any MCP server that only needs to query data, (2) implement query allow-listing to block destructive statements, (3) set up audit logging so every query is recorded with the agent session that triggered it, and (4) consider requiring human approval for any write operation. The broader question of agent access control is covered in our AI agent access control security guide.
Ready to govern your AI agents?
Handler gives your agents superpowers with built-in governance. Start in minutes.
Get Started Free