Làm chủ Claude Code trong một tuần (Phần 8): MCP Protocol
Đây là phần thứ tám trong series "Làm chủ Claude Code trong một tuần". Trong bài này, chúng ta sẽ tìm hiểu MCP Protocol — cách kết nối Claude Code với external tools và APIs.
MCP là gì?
Model Context Protocol (MCP) là giao thức cho phép Claude Code communicate với external services. Thay vì chỉ làm việc với local files, MCP cho phép Claude truy cập databases, APIs, cloud services, và nhiều hơn nữa.
┌────────────────────────────────────────────────────────────────┐
│ MCP PROTOCOL │
├────────────────────────────────────────────────────────────────┤
│ │
│ Claude Code │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────┐ │
│ │ MCP Client │ │
│ └─────────────────────────────────────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │GitHub │ │ DB │ │ Files │ │ Custom│ │
│ │Server │ │Server │ │Server │ │Server │ │
│ └───────┘ └───────┘ └───────┘ └───────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │GitHub │ │ MySQL │ │ AWS │ │ API │ │
│ │ API │ │Postgre│ │ S3 │ │Service│ │
│ └───────┘ └───────┘ └───────┘ └───────┘ │
│ │
└────────────────────────────────────────────────────────────────┘
MCP vs Other Features
| Aspect | MCP | Hooks | Skills |
|---|---|---|---|
| Access | External services | Local scripts | Local files |
| Direction | Query/Mutate data | React to events | Provide instructions |
| Real-time | Yes | Event-triggered | On-demand |
| Use case | APIs, databases | Automation | Workflows |
Cài đặt MCP Server
Via CLI
# Add GitHub MCP server
export GITHUB_TOKEN="ghp_xxxxxxxxxxxx"
claude mcp add github -- npx -y @modelcontextprotocol/server-github
# Add filesystem MCP server
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem ~/projects
# Add PostgreSQL MCP server
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
claude mcp add postgres -- npx -y @modelcontextprotocol/server-postgres
Via Configuration File
Location: .mcp.json (project) hoặc ~/.mcp.json (global)
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"~/projects"
]
}
}
}
Popular MCP Servers
1. GitHub Server
Install:
export GITHUB_TOKEN="ghp_xxxxxxxxxxxx"
claude mcp add github -- npx -y @modelcontextprotocol/server-github
Capabilities:
- List repositories
- Read/Create issues
- Read/Create pull requests
- Access repository contents
- Manage branches
Example usage:
User: "Create an issue for the performance bug we discussed"
Claude: [Uses GitHub MCP]
Created issue #42: "Performance degradation in API endpoints"
Repository: user/project
Labels: bug, performance
2. PostgreSQL Server
Install:
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
claude mcp add postgres -- npx -y @modelcontextprotocol/server-postgres
Capabilities:
- Execute SQL queries
- List tables
- Describe schema
- Run migrations (with care)
Example usage:
User: "Show me the top 10 users by order count"
Claude: [Uses PostgreSQL MCP]
SELECT u.name, COUNT(o.id) as order_count
FROM users u
JOIN orders o ON o.user_id = u.id
GROUP BY u.id
ORDER BY order_count DESC
LIMIT 10;
Results:
| name | order_count |
|------------|-------------|
| John Doe | 152 |
| Jane Smith | 143 |
...
3. Filesystem Server
Install:
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem ~/projects
Capabilities:
- Read files
- Write files
- List directories
- Search files
Example usage:
User: "Find all TODO comments in the projects folder"
Claude: [Uses Filesystem MCP]
Found 15 TODO comments across 8 files:
- ~/projects/app/src/api.ts:42: TODO: Add rate limiting
- ~/projects/app/src/auth.ts:78: TODO: Implement refresh token
...
4. AWS Server
Install:
export AWS_ACCESS_KEY_ID="AKIAXXXXXXXX"
export AWS_SECRET_ACCESS_KEY="xxxxxxxxxx"
export AWS_REGION="us-east-1"
claude mcp add aws -- npx -y @modelcontextprotocol/server-aws
Capabilities:
- S3 operations
- Lambda invocation
- DynamoDB queries
- CloudWatch logs
5. Slack Server
Install:
export SLACK_BOT_TOKEN="xoxb-xxxxxxxxxxxx"
claude mcp add slack -- npx -y @modelcontextprotocol/server-slack
Capabilities:
- Send messages
- Read channels
- Search messages
- Manage reactions
Configuration Examples
Multi-server Configuration
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres-main": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL_MAIN}"
}
},
"postgres-analytics": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL_ANALYTICS}"
}
},
"redis": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-redis"],
"env": {
"REDIS_URL": "${REDIS_URL}"
}
}
}
}
Project-specific Configuration
File: .mcp.json trong project root
{
"mcpServers": {
"project-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://dev:dev@localhost:5432/myapp_dev"
}
},
"project-files": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"./storage",
"./public"
]
}
}
}
Custom MCP Server
Bạn có thể tạo MCP server riêng cho internal APIs.
Basic Structure
// my-mcp-server/index.js
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({
name: "my-api-server",
version: "1.0.0",
});
// Define tools
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "get_users",
description: "Get list of users from internal API",
inputSchema: {
type: "object",
properties: {
limit: { type: "number", description: "Max users to return" },
},
},
},
{
name: "create_ticket",
description: "Create support ticket in internal system",
inputSchema: {
type: "object",
properties: {
title: { type: "string" },
description: { type: "string" },
priority: { type: "string", enum: ["low", "medium", "high"] },
},
required: ["title", "description"],
},
},
],
}));
// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "get_users":
const response = await fetch(
`${process.env.API_URL}/users?limit=${args.limit || 10}`,
{
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
}
);
return { content: [{ type: "text", text: JSON.stringify(await response.json()) }] };
case "create_ticket":
const ticket = await fetch(`${process.env.API_URL}/tickets`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.API_TOKEN}`,
},
body: JSON.stringify(args),
});
return { content: [{ type: "text", text: JSON.stringify(await ticket.json()) }] };
default:
throw new Error(`Unknown tool: ${name}`);
}
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Register Custom Server
{
"mcpServers": {
"my-api": {
"command": "node",
"args": ["./my-mcp-server/index.js"],
"env": {
"API_URL": "${MY_API_URL}",
"API_TOKEN": "${MY_API_TOKEN}"
}
}
}
}
Use Cases
1. Automated PR Review with GitHub
User: "Review the open PRs in our repo and summarize issues"
Claude: [Uses GitHub MCP]
1. Fetches open PRs from repository
2. Analyzes changes in each PR
3. Checks for CI status
4. Generates summary:
## Open PR Summary
### PR #45: Add user authentication
- Status: CI Passing
- Changes: 12 files, +450/-20
- Issues: Missing tests for edge cases
- Recommendation: Request test coverage
### PR #44: Fix database connection pooling
- Status: CI Failing (lint errors)
- Changes: 3 files, +25/-10
- Issues: ESLint errors on line 42
- Recommendation: Fix lint errors before review
2. Database Analysis
User: "Analyze slow queries in production and suggest indexes"
Claude: [Uses PostgreSQL MCP]
1. Queries pg_stat_statements
2. Identifies slow queries
3. Analyzes execution plans
4. Suggests indexes:
## Slow Query Analysis
### Query 1: User search (avg 2.3s)
```sql
SELECT * FROM users WHERE email LIKE '%@example.com'
Issue: Full table scan Recommendation:
CREATE INDEX idx_users_email_pattern ON users (email varchar_pattern_ops);
Query 2: Order history (avg 1.8s)
...
### 3. Multi-service Orchestration
User: "When a critical bug is reported, create GitHub issue, Slack alert, and Jira ticket"
Claude: [Uses GitHub MCP] Created GitHub issue #123: "Critical: Payment processing failure"
Claude: [Uses Slack MCP] Posted to #incidents: "🚨 Critical bug reported - Payment processing failure"
Claude: [Uses Jira MCP] Created Jira ticket PROJ-456 with priority: Critical
## Security Best Practices
### 1. Use environment variables
```json
{
"mcpServers": {
"github": {
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}" // ✅ Good
// "GITHUB_TOKEN": "ghp_xxxx" // ❌ Bad - hardcoded
}
}
}
}
2. Limit permissions
# GitHub: Use fine-grained tokens với minimal permissions
# - Read-only cho repos không cần write
# - Limit scope cho specific repositories
3. Project-specific configs
# Don't put production credentials in global config
# Use project-specific .mcp.json với dev credentials
4. Audit MCP usage
# Review Claude Code logs
tail -f ~/.claude/logs/mcp.log
# Check what queries are being run
Troubleshooting
MCP server not starting
# Check if server can start manually
npx -y @modelcontextprotocol/server-github
# Check environment variables
echo $GITHUB_TOKEN
Connection errors
# Verify network connectivity
curl https://api.github.com/user -H "Authorization: Bearer $GITHUB_TOKEN"
# Check DATABASE_URL format
psql $DATABASE_URL -c "SELECT 1"
Tool not available
# List available MCP tools
claude mcp list
# Restart Claude Code after adding new servers
Complete Example: DevOps Workflow
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
},
"kubernetes": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-kubernetes"],
"env": {
"KUBECONFIG": "${HOME}/.kube/config"
}
},
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}"
}
}
}
}
Workflow:
User: "Deploy the latest release to staging and notify the team"
Claude:
1. [GitHub MCP] Fetches latest release tag
2. [Kubernetes MCP] Updates staging deployment
3. [Kubernetes MCP] Monitors rollout status
4. [Slack MCP] Posts deployment notification
5. Returns summary to user
Tổng kết
MCP mở ra thế giới external integrations:
- ✅ Connect to databases, APIs, cloud services
- ✅ Real-time data access
- ✅ Custom MCP servers for internal tools
- ✅ Multi-service orchestration
Tiếp theo
Trong phần tiếp theo, chúng ta sẽ tìm hiểu Subagents — cách tạo và sử dụng specialized AI assistants.
Tài liệu tham khảo
Series này được dịch và mở rộng từ claude-howto — MIT License.