Overview
Model Context Protocol (MCP) servers extend Claude Code with external tool access, read databases, call APIs, or browse files outside the project directory. This guide installs Claude Code, wires the GitHub MCP server as a concrete example, limits permissions to read-only, and confirms the server is reachable with /mcp. The full MCP server reference lives in mcp-servers.
Prerequisites
- Claude Code installed and authenticated. If not, follow set-up-claude-code first.
- Node 22 on the path. MCP servers are most commonly Node packages.
- A GitHub personal access token (PAT) with at least
repo:readscope for the GitHub server example. Generate one at GitHub > Settings > Developer Settings > Personal Access Tokens. - The repository you are working in, open in a terminal.
Steps
1. Install Claude Code
If already installed, skip to step 2.
npm install -g @anthropic-ai/claude-code
claude --versionAuthenticate on first run. claude opens the login flow; complete it in the browser.
2. Locate or create .claude/settings.json
MCP server configuration lives in .claude/settings.json at the repository root (project scope) or ~/.claude/settings.json (user scope). Use project scope so the server config is committed and shared with the team.
mkdir -p .claude
touch .claude/settings.json3. Add the GitHub MCP server
The GitHub MCP server (@modelcontextprotocol/server-github) exposes tools to read issues, pull requests, file contents, and repository metadata.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PAT}"
}
}
}
}The ${GITHUB_PAT} syntax reads from the environment. Store the token in .env or export it in your shell profile; never hardcode it. Add .env to .gitignore. For secrets that differ per developer, use settings.local.json and gitignore that path.
4. Restrict permissions
By default Claude Code prompts for confirmation on every tool call. Add an allowedTools list to restrict what the GitHub server may do to read-only operations:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PAT}"
}
}
},
"permissions": {
"allow": [
"mcp__github__get_file_contents",
"mcp__github__list_issues",
"mcp__github__list_pull_requests",
"mcp__github__get_commit",
"mcp__github__search_code"
]
}
}Listing tools explicitly in allow skips the confirmation prompt for those tools only. Any tool not in the list still prompts. See mcp-servers for the full permissions model and prompt-injection-defense for why you should keep write tools behind prompts.
5. Verify with /mcp
Start a Claude Code session in the repository:
claudeThen run the /mcp command inside the session:
/mcp
Claude Code lists all connected MCP servers and their status. A healthy connection shows:
github: connected (14 tools available)
If the server shows “disconnected” or an error, check the troubleshooting section below.
6. Test a tool call
Ask Claude Code to use the server:
List the last 5 open issues in this repository.
Claude Code calls mcp__github__list_issues and prints the result. Confirm the tool call appears in the transcript.
Verify it worked
# 1. /mcp shows the server as connected.
# Run inside a claude session: /mcp
# 2. The settings file is valid JSON.
node -e "JSON.parse(require('fs').readFileSync('.claude/settings.json','utf8'))"
# No output means valid JSON.
# 3. The PAT has the right scope.
curl -sH "Authorization: Bearer $GITHUB_PAT" https://api.github.com/user | jq .login
# Your GitHub usernameCommon errors
/mcpshows server as disconnected. Thenpxcommand failed to install the package. Runnpx -y @modelcontextprotocol/server-githubmanually to see the error. Common causes: network proxy, wrong Node version.GITHUB_PERSONAL_ACCESS_TOKENis empty. The${GITHUB_PAT}substitution only works if the variable is exported in the shell runningclaude. Addexport GITHUB_PAT=...to your shell profile.- Tool calls prompt for confirmation despite being in
allow. The tool name inallowmust match exactly, including themcp__<server>__prefix. Use/mcpto confirm the exact names. settings.jsonis not read. Claude Code looks in.claude/settings.jsonfrom the working directory whereclaudewas invoked. Start Claude Code from the repo root.- Write tools are available when they should not be. Remove write tools from the PAT scopes at the GitHub level, not just from the
allowlist. Defense-in-depth: least privilege at both layers.