MCP quickstart
Connect your first MCP server to Claude Code, confirm it works, find where the config lives and fix the usual connection problems.
The Model Context Protocol (MCP) is how Claude Code picks up tools it does not have out of the box: reading your issue tracker, querying a database, driving a browser. Those tools come from MCP servers, which either run as a program on your machine or sit behind a URL.
This page takes one server from nothing to working, then shows the two other common shapes (a local process and a server behind a sign-in). For every option and flag, see the full MCP guide.
Note: You can also add servers from the desktop app, VS Code and cloud sessions. See Other ways to connect.
What you need
- Claude Code installed and signed in (see the quickstart)
- A terminal in any project folder, even an empty one
Your first server: hosted, no sign-in
I like to test the flow with a public server that needs no credentials. DeepWiki runs one that answers questions about public GitHub repositories, so it is a good first target. The steps are identical for any server: add, check, use, and optionally remove.
1. Add it
Run this from your normal shell, not inside a claude session:
claude mcp add --transport http deepwiki https://mcp.deepwiki.com/mcp
Reading it left to right:
| Part | Meaning |
|---|---|
claude mcp add | Register a server |
--transport http | It lives at a URL rather than running as a local process |
deepwiki | A label you choose. It prefixes the server's tools in Claude's output and is how you refer to it in later commands |
| The URL | Where the server is hosted |
You get a confirmation along the lines of Added HTTP MCP server deepwiki with URL: ... to local config, plus a File modified: line naming the file written. "Local config" means it is registered for you, in this project only. Open Claude in another project and it will not be there. Changing scope covers making it global or shared.
2. Check the status
claude mcp list
| Status | What it means |
|---|---|
✔ Connected | Working. This is what you want |
! Connected · tools fetch failed | Connected but could not list tools. claude mcp get <name> shows why |
! Needs authentication | Reachable, but needs a browser sign-in or a token via --header |
✘ Failed to connect | No response. See Troubleshooting |
✘ Connection error | The connection attempt threw. See Troubleshooting |
⏸ Pending approval (run `claude` to approve) | A project server you have not approved yet |
⊘ Disabled for this project (re-enable via /mcp) | Turned off by the project's disabledMcpServers list |
Older Windows consoles (the default one on Windows 10, for instance) show √ and × instead of the tick and cross.
3. Use it
Start claude and ask for something that needs the server. Naming the server is not normally necessary, because Claude picks tools by relevance, but it guarantees this test goes through MCP rather than a web fetch:
Use deepwiki to explain how the vercel/next.js repo structures its app router tests
Approve the permission prompt if one appears. The tool call in the output carries the server name, which is your proof the answer came from the server.
4. Remove it (optional)
claude mcp remove deepwiki
You see Removed MCP server "deepwiki" from local config and the file it changed.
Note: Every connected server costs some of your context window, because its tool names and instructions load into each session. I prune servers I have stopped using.
Where servers are stored
claude mcp add defaults to local scope. --scope user registers a server for all your projects, and --scope project shares it with your team. The command behaves the same in bash, zsh, PowerShell and Command Prompt. Inside a session, /mcp is where you check and manage servers.
| Scope | Stored in | Who gets it |
|---|---|---|
local (default) | ~/.claude.json, under this project's entry | You, in this project |
project | .mcp.json at the project root | Anyone who clones the repo |
user | ~/.claude.json, top-level mcpServers | You, in every project |
On Windows ~/.claude.json is %USERPROFILE%\.claude.json. If CLAUDE_CONFIG_DIR is set, the file is read from that folder instead (see environment variables). claude mcp get <name> tells you which scope holds a server. How duplicate definitions across scopes resolve is covered in the MCP guide.
Changing scope
Scope is set when a server is added, so to change it you remove and re-add. Clear any existing local copy first:
claude mcp remove deepwiki --scope local
For every project you open, still private to you:
claude mcp add --scope user --transport http deepwiki https://mcp.deepwiki.com/mcp
For the whole team, written to .mcp.json:
claude mcp add --scope project --transport http deepwiki https://mcp.deepwiki.com/mcp
Commit .mcp.json. Teammates are asked to approve the server the first time they start Claude Code in the repo, and then it connects for them too.
A local server
A stdio server is a program Claude Code launches as a subprocess. Use this shape when the tool needs things on your machine: files, a local database socket, a browser. The official filesystem server is an easy one to try; it needs Node.js and no account.
claude mcp add notes-fs -- npx -y @modelcontextprotocol/server-filesystem ~/Documents/notes
Compared with the hosted example:
- No
--transportflag: stdio is the default. - Everything after
--is the command Claude Code runs to start the server. -ystopsnpxasking before it installs the package.
"Added" only means the entry was saved. Run claude mcp list to see whether it actually starts. The first check can report ✘ Failed to connect while npx downloads the package; give it a moment and check again.
Then try it:
Use notes-fs to list the markdown files in my notes folder and summarise the three newest
Tool calls appear labelled with notes-fs and the action name.
Another popular local server is Microsoft's Playwright server (npx -y @playwright/mcp@latest), which gives Claude a real browser. It uses your installed Chrome by default; add --browser firefox after the package name to switch.
A server that needs sign-in
Hosted services such as Sentry, Linear and Notion put their MCP servers behind OAuth. You add the URL, then sign in through the browser. Using Linear as the example:
claude mcp add --transport http linear https://mcp.linear.app/mcp
claude mcp list will show ! Needs authentication. That is expected. Start claude, run /mcp, select linear, press Enter and choose Authenticate. Approve in the browser and the status flips to connected. Then ask something like "Which Linear issues are assigned to me this cycle?" and watch for linear in the tool calls.
Servers that use a fixed token rather than OAuth take it when you add them: --header "Authorization: Bearer <token>". The MCP guide has a GitHub example.
Writing .mcp.json by hand
All three storage locations use the same entry format. .mcp.json is the one worth writing yourself, because it is committed and acts as configuration-as-code for the team. Here is one with a hosted and a local server:
{
"mcpServers": {
"deepwiki": {
"type": "http",
"url": "https://mcp.deepwiki.com/mcp"
},
"notes-fs": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"]
}
}
}
HTTP entries need url; stdio entries need command and args. Claude Code reads the file when a session starts, so start a new one after saving.
The first time it sees a project server, Claude Code asks you to approve it. That prompt exists so a repository you clone cannot launch processes on your machine without consent. If you missed it, approve from /mcp, then check there that everything shows as connected.
Other ways to connect
- Desktop app: add servers in the Connectors UI (see desktop).
- Claude Desktop chat app: a separate product. On macOS or WSL,
claude mcp add-from-claude-desktopcopies servers from itsclaude_desktop_config.json. - VS Code: see VS Code.
- Cloud sessions: commit
.mcp.json; a session with one repository loads it (see cloud environments). - Claude.ai connectors: anything added at claude.ai/customize/connectors loads in the CLI when you sign in with the same account.
Troubleshooting
Start with /mcp in a session or claude mcp list in the shell, then find your symptom. /mcp also lets you reconnect or re-authenticate in place.
"No MCP servers configured"
- Added from another project. Local scope is tied to the project root (or the exact folder outside git). Re-add here, or use
--scope user. - Wrong file. Only
~/.claude.jsonand<project>/.mcp.jsonare read. Paths like~/.claude/.mcp.json,~/.claude/mcp.json,~/.claude/config/mcp.jsonor%APPDATA%\Claude\mcp.jsonare ignored. - Malformed entry. A broken entry in
.mcp.jsonis skipped while the rest load.claude mcp listprints a parse warning naming the bad field.
"Failed to connect" or "Connection error"
Both mean the process did not start or the URL did not answer. They can also mean an HTTP server rejected the token in headers.Authorization (a missing token shows Needs authentication instead).
- For
Failed to connect, read the detail first. From v2.1.219,claude mcp listandclaude mcp get <name>show the HTTP status or error code and any message the server sent, which often names the fault outright. Connection errornever carries detail, so go straight to the manual checks below.claude mcp listalso warns about config values with hidden leading or trailing whitespace, a classic result of pasting a token.- A
404producesMCP endpoint not found at <origin>. Check the URL in your MCP config.when you select the server in/mcp. Only the origin is shown, so runclaude mcp get <name>for the full URL, compare the path with the server's documentation, then remove and re-add.
For HTTP servers, test reachability (use curl.exe in PowerShell to avoid the Invoke-WebRequest alias):
curl -I https://mcp.linear.app/mcp
| Response | Meaning |
|---|---|
404 or 405 | The server is up; many endpoints only accept POST |
401 or 403 | Up, and you need to authenticate (OAuth via /mcp, or --header with a token) |
| Nothing | Check the URL and your network |
For stdio servers, run the configured command yourself:
npx -y @modelcontextprotocol/server-filesystem ~/Documents/notes
If it starts and sits waiting for input, the server is fine. Compare it with what claude mcp get <name> shows; a mismatch usually means you forgot the -- before the command. (Before v2.1.285, get showed no Command line for a hand-written entry with no type; use claude mcp list on those versions.) If it errors, the message usually names what is missing, such as Node.js.
Timed out at startup
Servers get 30 seconds to start by default, and a first npx run can be slower. Raise it with MCP_TIMEOUT, in milliseconds:
MCP_TIMEOUT=90000 claude
$env:MCP_TIMEOUT = "90000"; claude
"Server already exists"
That name is taken at that scope. Remove it or pick another name. If remove reports exists in multiple scopes, add --scope local (or user, project) to say which.
Connected but no tools
Select the server in /mcp to see its tools. An empty list usually means a missing environment variable such as an API key. Supply it with --env KEY=value on claude mcp add, or in the entry's env field.
Edits to .mcp.json are ignored
Restart the session, since the file is only read at startup. Check claude mcp list for parse warnings. If you rejected the server earlier, clear past answers with claude mcp reset-project-choices.
OAuth fails or no browser opens
Choose Authenticate again in /mcp. If no browser appears, copy the URL printed in the terminal into one. Fixed callback ports and pre-registered credentials are covered in the MCP guide.