Overview
Claude Code connects to MCP servers over HTTP (remote), stdio (local process), or WebSocket (JSON config only). This guide adds the GitHub MCP server and a local stdio server, picks the right scope, allows specific tools, and checks the connection. An MCP server is not a Claude Code skill; skills are covered in claude-code-skills.
Prerequisites
- Claude Code installed and signed in; see set-up-claude-code.
- For stdio servers distributed on npm, Node 22 or newer.
- For GitHub, a personal access token with the narrowest scopes the task needs.
Steps
1. Prefer HTTP for remote servers
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer $GITHUB_PAT"The SSE transport is deprecated; use --transport http wherever the server offers it. The old @modelcontextprotocol/server-github npm package is deprecated in favor of GitHub’s own server.
2. Add a local stdio server
Everything after -- is the server command.
claude mcp add --transport stdio --scope project fs -- \
npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/dir3. Choose the scope
| Scope | Stored in | Shared |
|---|---|---|
local (default) | ~/.claude.json, this project only | No |
project | .mcp.json at the repo root | Yes, commit it |
user | ~/.claude.json, all projects | No |
A committed .mcp.json can also be written by hand. Use ${VAR} or ${VAR:-default} for secrets in command, args, env, url, and headers; never write the literal token.
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer ${GITHUB_PAT}" }
}
}
}Teammates must approve a project-scoped server the first time they run claude in the repo. claude mcp reset-project-choices clears those approvals.
4. Allow specific tools
Tools are named mcp__<server>__<tool>. Add read-only ones to permissions.allow in .claude/settings.json; everything else keeps prompting.
{ "permissions": { "allow": ["mcp__github__get_file_contents", "mcp__github__list_issues"] } }Treat tool output as untrusted input; see mcp-security.
Verify it worked
claude mcp list # configured servers
claude mcp get github # scope, transport, URLInside a session, /mcp lists servers, tool counts, and OAuth state. Ask “List the last 5 open issues” and confirm a mcp__github__... call appears in the transcript.
Common errors
- Server stays pending. A project-scoped server needs interactive approval; start
claudein the repo and accept the prompt. - Empty token.
${GITHUB_PAT}expands from the shell that launchedclaude; export it first. Credential variables such asANTHROPIC_API_KEYread as empty inside remoteurlandheaders. - Prompted despite an allow rule. The name must match exactly; copy it from
/mcp. - Server missing.
.mcp.jsonmust sit at the project root and be valid JSON;claude mcp get <name>shows what loaded. - Write tools are available. Narrow the token’s scopes at the provider; an allow list only skips prompts.
FAQ
Should I use SSE or HTTP for a remote MCP server in Claude Code?
Use --transport http; the SSE transport is deprecated.
Where does Claude Code store MCP server config?
local (the default) and user scopes live in ~/.claude.json, while project scope lives in .mcp.json at the repo root, which you commit to share with the team.
How do I keep an API token out of .mcp.json?
Write ${VAR} or ${VAR:-default} instead of the literal token; it expands from the shell that launched claude, so export the variable first.
Why does my project MCP server stay pending?
A project-scoped server needs interactive approval the first time each teammate runs claude in the repo. claude mcp reset-project-choices clears those approvals.
Does a permissions allow list stop Claude Code from using MCP write tools?
No; an allow list only skips prompts for the named mcp__<server>__<tool> tools. Narrow the token’s scopes at the provider to remove write access.