Bỏ qua để đến nội dung

Kết nối tool bên ngoài bằng MCP

Bài viết được dịch tự động từ bài viết gốc, chưa được kiểm tra lại bởi con người. Chỉ những bài viết có dấu tick xanh cạnh tiêu đề là đã được kiểm tra.

Model Context Protocol (MCP) là một chuẩn mở để kết nối các agent AI với tool và nguồn dữ liệu bên ngoài. Với MCP, agent của bạn có thể truy vấn cơ sở dữ liệu, tích hợp với các API như Slack và GitHub, và kết nối tới các dịch vụ khác mà không cần tự viết tool.

MCP server có thể chạy dưới dạng process cục bộ, kết nối qua HTTP, hoặc thực thi trực tiếp trong ứng dụng SDK của bạn.

Ví dụ này kết nối tới MCP server tài liệu Claude Code documentation qua HTTP transport và dùng allowedTools với wildcard để cho phép mọi tool từ server.

import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Use the docs MCP server to explain what hooks are in Claude Code",
options: {
mcpServers: {
"claude-code-docs": {
type: "http",
url: "https://code.claude.com/docs/mcp"
}
},
allowedTools: ["mcp__claude-code-docs__*"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"claude-code-docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp",
}
},
allowed_tools=["mcp__claude-code-docs__*"],
)
async for message in query(
prompt="Use the docs MCP server to explain what hooks are in Claude Code",
options=options,
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())

Agent kết nối tới server tài liệu, tìm kiếm thông tin về hooks, và trả về kết quả.

Bạn có thể cấu hình MCP server trong code khi gọi query(), hoặc trong file .mcp.json được nạp qua settingSources.

Truyền MCP server trực tiếp qua tùy chọn mcpServers:

import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "List files in my project",
options: {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
},
allowedTools: ["mcp__filesystem__*"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/me/projects",
],
}
},
allowed_tools=["mcp__filesystem__*"],
)
async for message in query(prompt="List files in my project", options=options):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())

Tạo một file .mcp.json ở gốc dự án. File này được nạp khi nguồn cấu hình project được bật, mặc định đã bật với tùy chọn query() mặc định. Nếu bạn đặt settingSources một cách tường minh, hãy bao gồm "project" để file này được nạp:

{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}

Các server bạn truyền trong options.mcpServers bắt đầu kết nối ngay khi query bắt đầu. Việc kết nối không chặn (non-blocking) theo mặc định: lượt đầu tiên bắt đầu ngay mà không chờ, và tool của mỗi server trở nên khả dụng ngay khi kết nối của nó hoàn tất. Trước Claude Code v2.1.142, việc khởi động bị chặn tối đa 5 giây để chờ nhóm kết nối hoàn tất.

Để khôi phục việc chờ khởi động có giới hạn cho mọi server, đặt biến môi trường MCP_CONNECTION_NONBLOCKING thành 0. Thời gian chờ tối đa là 5 giây theo MCP_CONNECT_TIMEOUT_MS, và các server vẫn đang chờ khi hết hạn sẽ tiếp tục kết nối trong nền.

Để làm cho tool của một server khả dụng trước lượt đầu tiên, đặt alwaysLoad: true trong cấu hình của server đó. Lúc này khởi động sẽ chờ server đó kết nối, giới hạn ở cùng mốc 5 giây, trong khi các server khác vẫn tiếp tục kết nối trong nền. Trường alwaysLoad yêu cầu Claude Code v2.1.121 trở lên.

Message system với subtype init báo cáo trạng thái của mỗi server tại thời điểm nó được phát ra. Server còn đang kết nối có trạng thái pending. Hãy kiểm tra trạng thái failed hoặc needs-auth để phát hiện server sẽ không dùng được, thay vì coi mọi trạng thái khác connected là lỗi; xem Xử lý lỗi bên dưới để biết cách kiểm tra đầy đủ.

MCP tool cần được cấp quyền tường minh trước khi Claude có thể dùng. Không có quyền, Claude sẽ thấy tool khả dụng nhưng không thể gọi.

MCP tool theo mẫu tên mcp__<server-name>__<tool-name>. Ví dụ, một server GitHub tên "github" với tool list_issues sẽ trở thành mcp__github__list_issues.

Dùng allowedTools để duyệt trước các MCP tool cụ thể sao cho Claude có thể dùng chúng mà không cần prompt xin quyền:

const _ = {
options: {
mcpServers: {
// các server của bạn
},
allowedTools: [
"mcp__github__*", // Mọi tool từ server github
"mcp__db__query", // Chỉ tool query từ server db
"mcp__slack__send_message" // Chỉ send_message từ server slack
]
}
};
options = ClaudeAgentOptions(
mcp_servers={
# các server của bạn
},
allowed_tools=[
"mcp__github__*", # Mọi tool từ server github
"mcp__db__query", # Chỉ tool query từ server db
"mcp__slack__send_message", # Chỉ send_message từ server slack
],
)

Wildcard (*) cho phép bạn duyệt mọi tool từ một server mà không cần liệt kê từng tool.

Để xem tool nào một MCP server cung cấp, kiểm tra tài liệu của server hoặc xem mảng tools trong message init hệ thống. Tên MCP tool luôn bắt đầu bằng mcp__.

MCP server kết nối trong nền theo mặc định, nên message init đến trước khi chúng kết nối xong: mảng tools chỉ liệt kê built-in tool và mcp_servers hiển thị trạng thái pending cho mỗi server. Đặt biến môi trường MCP_CONNECTION_NONBLOCKING thành 0 để chờ tối đa 5 giây cho server kết nối trước khi message init được gửi; các server kịp kết nối sẽ liệt kê tool mcp__ của chúng ở đó, còn server chậm hơn tiếp tục kết nối trong nền:

Terminal window
export MCP_CONNECTION_NONBLOCKING=0

Với biến này được đặt, bộ lọc sau in ra tên các MCP tool:

import { query } from "@anthropic-ai/claude-agent-sdk";
const options = {
mcpServers: {
// các server của bạn
},
};
for await (const message of query({ prompt: "...", options })) {
if (message.type === "system" && message.subtype === "init") {
const mcpTools = message.tools.filter((name) => name.startsWith("mcp__"));
console.log("Available MCP tools:", mcpTools);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
# các server của bạn
},
)
async for message in query(prompt="...", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
mcp_tools = [t for t in message.data.get("tools", []) if t.startswith("mcp__")]
print("Available MCP tools:", mcp_tools)
asyncio.run(main())

Bạn cũng có thể hỏi Claude liệt kê tool khả dụng từ một server.

MCP server giao tiếp với agent của bạn bằng các giao thức transport khác nhau. Kiểm tra tài liệu của server để biết transport nào nó hỗ trợ:

  • Nếu tài liệu cho bạn một lệnh để chạy (như npx @modelcontextprotocol/server-filesystem), dùng stdio
  • Nếu tài liệu cho bạn một URL, dùng HTTP hoặc SSE
  • Nếu bạn tự xây dựng tool trong code, dùng SDK MCP server

Process cục bộ giao tiếp qua stdin/stdout. Dùng cho các MCP server bạn chạy trên cùng máy.

const _ = {
options: {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
},
allowedTools: ["mcp__filesystem__read_file", "mcp__filesystem__list_directory"]
}
};
options = ClaudeAgentOptions(
mcp_servers={
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/me/projects",
],
}
},
allowed_tools=["mcp__filesystem__read_file", "mcp__filesystem__list_directory"],
)

Trong .mcp.json:

{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}

Dùng HTTP hoặc SSE cho MCP server chạy trên cloud và API từ xa:

const _ = {
options: {
mcpServers: {
"remote-api": {
type: "sse",
url: "https://api.example.com/mcp/sse",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`
}
}
},
allowedTools: ["mcp__remote-api__*"]
}
};
options = ClaudeAgentOptions(
mcp_servers={
"remote-api": {
"type": "sse",
"url": "https://api.example.com/mcp/sse",
"headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
}
},
allowed_tools=["mcp__remote-api__*"],
)

Trong .mcp.json:

{
"mcpServers": {
"remote-api": {
"type": "sse",
"url": "https://api.example.com/mcp/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}

Với transport streamable HTTP, dùng "type": "http" thay vào đó. Trong .mcp.json và các file config JSON khác, "streamable-http" được chấp nhận như một tên gọi khác của "http". Tùy chọn mcpServers trong code chỉ chấp nhận "http".

Định nghĩa tool tùy chỉnh trực tiếp trong code ứng dụng của bạn thay vì chạy một process server riêng. Xem hướng dẫn tool tùy chỉnh để biết chi tiết triển khai.

Khi bạn cấu hình nhiều MCP tool, các định nghĩa tool có thể chiếm một phần đáng kể context window. Tool search giải quyết vấn đề này bằng cách giữ lại định nghĩa tool ngoài context và chỉ nạp những tool Claude cần cho mỗi lượt.

Tool search được bật mặc định. Xem Tool search để biết tùy chọn cấu hình, best practice, và cách dùng tool search với SDK tool tùy chỉnh.

Hầu hết MCP server cần xác thực để truy cập dịch vụ bên ngoài. Truyền thông tin xác thực qua biến môi trường trong cấu hình server.

Truyền thông tin xác thực qua biến môi trường

Phần tiêu đề “Truyền thông tin xác thực qua biến môi trường”

Dùng trường env để truyền API key, token, và các thông tin xác thực khác cho MCP server:

const _ = {
options: {
mcpServers: {
"api-server": {
command: "npx",
args: ["-y", "@your-org/api-mcp-server"],
env: {
API_KEY: process.env.API_KEY
}
}
},
allowedTools: ["mcp__api-server__*"]
}
};
options = ClaudeAgentOptions(
mcp_servers={
"api-server": {
"command": "npx",
"args": ["-y", "@your-org/api-mcp-server"],
"env": {"API_KEY": os.environ["API_KEY"]},
}
},
allowed_tools=["mcp__api-server__*"],
)

Trong .mcp.json, cú pháp ${API_KEY} giãn nở biến môi trường tại thời điểm chạy.

Với server HTTP và SSE, truyền header xác thực trực tiếp trong cấu hình server:

const _ = {
options: {
mcpServers: {
"secure-api": {
type: "http",
url: "https://api.example.com/mcp",
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`
}
}
},
allowedTools: ["mcp__secure-api__*"]
}
};
options = ClaudeAgentOptions(
mcp_servers={
"secure-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
}
},
allowed_tools=["mcp__secure-api__*"],
)

Đặc tả MCP hỗ trợ OAuth 2.1 cho việc cấp quyền. SDK không mở trình duyệt hay chạy luồng OAuth tương tác. Khi một server đã cấu hình trả về thử thách xác thực và không có token lưu sẵn, phiên agent tiếp tục chạy mà không có tool của server đó, và server báo trạng thái needs-auth. Vì server kết nối trong nền theo mặc định, mảng mcp_servers trong message init hệ thống có thể vẫn hiển thị pending cho server đó. Để xác nhận server có cần thông tin xác thực hay không, hãy poll mcpServerStatus() trong TypeScript SDK hoặc get_mcp_status() trong Python, hoặc đặt MCP_CONNECTION_NONBLOCKING=0 để chờ kết nối trước khi message init được gửi.

Để cung cấp thông tin xác thực, hoàn tất luồng OAuth trong ứng dụng của bạn và truyền access token nhận được vào headers của server:

// Sau khi hoàn tất luồng OAuth trong ứng dụng của bạn.
// Tự triển khai getAccessTokenFromOAuthFlow cho nhà cung cấp OAuth của bạn.
const accessToken = await getAccessTokenFromOAuthFlow();
const options = {
mcpServers: {
"oauth-api": {
type: "http",
url: "https://api.example.com/mcp",
headers: {
Authorization: `Bearer ${accessToken}`
}
}
},
allowedTools: ["mcp__oauth-api__*"]
};
# Sau khi hoàn tất luồng OAuth trong ứng dụng của bạn.
# Tự triển khai get_access_token_from_oauth_flow cho nhà cung cấp OAuth của bạn.
access_token = await get_access_token_from_oauth_flow()
options = ClaudeAgentOptions(
mcp_servers={
"oauth-api": {
"type": "http",
"url": "https://api.example.com/mcp",
"headers": {"Authorization": f"Bearer {access_token}"},
}
},
allowed_tools=["mcp__oauth-api__*"],
)

Ví dụ này kết nối tới GitHub MCP server từ xa để liệt kê các issue gần đây. Trước khi chạy, tạo một GitHub personal access token với quyền đọc các repository bạn muốn truy vấn và đặt nó dưới dạng biến môi trường:

Terminal window
export GITHUB_TOKEN=YOUR_GITHUB_PAT
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "List the 3 most recent issues in anthropics/claude-code",
options: {
mcpServers: {
github: {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
headers: {
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`
}
}
},
allowedTools: ["mcp__github__list_issues"]
}
})) {
// Xác nhận MCP server đã kết nối thành công
if (message.type === "system" && message.subtype === "init") {
console.log("MCP servers:", message.mcp_servers);
}
// Log khi Claude gọi một MCP tool
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "tool_use" && block.name.startsWith("mcp__")) {
console.log("MCP tool called:", block.name);
}
}
}
// In kết quả cuối cùng
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
import asyncio
import os
from claude_agent_sdk import (
query,
ClaudeAgentOptions,
ResultMessage,
SystemMessage,
AssistantMessage,
)
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"},
}
},
allowed_tools=["mcp__github__list_issues"],
)
async for message in query(
prompt="List the 3 most recent issues in anthropics/claude-code",
options=options,
):
# Xác nhận MCP server đã kết nối thành công
if isinstance(message, SystemMessage) and message.subtype == "init":
print("MCP servers:", message.data.get("mcp_servers"))
# Log khi Claude gọi một MCP tool
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "name") and block.name.startswith("mcp__"):
print("MCP tool called:", block.name)
# In kết quả cuối cùng
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())

Ví dụ này dùng DBHub để truy vấn cơ sở dữ liệu Postgres. Agent tự động khám phá schema, viết câu SQL, và trả về kết quả.

Tool execute_sql của DBHub chạy bất kỳ SQL nào agent phát ra, kể cả lệnh ghi, trừ khi bạn giới hạn nó. Đặt readonly = true trong file cấu hình DBHub khiến DBHub từ chối INSERT, UPDATE, DELETE, và các câu DDL, nên ví dụ này không thể sửa dữ liệu của bạn kể cả khi agent phát ra lệnh ghi. DBHub giãn nở ${DATABASE_URL} từ biến môi trường process khi nạp cấu hình, nên chuỗi kết nối không nằm trong file. Tạo file dbhub.toml này cạnh script của bạn:

[[sources]]
id = "production"
dsn = "${DATABASE_URL}"
[[tools]]
name = "execute_sql"
source = "production"
readonly = true

Script sau đó trỏ DBHub vào file config thay vì truyền trực tiếp chuỗi kết nối. Trước khi chạy, đặt biến môi trường DATABASE_URL bằng chuỗi kết nối của bạn:

Terminal window
export DATABASE_URL=postgresql://user:password@localhost:5432/mydb
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
// Truy vấn bằng ngôn ngữ tự nhiên - Claude viết SQL
prompt: "How many users signed up last week? Break it down by day.",
options: {
mcpServers: {
postgres: {
command: "npx",
// dbhub.toml đặt readonly = true, nên execute_sql từ chối lệnh ghi
args: ["-y", "@bytebase/dbhub", "--config", "dbhub.toml"]
}
},
allowedTools: ["mcp__postgres__execute_sql"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
options = ClaudeAgentOptions(
mcp_servers={
"postgres": {
"command": "npx",
# dbhub.toml đặt readonly = true, nên execute_sql từ chối lệnh ghi
"args": [
"-y",
"@bytebase/dbhub",
"--config",
"dbhub.toml",
],
}
},
allowed_tools=["mcp__postgres__execute_sql"],
)
# Truy vấn bằng ngôn ngữ tự nhiên - Claude viết SQL
async for message in query(
prompt="How many users signed up last week? Break it down by day.",
options=options,
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
asyncio.run(main())

MCP server có thể kết nối thất bại vì nhiều lý do: process server chưa được cài, thông tin xác thực sai, hoặc server từ xa không thể truy cập.

SDK phát ra message system với subtype init lúc bắt đầu mỗi query. Message này bao gồm trạng thái kết nối cho từng MCP server. Trường status có thể là "pending", "connected", "failed", "needs-auth", hoặc "disabled". Vì kết nối không chặn theo mặc định, server hoạt động tốt vẫn có thể báo "pending" khi message init được phát ra. Hãy kiểm tra "failed" hoặc "needs-auth" để phát hiện server không dùng được, và đừng coi "pending" là lỗi:

import { query } from "@anthropic-ai/claude-agent-sdk";
try {
for await (const message of query({
prompt: "Process data",
options: {
mcpServers: {
// Thay dataServer bằng cấu hình server của bạn
"data-processor": dataServer
}
}
})) {
if (message.type === "system" && message.subtype === "init") {
const unavailableServers = message.mcp_servers.filter(
(s) => s.status === "failed" || s.status === "needs-auth"
);
if (unavailableServers.length > 0) {
console.warn("Unavailable MCP servers:", unavailableServers);
}
}
if (message.type === "result" && message.subtype === "error_during_execution") {
console.error("Execution failed");
}
}
} catch (error) {
// query() một lượt sẽ throw sau khi trả về một kết quả lỗi. Nếu lỗi
// là một kết quả lỗi, nhánh subtype ở trên đã chạy; process không
// khởi động được hoặc không kết nối được sẽ không phát ra message
// kết quả nào. MCP server kết nối thất bại không throw: dùng cách
// kiểm tra trạng thái ở trên, và lưu ý server còn "pending" lúc init
// cần kiểm tra trạng thái sau đó.
console.log(`Session ended with an error: ${error}`);
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage, ResultMessage
async def main():
# Thay data_server bằng cấu hình server của bạn
options = ClaudeAgentOptions(mcp_servers={"data-processor": data_server})
try:
async for message in query(prompt="Process data", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
unavailable_servers = [
s
for s in message.data.get("mcp_servers", [])
if s.get("status") in ("failed", "needs-auth")
]
if unavailable_servers:
print(f"Unavailable MCP servers: {unavailable_servers}")
if (
isinstance(message, ResultMessage)
and message.subtype == "error_during_execution"
):
print("Execution failed")
except Exception as error:
# query() một lượt sẽ raise sau khi trả về một kết quả lỗi. Nếu lỗi
# là một kết quả lỗi, nhánh subtype ở trên đã chạy; process không
# khởi động được hoặc không kết nối được sẽ không phát ra message
# kết quả nào. MCP server kết nối thất bại không raise: dùng cách
# kiểm tra trạng thái ở trên, và lưu ý server còn "pending" lúc init
# cần kiểm tra trạng thái sau đó.
print(f"Session ended with an error: {error}")
asyncio.run(main())

Kiểm tra message init để biết server nào kết nối thất bại:

if (message.type === "system" && message.subtype === "init") {
for (const server of message.mcp_servers) {
if (server.status === "failed") {
console.error(`Server ${server.name} failed to connect`);
}
}
}
if isinstance(message, SystemMessage) and message.subtype == "init":
for server in message.data.get("mcp_servers", []):
if server.get("status") == "failed":
print(f"Server {server['name']} failed to connect")

Trạng thái "pending" nghĩa là server còn đang kết nối, không phải thất bại. Để lấy trạng thái cập nhật sau đó trong phiên, gọi phương thức mcpServerStatus() của query trong TypeScript SDK, hoặc ClaudeSDKClient.get_mcp_status() trong Python.

Nguyên nhân phổ biến:

  • Thiếu biến môi trường: đảm bảo token và thông tin xác thực cần thiết đã được đặt. Với stdio server, kiểm tra trường env khớp với những gì server yêu cầu.
  • Server chưa được cài: với lệnh npx, xác nhận package tồn tại và Node.js nằm trong PATH.
  • Chuỗi kết nối không hợp lệ: với server cơ sở dữ liệu, xác nhận định dạng chuỗi kết nối và cơ sở dữ liệu có thể truy cập được.
  • Sự cố mạng: với server HTTP/SSE từ xa, kiểm tra URL có thể truy cập và firewall cho phép kết nối.

Nếu Claude thấy tool nhưng không dùng, kiểm tra bạn đã cấp quyền bằng allowedTools chưa:

const _ = {
options: {
mcpServers: {
// các server của bạn
},
allowedTools: ["mcp__servername__*"] // Tự động duyệt lệnh gọi từ server này
}
};
options = ClaudeAgentOptions(
mcp_servers={
# các server của bạn
},
allowed_tools=["mcp__servername__*"], # Tự động duyệt lệnh gọi từ server này
)

Kết nối MCP server hết hạn sau 30 giây theo mặc định. Nếu server của bạn cần nhiều thời gian hơn để khởi động, kết nối sẽ thất bại. Tăng giới hạn với biến môi trường MCP_TIMEOUT, tính bằng mili-giây. Với server cần nhiều thời gian khởi động hơn, cân nhắc thêm:

  • Dùng một server nhẹ hơn nếu có
  • Khởi động trước (pre-warm) server trước khi bắt đầu agent
  • Kiểm tra log server để tìm nguyên nhân khởi tạo chậm

Kết quả tool vượt quá số token tối đa cho phép

Phần tiêu đề “Kết quả tool vượt quá số token tối đa cho phép”

SDK áp dụng cùng giới hạn output MCP như Claude Code. Khi kết quả tool lớn hơn 25.000 token, toàn bộ output được lưu vào file và kết quả tool được thay bằng một thông báo lỗi nêu tên đường dẫn file, để agent có thể đọc lại output theo từng phần. Tăng giới hạn với biến môi trường MAX_MCP_OUTPUT_TOKENS.

  • Hướng dẫn tool tùy chỉnh: xây dựng MCP server của riêng bạn chạy cùng process với ứng dụng SDK
  • Permissions: kiểm soát MCP tool nào agent của bạn có thể dùng qua allowedToolsdisallowedTools
  • Kho MCP server: duyệt các MCP server khả dụng cho cơ sở dữ liệu, API, và nhiều hơn nữa