làm tíai?GitHub ↗
CHƯƠNG 07 / 16

Kết nối công cụ bằng MCP

Kết nối dịch vụ ngoài qua MCP, chọn scope, transport và cách xử lý authentication.

14 phút đọc

MCP là chuẩn mở kết nối Claude Code với hàng trăm tool và data source bên ngoài: issue tracker, database, monitoring, browser, API nội bộ. Khi bạn thấy mình đang copy dữ liệu từ tool khác dán vào chat, đó là lúc nên thêm một MCP server để Claude đọc và thao tác trực tiếp trên hệ thống đó.

7.1. MCP là gì

  • MCP (Model Context Protocol): chuẩn mở, open source cho tích hợp AI–tool.
  • MCP server: chương trình cung cấp tool, resource, prompt cho Claude Code. Chạy local (subprocess) hoặc hosted (dịch vụ qua URL).
  • Sau khi kết nối, bạn có thể yêu cầu Claude:
    • Triển khai feature từ JIRA/GitHub issue, tạo PR.
    • Phân tích dữ liệu monitoring (Sentry, Statsig).
    • Query database (PostgreSQL...).
    • Tích hợp design (Figma), tự động hoá workflow (Gmail, Slack).
    • Phản ứng với external event qua channel (Telegram, Discord, webhook).

Tìm connector đã được review tại Anthropic Directory. Mọi remote server trong Directory đều thêm được bằng claude mcp add.

Cảnh báo bảo mật: chỉ kết nối server bạn tin tưởng. Server fetch nội dung ngoài có thể tạo rủi ro prompt injection.

7.2. Các transport và cách thêm server

Claude Code hỗ trợ 4 transport. Chọn transport tùy nơi server chạy.

TransportDùng khiOAuthCờ --transport
http (streamable-http)Remote/cloud, khuyến nghị
sseRemote (deprecated, dùng http thay thế)
stdioChạy local, cần truy cập hệ thốngKhôngCó (mặc định)
ws (WebSocket)Remote push event, kết nối 2 chiềuKhông (chỉ header)Không

HTTP server (khuyến nghị cho remote)

# Cú pháp
claude mcp add --transport http <name> <url>

# Ví dụ: Notion
claude mcp add --transport http notion https://mcp.notion.com/mcp

# Với Bearer token
claude mcp add --transport http secure-api https://api.example.com/mcp \
  --header "Authorization: Bearer your-token"

Trong JSON (.mcp.json, ~/.claude.json, claude mcp add-json), field type chấp nhận streamable-http như alias của http. Một entry có url nhưng thiếu type là lỗi cấu hình — Claude Code đọc nó như stdio server và bỏ qua, báo cần thêm "type": "http" (hoặc "sse" / "ws").

SSE server (deprecated)

claude mcp add --transport sse asana https://mcp.asana.com/sse

# Với header
claude mcp add --transport sse private-api https://api.company.com/sse \
  --header "X-API-Key: your-key-here"

Stdio server (local)

Stdio server chạy như process local, phù hợp cho tool cần truy cập hệ thống, filesystem, hoặc script tùy biến.

# Cú pháp — chú ý dấu -- ngăn cách
claude mcp add [options] <name> -- <command> [args...]

# Ví dụ: Airtable
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
  -- npx -y airtable-mcp-server

# Ví dụ: Playwright (browser automation)
claude mcp add playwright -- npx -y @playwright/mcp@latest

Quy tắc dấu -- (BẮT BUỘC với stdio):

  • -- ngăn cách option của Claude (--transport, --env, --scope) với command chạy server. Mọi thứ sau -- được truyền nguyên vẹn cho server.
  • Không có --, Claude Code sẽ cố parse cờ của server (ví dụ --port) như cờ của chính nó.
  • --env nhận nhiều cặp KEY=value. Đặt ít nhất một option khác giữa --env và tên server, nếu không CLI đọc nhầm tên server thành cặp env.

Claude Code đặt biến CLAUDE_PROJECT_DIR trong môi trường server (bằng project root ổn định), đọc qua process.env.CLAUDE_PROJECT_DIR (Node) hoặc os.environ["CLAUDE_PROJECT_DIR"] (Python). Server muốn giới hạn filesystem nên dùng MCP request roots/list thay vì biến này.

WebSocket server

Chỉ cấu hình qua .mcp.json hoặc claude mcp add-json (cờ --transport không nhận ws). Auth chỉ qua header.

claude mcp add-json events-server \
  '{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer YOUR_TOKEN"}}'

Thêm từ JSON

# HTTP
claude mcp add-json weather-api '{"type":"http","url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'

# stdio
claude mcp add-json local-weather '{"type":"stdio","command":"/path/to/weather-cli","args":["--api-key","abc123"],"env":{"CACHE_DIR":"/tmp"}}'

Import từ Claude Desktop

claude mcp add-from-claude-desktop   # macOS và WSL; hiện dialog chọn server

Tên server qua lệnh claude mcp chỉ được chứa chữ, số, gạch ngang, gạch dưới; tên có ký tự khác (như dấu cách) sẽ bị bỏ qua khi import.

7.3. Scope: local / project / user

Scope quyết định server load ở project nào và có chia sẻ với team không. Scope cố định khi thêm — muốn đổi phải remove rồi add lại.

ScopeLoad ởChia sẻ teamLưu tại
local (mặc định)Chỉ project hiện tạiKhông~/.claude.json (theo path project)
projectChỉ project hiện tạiCó, qua version control.mcp.json ở project root
userTất cả project của bạnKhông~/.claude.json (key mcpServers cấp cao)

Lưu ý: "local scope" của MCP (lưu ở ~/.claude.json) khác với "local settings" chung (.claude/settings.local.json). Phiên bản cũ gọi localproject, và gọi userglobal.

# local (mặc định)
claude mcp add --transport http stripe https://mcp.stripe.com
claude mcp add --transport http stripe --scope local https://mcp.stripe.com

# project (ghi vào .mcp.json, commit được)
claude mcp add --transport http paypal --scope project https://mcp.paypal.com/mcp

# user (mọi project)
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic

Rút gọn: -s/--scope, -e/--env, -t/--transport, -H/--header.

Thứ tự ưu tiên khi trùng tên

Khi cùng một server được định nghĩa nhiều nơi, Claude Code kết nối một lần, dùng nguồn ưu tiên cao nhất (không merge field giữa các scope):

  1. Local
  2. Project
  3. User
  4. Plugin-provided servers
  5. claude.ai connectors

Ba scope so trùng theo tên. Plugin và connector so trùng theo endpoint (URL/command).

7.4. File .mcp.json

Server ở project scope lưu trong .mcp.json tại project root, thiết kế để commit vào version control cho cả team dùng chung.

{
  "mcpServers": {
    "claude-code-docs": {
      "type": "http",
      "url": "https://code.claude.com/docs/mcp"
    },
    "playwright": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest"]
    }
  }
}
  • HTTP: dùng url (và tùy chọn headers).
  • stdio: dùng commandargs (và tùy chọn env).
  • Claude Code đọc .mcp.json lúc khởi động session — sửa file xong phải thoát và mở lại session.
  • Lần đầu thấy server project scope, Claude Code hỏi approve (bảo vệ chống repo clone tự chạy process). Approve ngay, hoặc /mcp để approve sau. Reset lựa chọn: claude mcp reset-project-choices.

Environment variable expansion

.mcp.json hỗ trợ mở rộng biến môi trường, cho phép chia sẻ cấu hình mà vẫn linh hoạt với path và secret theo máy.

  • ${VAR}: giá trị của biến VAR.
  • ${VAR:-default}: VAR nếu có, ngược lại dùng default.

Mở rộng được ở: command, args, env, url, headers.

{
  "mcpServers": {
    "api-server": {
      "type": "http",
      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
      "headers": { "Authorization": "Bearer ${API_KEY}" }
    }
  }
}

Nếu biến chưa set và không có default, config vẫn load nhưng Claude Code cảnh báo missing-variable trong claude mcp list và dùng nguyên text ${VAR}.

7.5. Quản lý server

claude mcp list          # Liệt kê mọi server + trạng thái
claude mcp get github    # Chi tiết một server (scope, OAuth...)
claude mcp remove github # Xóa server

Trong session: dùng /mcp để xem trạng thái, authenticate, reconnect.

Trạng thái trong claude mcp list

Trạng tháiNghĩa
✔ ConnectedSẵn sàng dùng
! Connected · tools fetch failedKết nối được nhưng không list được tool; xem claude mcp get <name>
! Needs authenticationCần browser sign-in hoặc token qua --header
✘ Failed to connect / ✘ Connection errorServer không phản hồi / lỗi kết nối
⏸ Pending approval (run claude to approve)Server project scope chưa approve; chạy claude để duyệt

Console Windows cũ có thể hiện / × thay cho / .

Timeout và giới hạn output

Cơ chếBiến / fieldMặc định
Startup timeoutMCP_TIMEOUT (ms)30s
Tool execution timeout (per-server)field timeout (ms) trong .mcp.json, hoặc MCP_TOOL_TIMEOUT~28h
Idle timeoutCLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT (ms, 0 = tắt)5 phút (HTTP/SSE/WS), 30 phút (stdio)
Auto-background call dàiCLAUDE_CODE_MCP_AUTO_BACKGROUND_MS (ms, 0 = tắt)2 phút
Giới hạn output tokenMAX_MCP_OUTPUT_TOKENS25.000 (cảnh báo ở 10.000)
MCP_TIMEOUT=10000 claude          # startup timeout 10s
export MAX_MCP_OUTPUT_TOKENS=50000

Field timeout ví dụ "timeout": 600000 (10 phút) ghi đè MCP_TOOL_TIMEOUT cho riêng server đó; giá trị dưới 1000 bị bỏ qua.

Kết nối lại và cập nhật động

  • HTTP/SSE mất kết nối giữa session: tự reconnect với exponential backoff (tối đa 5 lần, bắt đầu 1s, gấp đôi mỗi lần). Stdio không tự reconnect.
  • MCP list_changed: server cập nhật động tool/prompt/resource mà không cần disconnect.
  • Tên dành riêng (Claude Code từ chối/skip): workspace, claude-in-chrome, computer-use, Claude Preview, Claude Browser.

7.6. OAuth và xác thực remote server

Nhiều cloud server yêu cầu xác thực; Claude Code hỗ trợ OAuth 2.0 (chỉ HTTP và SSE).

Claude Code đánh dấu server cần auth khi nhận 401 Unauthorized hoặc 403 Forbidden. Token được lưu an toàn (keychain macOS hoặc credentials file) và tự refresh.

Luồng cơ bản

# 1. Thêm server
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# 2. Trong session, mở panel và đăng nhập qua browser
/mcp

Xác thực từ command line

claude mcp login sentry              # chạy OAuth flow từ shell
claude mcp login sentry --no-browser # in URL thay vì mở browser (SSH, Linux không display)
claude mcp logout sentry             # xóa credentials

Không có browser (SSH/headless): lệnh in URL; mở trên máy local, rồi dán URL redirect đầy đủ vào prompt (cần terminal tương tác, dùng ssh -t).

Fixed callback port và pre-configured credentials

Một số server yêu cầu redirect URI đăng ký trước dạng http://localhost:PORT/callback:

# Cố định port (dynamic client registration)
claude mcp add --transport http --callback-port 8080 \
  my-server https://mcp.example.com/mcp

# Với client ID/secret có sẵn (nếu server không hỗ trợ dynamic registration)
claude mcp add --transport http \
  --client-id your-client-id --client-secret --callback-port 8080 \
  my-server https://mcp.example.com/mcp

--client-secret nhắc nhập secret ẩn; hoặc set MCP_CLIENT_SECRET cho CI. Các cờ này chỉ áp dụng HTTP/SSE, vô hiệu với stdio.

Tùy chỉnh OAuth trong .mcp.json

Trong object oauth của entry server:

FieldTác dụng
authServerMetadataUrlTrỏ tới metadata URL cụ thể, bỏ qua discovery mặc định (phải https://)
scopesChuỗi space-separated ghim scope yêu cầu (ưu tiên cao nhất)
clientId, callbackPortCredentials/port đăng ký trước
{
  "mcpServers": {
    "slack": {
      "type": "http",
      "url": "https://mcp.slack.com/mcp",
      "oauth": { "scopes": "channels:read chat:write search:read" }
    }
  }
}

Header động (auth không phải OAuth)

Với Kerberos, short-lived token, SSO nội bộ — dùng headersHelper sinh header lúc kết nối:

{
  "mcpServers": {
    "internal-api": {
      "type": "http",
      "url": "https://mcp.internal.example.com",
      "headersHelper": "/opt/bin/get-mcp-auth-headers.sh"
    }
  }
}
  • Command phải in ra stdout một JSON object các cặp key-value string.
  • Chạy trong shell, timeout 10s, từ working directory hiện tại (dùng absolute path).
  • Chạy lại mỗi lần kết nối (không cache). headersHelper chỉ chạy sau khi bạn accept workspace trust dialog khi định nghĩa ở project/local scope.

7.7. Managed MCP (kiểm soát tổ chức)

Admin kiểm soát tập trung server nào được phép chạy. Chọn pattern theo mức kiểm soát cần:

PatternLàm gìCấu hình
Disable MCPKhông server nào loadmanaged-mcp.json với server map rỗng
Fixed deploymentMọi user cùng bộ server, không thêm đượcmanaged-mcp.json với server mong muốn
Approved catalogPublish list duyệt, user tự thêm, còn lại bị chặnallowedMcpServers + allowManagedMcpServersOnly: true
Plugin servers onlyServer chỉ đến từ pluginstrictPluginOnlyCustomization chứa mcp
Soft allowlistAllowlist mà user mở rộng đượcallowedMcpServers (không có allowManagedMcpServersOnly)
Denylist onlyChặn server xấu, cho phần còn lạideniedMcpServers

managed-mcp.json

Nếu triển khai file này, Claude Code chỉ load server trong đó — user không thêm/sửa/dùng server khác (kể cả plugin server, và mặc định chặn cả claude.ai connectors). Cùng format với .mcp.json project.

Nền tảngPath
macOS/Library/Application Support/ClaudeCode/managed-mcp.json
Linux/WSL/etc/claude-code/managed-mcp.json
WindowsC:\Program Files\ClaudeCode\managed-mcp.json
{
  "mcpServers": {
    "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/" },
    "sentry": { "type": "http", "url": "https://mcp.sentry.dev/mcp" }
  }
}
  • File standalone, không giao qua server-managed settings — triển khai bằng MDM/GPO/Jamf/Intune/fleet management.
  • Mọi user trên máy đọc được file: đừng lưu API key trong env. Dùng ${VAR} expansion, OAuth/per-user header, hoặc headersHelper.
  • Disable MCP hoàn toàn: { "mcpServers": {} }.
  • Kiểm chứng: claude mcp list chỉ hiện server managed; claude mcp add ... thất bại với enterprise MCP configuration is active and has exclusive control over MCP servers.

Allowlist / denylist

allowedMcpServersdeniedMcpServers lọc server nào được load (không phải registry — server vẫn phải được thêm trước). Mỗi entry có một key:

KeySo trùngDùng cho
serverUrlURL remote, exact hoặc có wildcard *HTTP/SSE
serverCommandCommand và args chính xác của stdioStdio
serverNameNhãn user gán, exact match — KHÔNG phải cơ chế bảo mậtCả hai (dễ bị đặt lại tên)

Thứ tự đánh giá: (1) merge list mọi nguồn, (2) check denylist — trùng là chặn, không gì ghi đè được, (3) check allowlist. Đặt allowManagedMcpServersOnly: true trong managed settings để chỉ allowlist managed có hiệu lực (denylist luôn merge mọi nguồn).

{
  "allowedMcpServers": [
    { "serverUrl": "https://api.githubcopilot.com/*" },
    { "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."] }
  ],
  "deniedMcpServers": [
    { "serverName": "dangerous-server" },
    { "serverUrl": "https://*.untrusted.example.com/*" }
  ]
}

Wildcard URL: https://mcp.example.com/* (mọi path), https://*.example.com/* (mọi subdomain), http://localhost:*/* (mọi port), *://mcp.example.com/* (mọi scheme). Command phải match chính xác từng argument.

Để enforce đáng tin cậy, dùng serverCommand/serverUrl (literal, không phụ thuộc biến môi trường), không dựa vào serverName.

7.8. Dùng MCP tool, resource, prompt

Tool

Sau khi kết nối, MCP tool xuất hiện tự nhiên — Claude tự chọn tool phù hợp. Lần đầu gọi, Claude hỏi permission. Tên tool đầy đủ dạng mcp__<server>__<tool>; với plugin: mcp__plugin_<plugin>_<server>__<tool>. Dùng tên đầy đủ này trong permission rule, allowed-tools của skill, tools của subagent, hoặc hook matcher.

Tool search (mặc định bật): tool được defer, chỉ load tên và server instruction lúc khởi động, nên thêm nhiều server ít ảnh hưởng context. Điều chỉnh qua ENABLE_TOOL_SEARCH:

Giá trịHành vi
(unset)Defer hết, load theo yêu cầu (mặc định)
trueDefer hết, gửi beta header kể cả trên proxy
auto / auto:NLoad upfront nếu vừa trong 10% (hoặc N%) context, defer phần dư
falseLoad hết upfront

Miễn defer một server (luôn load): thêm "alwaysLoad": true vào entry của nó trong .mcp.json.

Resource

MCP server có thể expose resource, tham chiếu bằng @ mention giống file.

# Gõ @ để thấy resource từ mọi server đã kết nối
Can you analyze @github:issue://123 and suggest a fix?
Please review the API documentation at @docs:file://api/authentication
Compare @postgres:schema://users with @docs:file://database/user-model

Format: @server:protocol://resource/path. Resource tự fetch và đính kèm khi tham chiếu; path fuzzy-searchable trong autocomplete.

Prompt (slash command)

MCP server có thể expose prompt thành slash command. Gõ / để thấy, format /mcp__servername__promptname:

/mcp__github__list_prs
/mcp__github__pr_review 456
/mcp__jira__create_issue "Bug in login flow" high

Argument truyền space-separated sau command; kết quả prompt được inject trực tiếp vào hội thoại.

Elicitation

Server có thể yêu cầu input giữa chừng: Claude Code hiện dialog form (điền field) hoặc mở URL (auth/approve trong browser). Không cần cấu hình. Tự động phản hồi bằng Elicitation hook.

7.9. Các trường hợp khác

Plugin-provided servers

Plugin có thể bundle MCP server (định nghĩa trong .mcp.json ở plugin root hoặc inline plugin.json). Server tự start khi plugin bật; quản lý qua cài đặt plugin, không qua /mcp. Placeholder: ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA}, ${CLAUDE_PROJECT_DIR}. Bật/tắt plugin giữa session thì chạy /reload-plugins.

claude.ai connectors

Đăng nhập Claude Code bằng tài khoản claude.ai thì connector thêm ở claude.ai tự động khả dụng. Thêm tại claude.ai/customize/connectors (Team/Enterprise: chỉ admin). Xem/quản lý bằng /mcp.

  • Chỉ load khi auth method đang dùng là claude.ai subscription login (không load khi dùng ANTHROPIC_API_KEY, Bedrock, Vertex...).
  • Tắt hết: disableClaudeAiConnectors: true (bất kỳ scope), hoặc ENABLE_CLAUDEAI_MCP_SERVERS=false.
  • Chặn từng cái: thêm vào deniedMcpServers theo serverName (vd "claude.ai Slack") hoặc serverUrl.

Claude Code làm MCP server

claude mcp serve   # chạy Claude như stdio MCP server

Cấu hình trong claude_desktop_config.json để dùng từ Claude Desktop; expose tool View/Edit/LS... Nếu claude không trong PATH, dùng full path (which claude) để tránh spawn claude ENOENT.

7.10. Troubleshooting nhanh

Triệu chứngXử lý
/mcp hiện "No MCP servers configured"Bạn add ở project khác (local scope gắn với project), hoặc sửa file sai path. File đúng: ~/.claude.json<project>/.mcp.json
Failed to connect / Connection errorHTTP: curl -I <url> (404/405 = server sống; 401/403 = cần auth). Stdio: chạy command trực tiếp để xem lỗi; kiểm tra dấu --
Connection timed out at startupMCP_TIMEOUT=60000 claude (stdio lần đầu tải npx package chậm)
Server already existsTrùng tên cùng scope; claude mcp remove <name> hoặc đổi tên
Kết nối nhưng không có toolThiếu env var (vd API key); truyền --env KEY=value hoặc field env
Sửa .mcp.json không có tác dụngĐọc lúc khởi động — thoát và mở lại session; đã reject trước đó thì claude mcp reset-project-choices
OAuth thất bại / browser không mở/mcp → chọn server → Authenticate; copy URL mở tay

Xem thêm

  • content/en/docs/claude-code/mcp.md — MCP reference đầy đủ (transport, scope, OAuth, tool search).
  • content/en/docs/claude-code/mcp-quickstart.md — hướng dẫn kết nối một server end-to-end.
  • content/en/docs/claude-code/managed-mcp.md — kiểm soát MCP cho tổ chức (managed-mcp.json, allow/deny list).
  • content/en/docs/claude-code/plugins.md — bundle MCP server trong plugin.
  • content/en/docs/claude-code/settings.mddisableClaudeAiConnectors, allowedMcpServers, deniedMcpServers.
  • https://modelcontextprotocol.io — chuẩn MCP và hướng dẫn build server.
  • https://claude.ai/directory — Anthropic Directory (connector đã review).
Nguồn của chương

Tài liệu chính thức duy nhất từ Anthropic.

Claude Code docs
Trở về mục lục