Prelude

The first time we connected an MCP server to Claude Code, the goal was mundane: query a Postgres database while working through a migration, without switching between terminals. Claude Code was open in one pane, a psql session in another, and a browser with the schema docs in a third. It was functional but fractured.

The Model Context Protocol came up in a thread about AI tooling. After confirming that Claude Code supported it natively, a database MCP server was running within fifteen minutes. Claude could query the schema directly. No terminal switching. No copy-pasting query results.

That was the moment MCP servers clicked. They are not plugins in the traditional sense. They are not extensions bolted onto the side of an application. They are a communication protocol that lets Claude Code talk to any external system through a standardised interface. Databases, APIs, file systems, monitoring tools, deployment pipelines. If something exposes an MCP server, Claude Code can use it as naturally as it reads files or runs shell commands.

At systemprompt.io, we have spent months building on top of this. MCP servers form the backbone of how our AI agents interact with external services. This guide covers everything we have learned about configuring them in Claude Code, from the first claude mcp add command through to enterprise-grade managed configurations and custom subagents.

The Problem

Claude Code is remarkably capable out of the box. It reads files, writes code, runs commands, searches codebases. For a self-contained development workflow, that is often enough. But real projects do not live in isolation.

Your application talks to a database. Your team communicates through Slack. Your infrastructure runs on AWS or GCP. Your issues live in Linear or Jira. Your documentation lives in Notion or Confluence.

Without MCP servers, interacting with these systems from Claude Code means one of two things. Either you shell out to CLI tools (which works but is brittle and verbose) or you leave Claude Code entirely and context-switch to another application. Both approaches break the flow of conversation. You lose the thread of what you were doing.

MCP servers solve this by giving Claude Code a structured way to interact with external tools. The Model Context Protocol is an open standard developed by Anthropic for connecting AI models to external data sources and tools. It defines a client-server architecture where Claude Code acts as the client and external services expose capabilities through a well-defined API.

Each MCP server declares what tools it offers, what inputs they expect, and what outputs they produce. Claude Code discovers these tools at startup and can call them during a conversation just like it calls its built-in tools.

The protocol handles serialisation, error handling, and lifecycle management. You do not need to write glue code or build custom integrations. If an MCP server exists for the service you need, connecting it is a configuration change, not a development project.

The practical difference is significant. Instead of asking Claude to "run this SQL query and tell me what it says", you ask Claude to "check how many users signed up this week" and it calls the database tool directly, interprets the results, and continues the conversation. Instead of saying "look at the latest Sentry errors", you ask Claude to "find any new exceptions related to the payment module" and it queries your error tracking system in context.

This guide walks through how to set all of that up.

The Journey

Understanding MCP Transports

MCP servers communicate with Claude Code through one of three transport mechanisms. The transport determines how messages are exchanged between Claude Code and the server process.

stdio is the transport for local MCP servers. Claude Code spawns the server as a child process and communicates over standard input and output. This is the simplest setup. The server runs on your machine, starts and stops with your Claude Code session, and has access to your local file system and network. Most community MCP servers use stdio.

claude mcp add --transport stdio my-database -- npx @modelcontextprotocol/server-postgres postgresql://localhost:5432/mydb

That command registers a stdio MCP server called my-database. When Claude Code starts, it spawns npx @modelcontextprotocol/server-postgres with the connection string as an argument. The server exposes tools for querying the database, and Claude Code discovers them automatically.

HTTP is the recommended transport for remote MCP servers. It uses a streamable HTTP connection where Claude Code sends requests and receives responses over standard HTTP. This is the transport you want for hosted MCP services, shared team servers, or any server that runs on infrastructure you do not manage directly.

claude mcp add --transport http my-remote-server https://mcp.example.com/v1

HTTP transport supports OAuth authentication, covered shortly below. It is the direction the ecosystem is moving, and if you are building or choosing MCP servers today, HTTP should be your default for anything remote. For guidance on taking MCP servers from development to reliable infrastructure, our guide on deploying MCP servers to production covers transport selection, containerisation, and operational concerns.

SSE (Server-Sent Events) was the original transport for remote MCP servers. It uses a persistent HTTP connection with server-sent events for streaming responses. As of early 2026, SSE is deprecated in favour of HTTP transport. It still works, and you will find many existing MCP servers that use it, but new implementations should use HTTP. Claude Code treats SSE as a legacy option.

claude mcp add --transport sse my-legacy-server https://mcp.example.com/sse

A typical progression starts with a stdio server for Postgres, which takes about thirty seconds to set up. Next might come an HTTP server for a team's shared knowledge base, which takes slightly longer because it involves OAuth. Then an SSE server for an older monitoring tool that has not yet migrated. All three work from within the same Claude Code session, and Claude can use tools from any of them interchangeably.

Installing and Managing MCP Servers

The claude mcp command handles all MCP server management. The subcommands are straightforward.

# Add a stdio server
claude mcp add --transport stdio github-mcp -- npx @modelcontextprotocol/server-github

# Add an HTTP server
claude mcp add --transport http analytics-server https://analytics.example.com/mcp

# List all configured servers
claude mcp list

# Get details about a specific server
claude mcp get my-database

# Remove a server
claude mcp remove my-database

You can also set environment variables for a server at registration time. This is useful for servers that need API keys or configuration values.

claude mcp add --transport stdio my-server -e API_KEY=your-api-key-here -e REGION=eu-west-1 -- npx some-mcp-server

Within a running Claude Code session, you can manage MCP servers interactively using the /mcp slash command. This opens a panel showing all connected servers, their status, and available tools. You can restart a server that has crashed, disconnect one you no longer need, or authenticate with a remote server that requires OAuth.

Scopes and Where Configuration Lives

Every MCP server you add has a scope that determines where its configuration is stored and who can see it. This is one of those details that seems minor until you are working in a team and someone asks why their Claude Code session does not have the database server you set up yesterday.

Local scope is the default. When you run claude mcp add, the server configuration is stored in your personal settings for the current project. Nobody else on the team sees it. It does not get committed to version control. This is right for personal tooling, experimental servers, or anything that uses your personal credentials.

Project scope stores the configuration in a .mcp.json file at the root of your project. This file is meant to be committed to version control. Everyone who clones the repository gets the same MCP server configuration.

claude mcp add --scope project shared-db -- npx @modelcontextprotocol/server-postgres $DATABASE_URL

The .mcp.json file looks like this.

{
  "mcpServers": {
    "shared-db": {
      "type": "stdio",
      "command": "npx",
      "args": ["@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    },
    "team-api": {
      "type": "http",
      "url": "https://mcp.team-tools.example.com/v1"
    }
  }
}

Notice the ${DATABASE_URL} syntax. Project-scoped servers can reference environment variables without hardcoding secrets. Each developer sets the variable in their own environment, and the .mcp.json file stays safe to commit.

User scope stores the configuration globally for your user account, across all projects. Use this for MCP servers you want available everywhere, like a personal knowledge base or a general-purpose utility server.

claude mcp add --scope user my-notes -- npx @modelcontextprotocol/server-notes ~/notes

Local scope works well for most things. Project scope suits shared team infrastructure. User scope fits the handful of servers you want available in every project regardless of context. The discipline of choosing the right scope saves confusion later.

OAuth Authentication for Remote Servers

Remote MCP servers often require authentication. The HTTP transport supports OAuth natively. When you connect to a server that requires OAuth, Claude Code handles the flow for you.

The first time you use a server that needs authentication, the /mcp command in Claude Code will prompt you to authorise. This opens a browser window with the OAuth consent screen. You authenticate, grant permissions, and the token is stored securely. Subsequent sessions reuse the token until it expires.

This matters because it means you can connect to company-internal MCP servers that sit behind SSO. The server implements OAuth, Claude Code handles the client-side flow, and your existing identity provider handles the rest. No API keys to rotate. No credentials in configuration files.

For servers that use simpler authentication, you can pass tokens as environment variables.

claude mcp add --transport http my-api -e AUTH_TOKEN=your-token-here https://api.example.com/mcp

Plugin-Provided MCP Servers

Some Claude Code plugins bundle their own MCP servers. When you install one of these plugins, the MCP server is managed automatically. It starts when Claude Code starts, stops when Claude Code stops, and updates when the plugin updates.

Plugin-provided MCP servers have access to a CLAUDE_PLUGIN_ROOT environment variable that points to the plugin's installation directory. This lets the server find its configuration files and assets without hardcoded paths.

The lifecycle management is the key advantage here. With a manually configured MCP server, you are responsible for ensuring the server process is running, updating it when new versions are released, and debugging it when it crashes. With a plugin-provided server, the plugin system handles all of that. You install the plugin and the tools appear.

Plugin-provided servers are particularly useful for services that require complex setup. A Kubernetes MCP server, for instance, needs cluster credentials, context configuration, and namespace defaults. Wrapping all of that in a plugin means the setup happens once and works consistently.

Custom Subagents

This is where MCP servers connect to something larger. Claude Code supports custom subagents, which are specialised AI agents that have their own tool access, model selection, and permissions. Subagents let you create focused assistants within your Claude Code environment.

A subagent is defined as a markdown file with YAML frontmatter. You place it in .claude/agents/ for project-specific agents or ~/.claude/agents/ for agents available across all projects. The markdown body becomes the agent's system prompt, and the frontmatter configures its capabilities.

Here is a subagent designed for database work.

---
name: "database-assistant"
description: "Queries and analyses the application database. Use for data questions, schema exploration, and migration planning."
tools:
  - "mcp:shared-db:query"
  - "mcp:shared-db:list_tables"
  - "mcp:shared-db:describe_table"
  - "Read"
model: "sonnet"
permissionMode: "default"
---

You are a database specialist. When asked about data or schema questions, use the database tools to query directly rather than guessing.

Always check the current schema before suggesting migrations. Use `describe_table` to verify column types and constraints.

When writing queries, prefer COUNT and aggregation for overview questions. Only return raw rows when specifically asked.

Never run DELETE, DROP, or TRUNCATE operations. If asked to modify data, write the query but do not execute it. Present it for review instead.

The tools field controls which tools the subagent can access. The mcp:shared-db:query syntax means "the query tool from the MCP server named shared-db". You can also reference built-in tools like Read, Bash, Edit, and Write. If you omit the tools field entirely, the subagent gets access to all available tools.

The model field selects which Claude model the subagent uses. Your options are sonnet, opus, haiku, or inherit. The inherit option uses whatever model the parent session is running.

sonnet works well for most subagents because it is fast and capable. For complex reasoning tasks, opus is the better choice. For high-volume, low-complexity work like code exploration, haiku keeps costs down.

The permissionMode field controls how the subagent handles tool permissions. Valid values are default (same permission rules as the parent session), acceptEdits (auto-accepts file edits but prompts for other tools), dontAsk (never prompts, skips disallowed tools), bypassPermissions (allows all tools without prompting), and plan (read-only mode for planning and analysis).

Other configuration options include hooks (to attach event-driven workflows to the subagent), skills (to reference registered skills the agent can use), and memory (to define persistent context the agent carries between invocations).

You invoke a subagent from Claude Code by referencing it in conversation. Type /agents to see available agents, or simply ask Claude to delegate to a specific agent. Claude Code manages the handoff, passes context, and returns the result to your main conversation.

Built-in Subagents

Claude Code ships with three built-in subagents that cover common patterns. Understanding these helps you design your own.

Explore is a read-only agent that uses the Haiku model. It is designed for codebase exploration, answering questions about project structure, finding relevant files, and summarising code. It cannot modify files or run commands. Because it uses Haiku, it is fast and inexpensive. It works especially well for orientation in unfamiliar codebases.

Plan is a read-only agent that inherits the parent model. It reads files and analyses code but cannot make changes. It is designed for planning work, creating implementation outlines, and identifying dependencies. The inherited model means it gets the same reasoning power as your main session.

The general-purpose subagent inherits the parent model and has access to all tools. This is the default delegation target when Claude Code decides it needs to break a task into subtasks. It can read, write, execute, and call any configured MCP server. It is essentially a fresh Claude Code session scoped to a specific task.

The recommended pattern is to use the built-in agents for general work and create custom subagents for specialised domains. A database assistant only sees database tools. A documentation agent only sees file reading and writing tools. A deployment agent only sees infrastructure tools. The narrower the tool access, the more focused and reliable the subagent becomes.

As you add more MCP servers, the number of available tools grows. A Postgres server might expose five tools. A GitHub server might expose twenty. A Kubernetes server might expose thirty. Connect all three and you have fifty-five tools competing for space in Claude's context window.

Claude Code handles this with an automatic tool search mechanism. When the total number of available tools exceeds roughly ten percent of the context window, Claude Code activates tool search. Instead of loading every tool description into the context, it loads a search index. When Claude needs a tool, it searches the index first, then loads the relevant tool descriptions on demand.

This is transparent to you as a user. You do not need to configure anything. But it is worth knowing about because it affects how you name and describe your MCP server tools.

Clear, descriptive tool names and descriptions make the search more effective. If your custom MCP server has a tool called do_thing, Claude will struggle to find it. If it is called query_user_signups_by_date_range, Claude finds it immediately. When building your own MCP server, invest time in naming tools clearly from the start.

This becomes apparent quickly with generic tool names like fetch, update, and list. Claude often picks the wrong tool because the names are ambiguous. Renaming them to fetch_customer_record, update_billing_address, and list_recent_orders fixes the problem entirely.

Enterprise MCP Management

For organisations running Claude Code across development teams, managing MCP servers at scale requires more than individual configuration. Claude Code provides enterprise-grade controls through managed settings that let administrators define which MCP servers are available, required, or prohibited.

The managed-mcp.json file is the enterprise configuration surface. Administrators deploy this file to control MCP server availability across the organisation. It sits alongside the managed settings file and follows a similar structure.

{
  "mcpServers": {
    "company-knowledge-base": {
      "type": "http",
      "url": "https://kb.internal.example.com/mcp",
      "description": "Internal knowledge base and documentation search"
    },
    "approved-database": {
      "type": "stdio",
      "command": "npx",
      "args": ["@company/db-mcp-server"],
      "env": {
        "DB_HOST": "readonly-replica.internal.example.com"
      }
    }
  }
}

The managed MCP servers appear automatically in every developer's Claude Code session. Developers cannot remove or modify them. They can add their own servers alongside the managed ones, unless the administrator restricts that.

For granular control, administrators can use allowedMcpServers and deniedMcpServers lists. The allowed list acts as an allowlist: only servers whose names match can be added. The denied list acts as a denylist: servers whose names match are blocked.

These use pattern matching, so you can allow company-* to permit any server with the company prefix while blocking everything else. To lock down the environment completely, set allowedMcpServers to an empty array, which prevents developers from adding any MCP servers beyond the managed configuration.

{
  "allowedMcpServers": ["company-*", "approved-*"],
  "deniedMcpServers": ["*-experimental"]
}

This layered approach means you can mandate certain servers (via managed-mcp.json), allow a curated set of additional servers (via allowedMcpServers), and block specific known-bad patterns (via deniedMcpServers). The combination covers most enterprise governance requirements without being so restrictive that developers cannot work effectively.

Security Considerations

MCP servers that make network requests introduce a security surface. A malicious or misconfigured MCP server could exfiltrate data, connect to unintended services, or make requests that violate network policies. For a detailed treatment of authentication and security patterns, see the guide on MCP server authentication and security.

The combination of managed MCP servers, allowedMcpServers, and deniedMcpServers gives administrators layered control. They know exactly which MCP servers are running and exactly which tools those servers expose.

For additional protection, scope each MCP server's credentials to the minimum required access. A database MCP server should connect to a read-only replica, not the primary. An API MCP server should use a token with the narrowest possible permissions.

For compliance-heavy industries, this level of control is not optional. For everyone else, it is still good practice. The full details of enterprise lockdown are covered in the managed settings guide.

Putting It All Together

Here is the MCP setup we use daily at systemprompt.io. This is a real configuration, not a contrived example.

The .mcp.json (project scope, committed to the repository) looks like this.

{
  "mcpServers": {
    "project-db": {
      "type": "stdio",
      "command": "npx",
      "args": ["@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    }
  }
}

Local-scope servers (not committed) include a GitHub MCP server with a personal access token and a file search server configured for the monorepo structure.

Three custom subagents live in .claude/agents/.

The database-assistant (shown earlier) handles all data queries and migration planning. It uses Sonnet and only has access to database tools.

A review-agent that reads code and runs analysis but cannot modify anything. It uses the inherited model and has Read, Glob, Grep, and Bash tools. Its system prompt instructs it to focus on code quality, security issues, and architectural concerns.

A deploy-agent that has access to our infrastructure MCP server and can check deployment status, view logs, and trigger staging deployments. It uses Sonnet and has strict permissions. Its system prompt prohibits production deployments and requires confirmation for any mutating operation.

Each agent has a clear boundary. The database assistant does not know about deployments. The deploy agent does not see the database. The review agent cannot change anything. This separation makes each agent more reliable because it cannot be confused by tools outside its domain.

We also use hooks alongside MCP servers. A PostToolUse hook logs every MCP tool invocation to a local file, providing an audit trail of what was queried and when. A PreToolUse hook on the deploy agent requires confirmation for any tool call that contains the word "production" in its arguments.

Troubleshooting Common MCP Issues

MCP servers occasionally fail to connect or behave unexpectedly. These are the most common issues and how to resolve them.

Server fails to start. Run claude mcp list and check the server status. If it shows as disconnected, the server process likely crashed on startup. Run the server command manually in a terminal (for example, npx @modelcontextprotocol/server-postgres postgresql://localhost:5432/mydb) to see the error output directly. Missing dependencies and incorrect connection strings are the usual culprits.

Tools not appearing. If a server shows as connected but its tools do not appear, restart it with the /mcp slash command in Claude Code. If tools still do not appear, the server may not be declaring them correctly. Use claude mcp get <server-name> to inspect the tool list.

Permission prompts reappearing. Claude Code remembers your tool approval choices per project. If you want to reset these choices and start fresh, run claude mcp reset-project-choices. This is useful when you have denied a tool by mistake or when a server has updated its tool definitions.

OAuth token expired. For HTTP servers using OAuth, an expired token causes authentication failures. Open the /mcp panel in Claude Code and re-authenticate with the affected server. The OAuth flow will refresh your token.

Server crashes mid-session. If a server crashes during a conversation, Claude Code will show an error when it tries to use that server's tools. Use the /mcp command to restart the server without leaving your session. Your conversation context is preserved.

The Lesson

MCP servers transform Claude Code from a code assistant into a development environment that can interact with your entire technology stack. But the real lesson is not about the technology. It is about boundaries.

The most effective MCP setups share three characteristics. They are specific in scope. They have clear permissions. They separate concerns through subagents.

The least effective setups connect everything to everything. Every MCP server available to every conversation, every tool accessible from every context. That approach leads to confused tool selection, accidental data access, and security blind spots.

Start with one MCP server that solves a real friction point. For most developers, that is a database server or a project management tool. Get comfortable with how it integrates into your workflow. Then add a second. Then consider whether a custom subagent would help focus the interaction.

For enterprise teams, invest in the managed configuration early. Setting up managed-mcp.json before developers start adding their own servers is far easier than retroactively locking things down. The enterprise managed settings guide covers the full configuration surface.

The Model Context Protocol is an open standard. The ecosystem of available servers is growing rapidly. As of early 2026, there are community servers for most major databases, cloud providers, communication tools, and development platforms. The official MCP documentation maintains a registry of available servers, and the subagents documentation covers the full configuration surface for custom agents.

Conclusion

This guide began with a three-pane terminal setup. Database in one, Claude Code in another, documentation in a third. That setup still works. But it is no longer how we work.

Our current setup is a single Claude Code session with MCP servers connected to the database, the project management tool, and the infrastructure. Custom subagents handle specialised tasks. Hooks log everything and enforce policies.

The result is not just more efficient. It is more coherent. Every interaction happens within the same context, and Claude can draw connections between a database query result, a code change, and a deployment status without manually bridging the gaps.

The Model Context Protocol is the layer that makes this possible. Not because the technology is particularly complex (it is a fairly straightforward client-server protocol) but because it standardises the interface between AI and tools. That standardisation means you set up the connection once and every future conversation benefits from it.

Connect your first MCP server today. The claude mcp add command takes thirty seconds. The productivity difference compounds from the first session.