Model Context Protocol (MCP) for Claude Code: Complete Guide
By Learnia Team
Model Context Protocol (MCP) for Claude Code: Complete Guide
This article is written in English. Our training modules are available in French.
Model Context Protocol (MCP) is the bridge between Claude Code and the outside world. It connects Claude to databases, APIs, SaaS platforms, and custom tools—transforming a smart coding assistant into an integrated development hub that understands your entire ecosystem.
What is MCP?
MCP is an open protocol that standardizes how AI assistants communicate with external data sources and tools. Think of it as USB for AI—a universal connector that works with anything.
Without MCP
> What's the status of issue #432?
I don't have access to your issue tracker.
Please check GitHub directly.
With MCP + GitHub Server
> What's the status of issue #432?
Issue #432: "Fix authentication redirect loop"
Status: Open
Assignee: @developer
Labels: bug, high-priority
Last updated: 2 hours ago
Related PR: #445 (in review)
Claude can now query, create, and update GitHub issues directly.
How MCP Works
MCP Data Flow:
Claude Code ⟷ MCP Server ⟷ External Service
- →Claude Code sends requests through the MCP protocol
- →MCP Server translates requests to the external service's API
- →External Service returns data through the same chain
MCP servers can run:
- →Locally (stdio transport) — Scripts on your machine
- →Remotely (HTTP transport) — Hosted services with OAuth
Built-in MCP Servers
Claude Code includes several MCP servers out of the box:
| Server | Purpose |
|---|---|
| File operations beyond current directory |
| PostgreSQL database access |
| SQLite database access |
| Persistent key-value storage |
| HTTP requests to external APIs |
Managing MCP Connections
View Current Servers
claude mcp list
Output:
Configured MCP Servers:
github (http) - https://api.github.com/mcp/ [authenticated]
sentry (http) - https://mcp.sentry.dev/mcp [authenticated]
filesystem (stdio) - local
Interactive Management
> /mcp
Opens interactive menu:
MCP Servers
[1] github (http) - authenticated
Tools: get_issue, create_issue, list_repos...
[2] sentry (http) - authenticated
Tools: get_issues, search_errors...
[3] filesystem (stdio) - connected
Tools: read_file, write_file, list_directory...
[a] Add server [r] Remove server [s] Server status
[o] Re-authenticate [Esc] Exit
Adding MCP Servers
HTTP Servers (Remote)
Most SaaS integrations use HTTP transport with OAuth:
# GitHub integration
claude mcp add github --transport http https://api.github.com/mcp/
# Sentry error tracking
claude mcp add sentry --transport http https://mcp.sentry.dev/mcp
# Linear project management
claude mcp add linear --transport http https://mcp.linear.app/mcp
# Notion (with header auth)
claude mcp add notion --transport http-stream https://mcp.notion.so/mcp
After adding, Claude Code opens a browser for OAuth authentication.
Stdio Servers (Local)
Local servers run as scripts:
# Using npx
claude mcp add my-server npx -y @modelcontextprotocol/server-filesystem /path/to/dir
# Using Python
claude mcp add my-db-server python /path/to/mcp_server.py
# Using Node.js
claude mcp add custom-tools node /path/to/server.js
With Environment Variables
claude mcp add my-server -e API_KEY=secret -e DB_URL=postgres://... npx my-mcp-server
Popular MCP Integrations
GitHub
claude mcp add github --transport http https://api.github.com/mcp/
Available tools:
- →
/get_issue
/create_issueupdate_issue - →
/get_pull_requestcreate_pull_request - →
/list_repossearch_code - →
/get_file_contentscreate_or_update_file
Usage:
> Create an issue for the login bug we discussed
Created issue #543: "Login fails when session expires"
Labels: bug
Assignee: @me
Sentry
claude mcp add sentry --transport http https://mcp.sentry.dev/mcp
Available tools:
- →
- Fetch error issuesget_sentry_issues - →
- Search by querysearch_sentry_errors - →
- Detailed error infoget_issue_details
Usage:
> Show me the most frequent errors this week
Top Sentry Issues (last 7 days):
1. TypeError: Cannot read 'map' of undefined
- 342 events, 89 users affected
- File: src/components/List.tsx:45
2. NetworkError: Failed to fetch
- 156 events, 45 users affected
- File: src/api/client.ts:23
PostgreSQL
claude mcp add postgres npx -y @modelcontextprotocol/server-postgres \
"postgresql://user:pass@localhost:5432/mydb"
Available tools:
- →
- Execute read queriesquery - →
- Show database schemalist_tables - →
- Table structuredescribe_table
Usage:
> Show me users who signed up this month
Executing: SELECT * FROM users WHERE created_at >= '2026-01-01'
Results (23 rows):
id | email | plan | created_at
---+--------------------+---------+------------
1 | alice@example.com | pro | 2026-01-02
2 | bob@example.com | free | 2026-01-03
...
Filesystem
claude mcp add docs-fs npx -y @modelcontextprotocol/server-filesystem /path/to/docs
Access files outside your current working directory.
Memory (Persistent Storage)
claude mcp add memory npx -y @modelcontextprotocol/server-memory
Store and retrieve data across sessions:
> Remember that the API key rotates every 30 days
Stored: api_key_rotation -> "30 days"
# Later session:
> When does the API key rotate?
Retrieved: The API key rotates every 30 days.
Configuring MCP in Settings
User Settings
Global MCP configuration in
~/.claude/settings.json:
{
"mcpServers": {
"github": {
"transport": "http",
"url": "https://api.github.com/mcp/"
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"],
"env": {}
},
"custom-db": {
"command": "python",
"args": ["/path/to/db_server.py"],
"env": {
"DATABASE_URL": "postgresql://localhost/mydb"
}
}
}
}
Project Settings
Project-specific MCP in
.claude/settings.json:
{
"mcpServers": {
"project-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
}
}
}
Use
${VAR} to reference environment variables.
MCP Permissions
Control which MCP tools Claude can use:
# Allow all tools from a server
claude config add permissions.allow "mcp__github__*"
# Allow specific tools
claude config add permissions.allow "mcp__github__get_issue"
claude config add permissions.allow "mcp__github__create_issue"
# Deny destructive operations
claude config add permissions.deny "mcp__github__delete_repo"
claude config add permissions.deny "mcp__postgres__query" # block all DB queries
See Claude Code Permissions: Deny, Allow & Ask Modes Explained.
Building Custom MCP Servers
When existing servers don't fit your needs, build your own.
Server Template (TypeScript)
// server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({
name: "my-custom-server",
version: "1.0.0",
});
// Define tools
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "get_weather",
description: "Get weather for a city",
inputSchema: {
type: "object",
properties: {
city: { type: "string", description: "City name" }
},
required: ["city"]
}
}
]
}));
// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "get_weather") {
const weather = await fetchWeather(args.city);
return {
content: [{ type: "text", text: JSON.stringify(weather) }]
};
}
throw new Error(`Unknown tool: ${name}`);
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Server Template (Python)
# server.py
import json
import sys
from mcp.server import Server, stdio_transport
server = Server("my-python-server")
@server.list_tools()
async def list_tools():
return [
{
"name": "analyze_logs",
"description": "Analyze application logs",
"inputSchema": {
"type": "object",
"properties": {
"path": {"type": "string", "description": "Log file path"},
"pattern": {"type": "string", "description": "Search pattern"}
},
"required": ["path"]
}
}
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "analyze_logs":
result = analyze_logs(arguments["path"], arguments.get("pattern"))
return {"content": [{"type": "text", "text": json.dumps(result)}]}
raise ValueError(f"Unknown tool: {name}")
if __name__ == "__main__":
stdio_transport.run(server)
Register Your Server
claude mcp add my-server node /path/to/server.js
# or
claude mcp add my-server python /path/to/server.py
MCP Server Registry
Find community-built servers at the MCP Registry:
Official Servers:
- →
@modelcontextprotocol/server-filesystem - →
@modelcontextprotocol/server-postgres - →
@modelcontextprotocol/server-sqlite - →
@modelcontextprotocol/server-memory - →
@modelcontextprotocol/server-fetch
Community Servers:
- →Slack integration
- →Jira integration
- →AWS services
- →Docker management
- →Kubernetes operations
Install from npm:
claude mcp add slack npx -y mcp-server-slack
Authentication
OAuth Flow (HTTP Servers)
HTTP servers typically use OAuth:
- →
Add the server:
claude mcp add github --transport http https://api.github.com/mcp/ - →
Claude Code opens browser for authentication
- →
After authorizing, tokens are stored securely
- →
Re-authenticate if needed:
> /mcp Select server > [o] Re-authenticate
API Keys (Stdio Servers)
Pass API keys via environment:
claude mcp add weather -e WEATHER_API_KEY=abc123 npx weather-mcp-server
Or in settings:
{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["weather-mcp-server"],
"env": {
"WEATHER_API_KEY": "${WEATHER_API_KEY}"
}
}
}
}
Set the environment variable:
export WEATHER_API_KEY=abc123
Debugging MCP
Check Server Status
claude mcp list
Shows connection status for each server.
View Server Logs
claude --verbose
Shows MCP communications:
[MCP] Connecting to github...
[MCP] github: authenticated
[MCP] Calling tool: get_issue(number=432)
[MCP] Response received (245 bytes)
Test Server Locally
# Test stdio server directly
echo '{"method":"tools/list"}' | node /path/to/server.js
Common Issues
Server won't connect:
- →Check the command path is correct
- →Verify dependencies are installed
- →Check environment variables
Authentication expired:
- →Use
> Re-authenticate/mcp - →Or remove and re-add the server
Tool calls failing:
- →Check server logs for errors
- →Verify input schema matches
- →Check API rate limits
MCP in Practice
Workflow: Automated Bug Fixing
Combine Sentry + GitHub + your codebase:
> Find the most critical Sentry error and create a fix
[Querying Sentry...]
Found: TypeError in src/components/UserList.tsx:45
"Cannot read property 'map' of undefined"
[Analyzing code...]
Issue: `users` can be null when API fails
[Creating fix...]
Added null check and loading state
[Creating GitHub issue...]
Created #234: "Fix UserList crash on API failure"
[Creating PR...]
Created PR #235 with the fix
Workflow: Database-Aware Development
> Add a "last_login" field to the users table
[Querying schema via MCP...]
Current users table: id, email, name, created_at
[Generating migration...]
Created: migrations/20260112_add_last_login.sql
[Updating models...]
Modified: src/models/User.ts
Modified: src/types/user.ts
[Updating tests...]
Modified: tests/user.test.ts
Ready to run: npm run migrate
Workflow: Cross-Platform Sync
> Update all platforms with the new release
[Checking GitHub...]
Latest tag: v2.3.0
[Updating Linear...]
Marked related issues as completed
[Posting to Slack...]
Sent release announcement to #releases
[Updating Notion...]
Added release notes to documentation
Release v2.3.0 synchronized across all platforms.
MCP Security Best Practices
1. Principle of Least Privilege
Only enable servers you need:
# Good: specific integration
claude mcp add github --transport http ...
# Avoid: exposing entire filesystem
claude mcp add fs npx server-filesystem /
2. Use Environment Variables for Secrets
Never hardcode credentials:
{
"mcpServers": {
"db": {
"env": {
"DATABASE_URL": "${DATABASE_URL}" // Good
// "DATABASE_URL": "postgres://user:pass@..." // Bad
}
}
}
}
3. Restrict Tool Permissions
Block destructive operations:
claude config add permissions.deny "mcp__github__delete_*"
claude config add permissions.deny "mcp__postgres__query" # if read-only needed
4. Audit MCP Usage
Review what Claude accesses:
claude --verbose 2>&1 | grep "\[MCP\]"
See Claude Code Best Practices: Security, Performance & Teams.
Key Takeaways
- →
MCP extends Claude's reach: Connect to any external service or data source.
- →
Two transport types: HTTP for SaaS with OAuth, stdio for local scripts.
- →
Easy to add:
handles configuration.claude mcp add - →
Build your own: TypeScript and Python SDKs make custom servers simple.
- →
Security matters: Use permissions to control which tools Claude can access.
Master API Interactions
MCP opens the door to API integrations. Learn to work with APIs effectively in your prompts.
In our Module 5 — Working with APIs, you'll learn:
- →Prompting for API interactions
- →Handling authentication in prompts
- →Error handling patterns
- →Building API-powered workflows
Module 5 — RAG (Retrieval-Augmented Generation)
Ground AI responses in your own documents and data sources.