Claude Lessons / Guides
What Is MCP (Model Context Protocol)? A Practical Guide for Claude Code
MCP gets described in ways that make it sound bigger and vaguer than it is. Strip away the buzzwords: MCP is how Claude Code talks to things that aren't your local files — issue trackers, databases, browsers, internal APIs — through one standard instead of a bespoke integration for each. This guide explains what it actually is, then walks through connecting your first server and fixing the errors you'll actually hit.
What MCP actually is
The Model Context Protocol is an open standard, introduced by Anthropic, for connecting AI assistants to the systems where your data and tools actually live. Before MCP, every integration between an AI tool and an external service was its own one-off implementation. MCP standardizes that connection into a client and server relationship: Claude Code is the client, and an MCP server is anything that speaks the protocol on the other end — Slack, GitHub, Postgres, a browser via Playwright, or a small script you wrote yourself.
The practical effect: instead of Claude only being able to read and edit files in your project, it can query a database, open an issue, drive a real browser, or call an internal API — with your explicit approval at each step, the same permission model that governs file edits and shell commands.
The three things a server can expose
An MCP server can offer any combination of:
- Tools — functions the model can call, like "create a Linear issue" or "run this SQL query."
- Resources — file-like data the client can read, such as a document or a database schema.
- Prompts — pre-written templates that help you accomplish a specific task with that server.
In practice, most of what you'll use day to day are tools: Claude sees them alongside its built-in tools (Read, Bash, and so on) and decides when a task calls for one, asking your permission the first time it uses a new one.
Add your first MCP server
The command is the same shape for any server: add it, check its connection status, then use it. Run this
in your terminal — not inside a claude session, since you're configuring before starting a
conversation:
claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp
Breaking that down:
claude mcp addregisters a server with Claude Code.--transport httpmeans the server lives at a URL rather than running as a local process.claude-code-docsis a name you choose, used to label the server's tools and to reference it later (e.g.claude mcp remove).- The URL is where the server is hosted.
Check that it connected:
claude mcp list
| Status | Meaning |
|---|---|
✔ Connected | Ready to use |
! Connected · tools fetch failed | Connected but couldn't list tools — run claude mcp get <name> for detail |
! Needs authentication | Reachable but needs a browser sign-in or token |
✘ Failed to connect | Server didn't respond |
⏸ Pending approval | A project-scoped server you haven't approved yet — run claude to approve |
Then start a session and use it — you don't usually need to name the server; Claude picks relevant tools on its own:
claude
The first time Claude calls a new server's tool, it asks permission. Approve it, and the tool call in Claude's output is labeled with the server name so you can confirm where the answer came from.
Practice tool use before you wire up real integrations
Claude Lessons has 38 free interactive lessons that simulate a real Claude Code workspace — including lessons on connecting tools and reviewing what an agent does with new capabilities.
Start the free interactive lessonsAdd a local (stdio) server
Some servers run as a program on your machine rather than a hosted URL — useful for tools that need local resources like a browser or a filesystem. The Playwright MCP server is a common one to start with; it needs Node.js 18+ and no account:
claude mcp add playwright -- npx -y @playwright/mcp@latest
There's no --transport flag here, because local servers default to stdio.
Everything after the -- separator is the command Claude Code runs to start the server. The
first connection check can show Failed to connect while npx downloads the
package — wait a moment and check again.
Once connected, give it a real task:
Use playwright to open https://example.com and tell me the page title
Scopes: where servers live on disk
A server's scope controls who it's available to, and it's set at add time:
| Scope | File | Available to |
|---|---|---|
local (default) | ~/.claude.json, under this project's entry | Only you, only this project |
project | .mcp.json in the project root | Everyone who clones the project |
user | ~/.claude.json, top-level mcpServers key | Only you, all projects |
Changing scope means removing the entry and re-adding it at the new one:
# Available in every project, still private to you
claude mcp add --scope user --transport http claude-code-docs https://code.claude.com/docs/mcp
# Shared with your team — commit .mcp.json to git
claude mcp add --scope project --transport http claude-code-docs https://code.claude.com/docs/mcp
Teammates who clone a repo with a committed .mcp.json see a one-time approval prompt before
the server activates for them — a deliberate safeguard so a cloned repo can't silently launch processes
on someone's machine.
You can also write .mcp.json by hand instead of using the CLI:
{
"mcpServers": {
"claude-code-docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp"
},
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
}
}
}
Servers that need sign-in
Hosted services like Sentry, Linear, and Notion run their MCP servers behind OAuth. Add the server, and
claude mcp list shows Needs authentication — that's expected:
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
Inside a session, run /mcp, select the server, and choose Authenticate.
Your browser opens for sign-in; approve it, and the status flips to connected. Servers that use a static
token instead of OAuth take it at add time with --header "Authorization: Bearer <token>".
Troubleshooting connection errors
Run /mcp inside a session or claude mcp list from your shell to see status, then match the symptom:
- "No MCP servers configured" — you likely added the server from a different project directory. Local-scoped servers are tied to the project where you added them; re-add from the current project, or use
--scope userso it isn't tied to one. - "Failed to connect" (HTTP server) — check the URL is reachable:
curl -I <url>. A404/405usually means the server is up but many endpoints only answer POST, so this still confirms reachability. A401/403means you need to authenticate. No response at all means a network or URL problem. - "Failed to connect" (stdio server) — run the configured command directly in your terminal. If it starts and waits for input, the server itself works — check that the command Claude Code has stored (
claude mcp get <name>) matches. If it errors, the message usually names what's missing, like Node.js. - Connection timed out at startup — a slow
npxdownload on first run can exceed the default 30-second timeout. Raise it:MCP_TIMEOUT=60000 claude. - Server connects but no tools appear — usually a missing required environment variable, like an API key. Pass it with
--env KEY=valueonclaude mcp add. - Changes to .mcp.json don't take effect — Claude Code reads it at session start; restart the session. If you previously declined the approval prompt, run
claude mcp reset-project-choices.
Should you build your own server?
Not as a first step. Hosted MCP servers already exist for most common tools — GitHub, Slack, Linear, Notion, Sentry, Google Drive, Postgres, and more — in Anthropic's directory of MCP servers. Add one of those and confirm the workflow before building anything.
Build a custom server only when you need to expose something no existing server covers: an internal API, a proprietary database schema, a company-specific tool. The MCP SDK documentation covers building a server from scratch once you've decided you need one.
A word on security
Each connected server adds its tool names and descriptions to every session's context, and each new tool
call still goes through the same permission prompt as a file edit or shell command — approve tool use
you don't recognize with the same scrutiny you'd give a shell command. Remove servers you're not
actively using (claude mcp remove <name>) to keep both your context window and your
tool surface smaller. For a project shared via .mcp.json, remember teammates get a one-time
approval prompt precisely so a cloned repo can't silently run processes on their machine — don't train
people to blindly click through it.
FAQ
What is MCP (Model Context Protocol)?
MCP is an open standard, created by Anthropic, that lets AI assistants like Claude connect to external tools, data sources, and services through one consistent protocol instead of a custom integration per tool. An MCP server exposes resources, tools, and prompts; an MCP client, like Claude Code, connects to it and uses what it exposes.
How do I add an MCP server to Claude Code?
Run claude mcp add from your terminal, outside a session. For a hosted server reached over a
URL, use claude mcp add --transport http <name> <url>. For a local server run as
a subprocess, use claude mcp add <name> -- <command>. Then run
claude mcp list to confirm it shows Connected.
Where are MCP servers configured on disk?
It depends on scope. Local scope (the default, private to you and one project) and user scope (private
to you, all projects) both live in ~/.claude.json. Project scope, meant to be committed and
shared with your team, lives in .mcp.json at the project root.
Is MCP the same as a Claude Code plugin?
No. MCP servers give Claude new tools and data access — a database connection, an issue tracker, a browser. Plugins can bundle MCP servers along with subagents, hooks, skills, and slash commands, but MCP itself is just the protocol for the tool-and-data layer.
Why does my MCP server show "Failed to connect"?
For a local (stdio) server, run its configured command directly in your terminal — the error it throws there is the real problem, usually a missing dependency like Node.js. For a hosted (HTTP) server, curl -I the URL: a 401/403 means you need to authenticate, a 404/405 usually means the server is up but the endpoint path is wrong, and no response at all means a network or URL problem.
Do I need to build my own MCP server?
Usually not to start. Hosted MCP servers already exist for GitHub, Slack, Linear, Notion, Sentry, Google Drive, and many other tools — add those first. Build a custom server only when you need to expose your own internal API, database, or proprietary tool that no existing server covers.
Reading about it ≠ being good at it
The fastest way to build good habits around tool use and permissions is reps. Practice reviewing new capabilities, approving tool calls deliberately, and verifying results in a simulated Claude Code workspace — free, in your browser, with instant feedback.
Practice hands-on in the free interactive lessons