Claude CodeMCPAI developmenttutorialfield notes

How to connect MCP servers to Claude Code (2026): the command, .mcp.json and remote OAuth

· · 12 min read
Table of Contents
  1. Why connect MCP at all?
  2. Three ways to connect
  3. Option 1: one `claude mcp add` command
  4. Option 2: `.mcp.json` in the project root
  5. Option 3: a remote server that needs OAuth
  6. Our test run, in three parts
  7. Test 1: adding a stdio server
  8. Test 2: `.mcp.json` and the three scopes
  9. Test 3: remote sign-in status and re-authenticating with `/mcp`
  10. Six common errors
  11. How we use it ourselves

Connecting an MCP server to Claude Code takes one command: claude mcp add <name> -- <command> for a program that runs on your machine, or claude mcp add --transport http <name> <url> for a hosted one. Run claude mcp list afterwards, and once it says ✔ Connected the tools are ready. To share servers with a team, put them in .mcp.json at the project root. For a remote server that needs a login, type /mcp inside Claude Code and sign in through your browser.

Commands and output marked as tested come from a run we did on November 8, 2026, on a Windows 10 machine (Git Bash, Claude Code 2.1.285). Everything else follows the official Claude Code docs, and we say so where it applies. If Claude Code isn't installed yet, start with our hands-on Claude Code tutorial and come back.

Disclosure: the example package, mindthread-mcp, is the MCP package for our own product, MindThread. We picked it because it lists its tools without an API key. Any stdio server works the same way.

Why connect MCP at all?

If you keep copying data out of another tool and pasting it into Claude, that tool is a candidate for MCP. The Model Context Protocol is an open source standard for connecting AI to external tools, and once a server is connected, Claude reads and acts on that system directly.

For small teams and solo developers, MCP is how you plug Claude into systems you already use. The official docs give examples like implementing a feature straight from an issue tracker, checking Sentry monitoring data, querying a PostgreSQL database and driving a browser to test a site. You don't write the integration yourself. You find the MCP server the service provides and connect it.

Three ways to connect

You can connect an MCP server to Claude Code with a claude mcp add command, with a .mcp.json file in the project root, or as a remote server you sign in to with OAuth.

Option 1: one `claude mcp add` command

The fastest route is claude mcp add, run in your terminal rather than inside a Claude Code conversation. A server that runs as a local program uses the stdio transport, and Claude Code starts it as a subprocess:

claude mcp add mindthread -- npx -y mindthread-mcp

Don't drop the --. Per the docs, everything before it is an option for Claude Code itself (--transport, --env, --scope), and everything after it goes to the server untouched. Pass API keys with --env KEY=value.

Remote servers use the HTTP transport, which the docs recommend for anything hosted:

claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp

Three management commands cover most needs: claude mcp list lists every server and checks its connection, claude mcp get <name> shows one server in detail, and claude mcp remove <name> deletes it.

Option 2: `.mcp.json` in the project root

To share MCP servers with a team, write them into .mcp.json at the project root and commit it, so everyone who clones the repository gets the same tools. You can write it by hand or let --scope project write it for you. The format:

{
  "mcpServers": {
    "claude-code-docs": {
      "type": "http",
      "url": "https://code.claude.com/docs/mcp"
    },
    "mindthread": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mindthread-mcp"],
      "env": { "MINDTHREAD_API_KEY": "${MINDTHREAD_API_KEY}" }
    }
  }
}

Keep keys out of the file and reference environment variables instead. The docs support ${VAR} and ${VAR:-default} in command, args, env, url and headers.

The docs state that Claude Code reads .mcp.json at session start, so exit and restart the session after editing it. The first time it sees a project server, it asks you to approve it; the docs explain that this stops a repository you clone from launching processes on your machine without your consent. Read what tools an unfamiliar server exposes before you approve it. If you wrote the server yourself, its tool descriptions go straight into Claude's context (anything past the length limit is cut), and our open source UltraProbe can run a static check on tool descriptions you paste in. It reads only that text and does not connect to or scan the server itself.

Option 3: a remote server that needs OAuth

Hosted MCP servers from services like Sentry, Notion and Linear need a sign-in first: you add the URL, then authorize inside Claude Code. Add it:

claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

At this point claude mcp list shows ! Needs authentication, which is expected. Start Claude Code, type /mcp, pick the server and choose Authenticate. Your browser opens the service's sign-in page, and after you approve, the status changes to connected. According to the docs, tokens are stored securely and refreshed automatically.

For services that use a static token instead of OAuth, pass it when adding: --header "Authorization: Bearer <token>". Older services with only an SSE endpoint also go in with --transport http; from v2.1.265 Claude Code falls back to SSE on its own.

Our test run, in three parts

We tested three things on Windows 10 with Claude Code 2.1.285: adding a stdio server, the three scopes, and the sign-in status of remote servers. The run used a separate temporary config directory, so our everyday settings weren't touched.

Test 1: adding a stdio server

When claude mcp add prints Added, the configuration was written; only claude mcp list tells you whether the program actually starts. Our output, with paths rewritten:

$ claude mcp add mindthread -- npx -y mindthread-mcp
Added stdio MCP server mindthread with command: npx -y mindthread-mcp to local config
File modified: <config dir>\.claude.json [project: <project path>]

$ claude mcp list
mindthread: npx -y mindthread-mcp - ✔ Connected

We also asked the server for its tools directly over the MCP protocol. Without a key it listed 43 tools, about 47,000 characters of tool definitions. The server decides the count, so it will change. In our setup (Windows 10, Git Bash, Claude Code 2.1.285), plain npx connected without a cmd /c wrapper. We didn't test PowerShell or Command Prompt.

Test 2: `.mcp.json` and the three scopes

Claude Code has three MCP scopes, local, project and user, and the scope decides which projects a server appears in and whether teammates get it. From the docs:

Scope Loads in Shared with team Stored in
local (default) Current project only No ~/.claude.json, under this project
project Current project only Yes, via version control .mcp.json in the project root
user All your projects No ~/.claude.json, top-level mcpServers

We added one server at each scope. claude mcp list then showed:

mt-everywhere: npx -y mindthread-mcp - ✔ Connected
mt-shared: npx -y mindthread-mcp - ⏸ Pending approval (run `claude` to approve)
mindthread: npx -y mindthread-mcp - ✔ Connected

The project-scoped mt-shared waits for approval until you start claude in that folder and accept it. claude mcp get names the scope a server came from, so run it first whenever you can't tell where a definition lives.

Test 3: remote sign-in status and re-authenticating with `/mcp`

/mcp is the in-session command for checking every server's status and tool count, and for reconnecting or signing in from the same panel. With two remote servers added, claude mcp list showed:

sentry: https://mcp.sentry.dev/mcp (HTTP) - ! Needs authentication
claude-code-docs: https://code.claude.com/docs/mcp (HTTP) - ✔ Connected

We didn't actually sign in to Sentry, so the re-authentication flow below follows the docs. When a server you signed in to rejects the stored token, Claude Code refreshes it and retries once if it has a refresh token. If the refresh token is rejected too, it shows a notice pointing at /mcp, where you pick the server and choose Re-authenticate. If it expires in the middle of a session, the error reads:

MCP server "<name>" needs you to sign in again (run /mcp to re-authenticate)

Six common errors

1. Added, but it won't connect (tested). Forget the -- and Claude Code reads npx's -y as its own option; in our run it failed with error: unknown option '-y'. A misspelled command is the opposite case: claude mcp add succeeds anyway, and only claude mcp list shows ✘ Failed to connect, with CONNECTION_CLOSED: Connection closed on the Issue line of claude mcp get. The docs suggest running the server command on its own in a terminal to see the real error. Also, npx's first download can outlast the default 30-second startup timeout; raise it with MCP_TIMEOUT=60000 claude.

2. Permission prompts every time (from the docs). Claude Code asks the first time Claude calls an MCP tool, and that is intended. For servers you trust, add an allow rule to a settings file, such as the project's .claude/settings.json or your own ~/.claude/settings.json:

{
  "permissions": {
    "allow": ["mcp__mindthread__*"]
  }
}

mcp__mindthread__* covers every tool on that server, and mcp__mindthread__list_accounts covers one. The wildcard only works after a literal mcp__<server>__ prefix; a bare mcp__* allow rule is skipped. If you rejected a project server earlier and want the prompt back, run claude mcp reset-project-choices.

3. Too many tools in context (from the docs). Each connected server costs some context, because its tool names and server instructions load in every session. On Opus 4, Sonnet 4, Haiku 4.5 and later models, tool search is on by default and full definitions load only when needed, so per the docs the 43 tools from our test don't all land in context at once (we didn't measure actual usage). With tool search off or on older models, every tool loads upfront. Tool output above 10,000 tokens triggers a warning, the default cap is 25,000 tokens, and anything larger is saved to a file that Claude reads when it needs it. Remove servers you don't use.

4. Expired OAuth (from the docs). When you see needs you to sign in again, open /mcp and sign in again. Note that a non-interactive claude -p run has no /mcp panel and can't run the OAuth flow, so sign in from an interactive session first, or run claude mcp login <name> in your shell. If you pass your own token with --header and the server rejects it, Claude Code reports a failed connection rather than asking you to sign in; replace the token.

We ran into one claude.ai connector case ourselves on November 8 (connectors are services you authorize in your claude.ai account; they load into Claude Code automatically when you sign in with the same account). After we switched the account Claude Code was logged in with, a Gmail connector kept showing as expired, re-authenticating it in /mcp didn't help, and restarting the session fixed it. That looks like the "session token rejected" case in the docs: the rejected token is your Claude Code login, so authorizing the connector again doesn't help, and the documented order is /login first, then reconnect from /mcp. We didn't try /login first and didn't note the exact status text in the panel.

5. Windows paths (tested). On Windows, ~/.claude.json is %USERPROFILE%\.claude.json. Windows paths inside .mcp.json need doubled backslashes (C:\\Program Files\\...). We tried a single backslash on purpose, and claude mcp list reported MCP config is not a valid JSON, so none of the project's servers loaded. The default Windows 10 console shows ✔ and ✘ as √ and ×; the docs mention this, and nothing is broken.

6. Project and global scopes in conflict (tested). When the same name exists at local and user scope, Claude Code uses only the higher-precedence entry (local, then project, then user) without merging fields. In our run, with different commands in the two entries, claude mcp list printed a [Conflicting scopes] warning, and a bare claude mcp remove mindthread was refused until we added -s local or -s user. The docs add that OAuth sign-ins are stored per endpoint, so two definitions pointing at different endpoints each need their own sign-in.

How we use it ourselves

MindThread, one of our products, has an MCP server. The mindthread-mcp package is on npm and listed in the official MCP Registry as io.github.ppcvote/mindthread. It bridges stdio to MindThread's hosted API, so the tool list follows the server without reinstalling the package. For what it looks like in real use, see pulling your best posts with MindThread MCP before drafting.

Our own Claude Code work sessions often stay open for hours with several MCP servers connected, and we check on them from a phone when we're away from the desk; the setup is in our Claude Code Remote Control guide. If you get stuck, debug in this order: claude mcp list for the status, claude mcp get <name> for the detail, then run the server command by itself in a terminal.

FAQ

Where does Claude Code store MCP server settings?

It depends on the scope. Local and user scope both live in ~/.claude.json in your home directory (%USERPROFILE%\.claude.json on Windows): local under the entry for the current project, user under the top-level mcpServers key. Project scope lives in .mcp.json at the project root. Claude Code does not read paths like ~/.claude/mcp.json, and editing the wrong file is a common reason a server never shows up.

Which scope should I use: local, project or user?

Use local, the default, for a server only you use in one project. Use project when everyone who clones the repository should get it; the entry goes into .mcp.json under version control. Use user for a server you want in all of your projects. When one name exists in several scopes, Claude Code uses only the highest-precedence entry (local, then project, then user) and does not merge fields.

Can I still use the SSE transport?

Yes, but the official docs mark it as deprecated and recommend HTTP. For a service that only exposes an SSE endpoint, add it with claude mcp add --transport http anyway: from Claude Code v2.1.265, it tries HTTP first and switches to SSE when the server does not accept it. You only need --transport sse on older versions.

Will connecting many MCP servers eat my context window?

Not much on recent models. On Claude Opus 4, Sonnet 4, Haiku 4.5 and later, tool search is on by default, so only tool names and server instructions load at session start, and full tool definitions load when Claude needs them. On older models, with ENABLE_TOOL_SEARCH=false, or in some enterprise setups, every tool loads upfront. Tool output has its own limits: a warning above 10,000 tokens and a default cap of 25,000 tokens, adjustable with MAX_MCP_OUTPUT_TOKENS. Removing servers you no longer use still helps.

Weekly AI Automation Playbook

No fluff — just templates, SOPs, and technical breakdowns you can use right away.

Join the Solo Lab Community

Free resource packs, daily build logs, and AI agents you can talk to. A community for solo devs who build with AI.

Want to try it yourself?

UltraProbe is free and needs no sign-up. One scan tells you whether Google and AI engines can find your site.