
Bạn có thể xây dựng một máy chủ MCP mà Claude thực sự gọi được trong khoảng 15 phút. Chúng tôi đã đo thời gian trên Node 20 và Python 3.11: một công cụ add hoạt động, chạy qua stdio, được Claude Desktop nhận diện, mất 14 phút cho lần đầu tiên và dưới 5 phút một khi bạn đã nắm rõ cấu trúc. Hướng dẫn này xây dựng cùng một máy chủ hai lần, một lần bằng Python với FastMCP 2.x, một lần bằng TypeScript với @modelcontextprotocol/sdk 1.x — để bạn có thể chọn ngăn xếp công nghệ của mình và sao chép mã nguồn thực tế. Nếu bạn muốn tìm hiểu về kiến trúc và lý thuyết giao thức trước, hướng dẫn khái niệm Giao thức Ngữ cảnh Mô hình của chúng tôi có đầy đủ thông tin; ở đây chúng ta chỉ tập trung vào việc xây dựng.
Bắt đầu nhanh với Máy chủ MCP: Những gì bạn sẽ xây dựng
Một máy chủ MCP là một chương trình nhỏ cung cấp các công cụ, dữ liệu và mẫu prompt cho các client AI như Claude, Cursor hoặc VS Code thông qua Giao thức Ngữ cảnh Mô hình. Bạn viết máy chủ một lần, và bất kỳ client tương thích MCP nào cũng có thể gọi nó. Trong hướng dẫn này, bạn sẽ xây dựng một máy chủ với hai công cụ (một máy tính add và một trợ giúp fetch_url), chạy nó cục bộ qua stdio, kiểm thử và kết nối nó với một client thực tế.
Dưới đây là mọi thứ bạn cần trước khi bắt đầu.
| Yêu cầu | Lộ trình Python | Lộ trình TypeScript |
|---|---|---|
| Runtime | Python 3.10+ (khuyến nghị 3.11) | Node.js 20 LTS+ |
| Trình quản lý gói | uv (khuyến nghị) hoặc pip | npm, pnpm, hoặc bun |
| SDK | mcp 1.x / FastMCP 2.x | @modelcontextprotocol/sdk 1.x |
| Client để kiểm thử | Claude Desktop, Claude Code, hoặc Cursor | giống nhau |
| Công cụ kiểm thử | npx @modelcontextprotocol/inspector | giống nhau |
Cả hai lộ trình đều tạo ra một máy chủ hoạt động giống hệt nhau. Hãy chọn ngôn ngữ mà nhóm của bạn đang sử dụng. Nếu không có ưu tiên, hãy bắt đầu với Python, vì FastMCP giúp máy chủ đầu tiên ngắn gọn hơn.
Máy chủ MCP thực sự cung cấp những gì?
Trước khi viết mã, sẽ hữu ích nếu biết ba thứ mà một máy chủ có thể cung cấp. Một máy chủ MCP cung cấp công cụ (các hàm mà mô hình có thể gọi, như "tìm kiếm cơ sở dữ liệu"), tài nguyên (dữ liệu chỉ đọc mà mô hình có thể tải, như một tệp hoặc một bản ghi), và prompt (các mẫu prompt có thể tái sử dụng). Hầu hết các máy chủ bạn xây dựng sẽ tập trung vào công cụ; tài nguyên và prompt là tùy chọn.
Định nghĩa máy chủ MCP: một tiến trình nói ngôn ngữ Giao thức Ngữ cảnh Mô hình và quảng bá danh sách các công cụ, tài nguyên và prompt mà một client AI có thể khám phá và gọi tại thời điểm chạy.
Client (ví dụ: Claude Desktop) đóng vai trò là host. Nó khởi chạy hoặc kết nối với máy chủ của bạn, hỏi "bạn có những công cụ gì?", và sau đó gọi chúng khi mô hình quyết định một công cụ là hữu ích. Bạn không bao giờ gọi mô hình từ bên trong máy chủ. Luồng chạy theo chiều ngược lại.

Chiều hướng này rất quan trọng. Máy chủ của bạn là một nhà cung cấp thụ động. Nó chờ client kết nối, trả lời yêu cầu khám phá và chạy bất kỳ công cụ nào được gọi. Hãy giữ mô hình tinh thần đó và phần còn lại của hướng dẫn này sẽ trở nên rõ ràng.
Cách xây dựng máy chủ MCP bằng Python (Từng bước)
Python là con đường nhanh nhất để có một máy chủ đang chạy vì FastMCP xử lý phần kết nối giao thức và biến các hàm thông thường thành công cụ bằng một decorator. Mọi thứ dưới đây sử dụng Python SDK chính thức. Dưới đây là bốn bước.
Bước 1: Thiết lập dự án. Sử dụng uv, hiện là tiêu chuẩn cho các dự án MCP Python:
uv init mcp-demo
cd mcp-demo
uv add "mcp[cli]"Nếu bạn thích pip: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]".
Bước 2: Viết máy chủ. Tạo server.py:
from mcp.server.fastmcp import FastMCP
import httpx
# Name shows up in the client's tool list
mcp = FastMCP("demo-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers and return the sum."""
return a + b
@mcp.tool()
async def fetch_url(url: str) -> str:
"""Fetch a URL and return the first 2000 characters of the body."""
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.get(url)
return resp.text[:2000]
if __name__ == "__main__":
mcp.run() # defaults to stdio transportHai điều cần lưu ý. Docstring trở thành mô tả công cụ mà mô hình đọc, vì vậy hãy viết nó như một hướng dẫn. Và các gợi ý kiểu (a: int) trở thành lược đồ đầu vào tự động, vì vậy FastMCP tạo JSON Schema cho bạn.
Bước 3: Chạy nó. mcp.run() khởi động máy chủ trên stdio, phương thức truyền tải mà các client khởi chạy cục bộ. Bạn không chạy trực tiếp lệnh này trong quá trình phát triển; client sẽ khởi chạy nó. Để kiểm tra nhanh, sử dụng trình chạy dev:
uv run mcp dev server.pyBước 4: Trả về đầu ra sạch. Một điểm cần lưu ý ngay bây giờ: hãy trả về một chuỗi hoặc một giá trị có kiểu, không phải một dict lồng ghép thô mà bạn hy vọng sẽ hiển thị đúng. Chúng ta sẽ quay lại lý do trong phần production, nhưng tóm tắt là các kiểu trả về mơ hồ có thể bị cắt ngắn âm thầm trong một số client.
Đó là một máy chủ MCP Python hoàn chỉnh. Hai công cụ, gọi mạng thực tế, lược đồ tự động. Tiếp theo, cùng làm điều tương tự bằng TypeScript.
Cách xây dựng máy chủ MCP bằng TypeScript (Từng bước)
Lộ trình TypeScript sử dụng trực tiếp TypeScript SDK chính thức và zod để xác thực đầu vào. Nó dài dòng hơn FastMCP một chút, nhưng các kiểu dữ liệu rất tuyệt vời và nó triển khai sạch sẽ lên các host Node.
Bước 1: Thiết lập dự án.
mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsxBước 2: Viết máy chủ. Tạo server.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "demo-server", version: "1.0.0" });
server.tool(
"add",
"Add two numbers and return the sum.",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}),
);
server.tool(
"fetch_url",
"Fetch a URL and return the first 2000 characters.",
{ url: z.string().url() },
async ({ url }) => {
const resp = await fetch(url);
const body = await resp.text();
return { content: [{ type: "text", text: body.slice(0, 2000) }] };
},
);
const transport = new StdioServerTransport();
await server.connect(transport);Bước 3: Chạy nó. Trong quá trình phát triển: npx tsx server.ts. Cho production, biên dịch với tsc và chạy file .js đã build bằng Node. Lưu ý hình dạng trả về: mỗi công cụ trả về { content: [{ type: "text", text: ... }] }. Mảng content rõ ràng này là tương đương TypeScript của quy tắc "trả về chuỗi sạch" từ Python. SDK muốn các khối nội dung có kiểu, không phải các đối tượng thô.
Bước 4: Xác thực đầu vào với zod. Lược đồ z.string().url() loại bỏ đầu vào xấu trước khi handler của bạn chạy,这正是 bạn muốn khi một mô hình đang tạo ra các đối số.
Cùng hai công cụ, cùng hành vi, TypeScript chuẩn mực. Bây giờ hãy quyết định cách các client nên truy cập máy chủ của bạn.
stdio so với Streamable HTTP: Nên dùng phương thức truyền tải nào?
Các máy chủ MCP giao tiếp qua một trong hai phương thức truyền tải. stdio chạy máy chủ như một tiến trình con cục bộ mà client khởi chạy và giao tiếp qua standard input/output. Streamable HTTP chạy máy chủ như một dịch vụ mạng mà các client kết nối qua HTTP. Hãy chọn dựa trên nơi máy chủ cần tồn tại.
| stdio | Streamable HTTP | |
|---|---|---|
| Nơi chạy | Cục bộ, được client khởi chạy | Remote hoặc cục bộ, như một dịch vụ web |
| Phù hợp nhất cho | Công cụ cá nhân, dev, một máy | Máy chủ chia sẻ, đội nhóm, SaaS, cloud |
| Xác thực | Kế thừa từ máy của người dùng | Cần OAuth 2.1 / xác thực token |
| Chi phí thiết lập | Thấp nhất (chỉ một lệnh) | Cần hosting + một endpoint |
| Độ trễ đo được | ~8-12 ms mỗi lần gọi (cục bộ) | ~40-70 ms mỗi lần gọi (bị giới hạn bởi mạng) |

Quy tắc chung: xây dựng và kiểm thử trên stdio, sau đó chuyển sang Streamable HTTP chỉ khi nhiều hơn một người hoặc máy cần máy chủ. Hầu hết các máy chủ không bao giờ cần rời khỏi stdio. Các lệnh gọi mcp.run() và StdioServerTransport() ở trên đã là stdio, vì vậy bạn đã sẵn sàng cho việc phát triển.
Cách kiểm thử máy chủ MCP của bạn với Inspector
Trước khi tích hợp máy chủ của bạn vào Claude, hãy kiểm thử nó trong môi trường cô lập với MCP Inspector. Đây là giao diện trình duyệt kết nối với máy chủ của bạn, liệt kê các công cụ và cho phép bạn gọi chúng bằng tay. Chạy nó đối với máy chủ của bạn:
# Python
npx @modelcontextprotocol/inspector uv run server.py
# TypeScript
npx @modelcontextprotocol/inspector npx tsx server.tsInspector mở một trang cục bộ nơi bạn có thể thấy các công cụ add và fetch_url của mình, thực hiện một lệnh gọi kiểm thử và đọc phản hồi thô. Đây là thói quen tốt nhất cho phát triển MCP. Nếu lược đồ của một công cụ bị lỗi hoặc giá trị trả về sai, bạn sẽ thấy nó ở đây trong vài giây thay vì nhìn chằm chằm vào một lỗi im lặng bên trong Claude. Chúng tôi đã bắt được một lược đồ đầu vào xấu bằng cách này, điều mà lẽ ra sẽ tốn một vòng gỡ lỗi đầy đủ thông qua client. Hãy kiểm thử trong Inspector trước, mọi lúc.
Cách kết nối máy chủ MCP của bạn với Claude Desktop, Claude Code và Cursor
Khi Inspector đã ổn, hãy trỏ một client thực tế vào máy chủ của bạn. Mỗi client đọc một file cấu hình cho nó biết cách khởi chạy máy chủ của bạn qua stdio.
Claude Desktop. Chỉnh sửa claude_desktop_config.json (trên macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"demo-server": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/mcp-demo", "run", "server.py"]
}
}
}Khởi động lại Claude Desktop và các công cụ của bạn sẽ xuất hiện dưới biểu tượng connectors.
Claude Code. Thêm máy chủ với một lệnh từ dự án của bạn: claude mcp add demo-server -- uv run server.py. Claude Code lưu trữ nó trong cấu hình dự án của bạn và tải nó khi khởi chạy. Nếu bạn cũng sử dụng hooks để script hóa Claude Code, hướng dẫn hooks Claude Code của chúng tôi phù hợp tốt với các công cụ MCP tùy chỉnh.
Cursor. Thêm cùng khối mcpServers vào .cursor/mcp.json trong thư mục gốc dự án của bạn. Hình dạng khớp với Claude Desktop. Để xem ví dụ thực tế về một máy chủ MCP chạy bên trong Claude Code, hãy xem cách chúng tôi tích hợp Higgsfield vào Claude Code.
Sử dụng đường dẫn tuyệt đối trong mọi cấu hình. Đường dẫn tương đối là lý do phổ biến nhất khiến máy chủ không khởi chạy được.
Triển khai máy chủ MCP lên Production (Xác thực và Hosting)
Khi máy chủ của bạn cần được chia sẻ, hãy chuyển nó từ stdio sang Streamable HTTP và thêm ba thứ: xác thực, xử lý lỗi và một host.
- Xác thực. Các máy chủ MCP remote phải sử dụng OAuth 2.1 theo đặc tả ủy quyền MCP. Đối với các công cụ nội bộ, kiểm tra bearer-token trên endpoint HTTP là mức tối thiểu thực tế. Không bao giờ triển khai một máy chủ công cụ công khai, không xác thực, vì một công cụ chạy SQL hoặc truy cập các API nội bộ là một bề mặt tấn công trực tiếp.
- Xử lý lỗi. Bao bọc thân công cụ trong try/except (hoặc try/catch) và trả về một thông báo lỗi có kiểu thay vì ném ngoại lệ. Mô hình xử lý "truy vấn thất bại, đây là lý do" tốt hơn nhiều so với một kết nối bị dropped.
- Hosting. Bất kỳ nền tảng nào chạy một tiến trình Node hoặc Python lâu dài đều hoạt động: một VPS nhỏ, Fly.io, Railway, hoặc một container trên hạ tầng riêng của bạn. Giữ tiến trình luôn ấm, vì cold start thêm độ trễ cho lần gọi công cụ đầu tiên.
- Đồng thời và chi phí. Nếu các công cụ của bạn gọi một LLM hoặc API trả phí downstream, hãy đặt một gateway trước chúng. Tổng hợp các công cụ LLM gateway của chúng tôi bao gồm giới hạn tốc độ và dự phòng, và các công cụ kỹ thuật ngữ cảnh giúp giữ cho đầu ra công cụ không làm phồng cửa sổ ngữ cảnh của mô hình.
Đối với Python, chuyển lệnh chạy thành mcp.run(transport="streamable-http"); đối với TypeScript, thay thế StdioServerTransport bằng StreamableHTTPServerTransport của SDK. Các định nghĩa công cụ không thay đổi chút nào — đó là điểm mạnh của sự trừu tượng hóa phương thức truyền tải.
Những gì chúng tôi học được khi triển khai máy chủ MCP trong Production
Chúng tôi đã xây dựng các máy chủ MCP cho sử dụng nội bộ tại Techsy, và một vài bài học chỉ xuất hiện khi có lưu lượng thực tế. Dưới đây là những gì chúng tôi đã đo lường và nơi chúng tôi gặp vấn đề.
Máy chủ đầu tiên chúng tôi triển khai là một công cụ truy vấn Postgres chỉ đọc được xây dựng bằng FastMCP 2.x trên Python mcp 1.x SDK, sau đó được viết lại bằng @modelcontextprotocol/sdk 1.x để so sánh. Trên ngăn xếp 2026 (Node 20, Python 3.11), các lệnh gọi công cụ stdio cục bộ thêm khoảng 8 đến 12 ms độ trễ truyền tải mỗi lần gọi. Khi chúng tôi chuyển máy chủ đó sang Streamable HTTP trên một VPS, chi phí mỗi lần gọi tăng lên 40 đến 70 ms, hầu như hoàn toàn do vòng lặp mạng chứ không phải chi phí giao thức. Cold-start của FastMCP mất khoảng 300 ms cho tiến trình, đó là lý do tại sao chúng tôi giữ tiến trình production luôn ấm.
Vấn đề khiến chúng tôi mất khoảng hai giờ: một công cụ trả về một dict Python thô hiển thị tốt trong Inspector nhưng bị cắt ngắn bên trong Claude Desktop. Bao bọc giá trị trả về dưới dạng chuỗi văn bản có kiểu đã khắc phục nó ngay lập tức. Đó là lý do tại sao hướng dẫn này trả về chuỗi và các khối văn bản content ở khắp mọi nơi thay vì các đối tượng lồng ghép. Thói quen khác mang lại hiệu quả ngay lập tức là chạy mọi máy chủ qua npx @modelcontextprotocol/inspector trước khi chạm vào cấu hình client, điều này đã bộc lộ một lược đồ đầu vào bị lỗi trong bản viết lại TypeScript mà lẽ ra sẽ thất bại âm thầm trong Cursor.
| Những gì chúng tôi đã dùng | Phiên bản |
|---|---|
Python mcp SDK | 1.x |
| FastMCP | 2.x |
@modelcontextprotocol/sdk (TS) | 1.x |
| Node.js | 20 LTS |
| Inspector | @modelcontextprotocol/inspector (mới nhất) |
Nếu bạn đang chọn những công cụ nào để xây dựng vào các máy chủ ngay từ đầu, danh sách các máy chủ MCP tốt nhất năm 2026 của chúng tôi là một ngân hàng ý tưởng tốt.
Cách Techsy tiếp cận phát triển MCP
Tại Techsy, chúng tôi xây dựng các máy chủ MCP như một phần của các hệ thống tác nhân AI mà chúng tôi triển khai cho khách hàng, kết nối các tác nhân với cơ sở dữ liệu nội bộ, CRM và API thông qua một lớp công cụ có kiểu. Cách tiếp cận của chúng tôi là bắt đầu hẹp (một công cụ được kiểm thử kỹ qua stdio), xác thực nó trong Inspector, sau đó nâng cấp nó lên một dịch vụ HTTP được xác thực chỉ khi nhiều hơn một tác nhân cần nó. Chúng tôi kết hợp các máy chủ tùy chỉnh với Claude Agent SDK khi logic tác nhân trở nên phức tạp.
Đó là phiên bản trung thực: hầu hết các đội nhóm đều xây dựng quá mức máy chủ đầu tiên của họ. Bạn hiếm khi cần HTTP, OAuth và một tá công cụ ngay ngày đầu tiên. Nếu bạn muốn một cặp mắt thứ hai xem xét tích hợp MCP, nhận tư vấn miễn phí và chúng tôi sẽ cho bạn biết đó là công việc stdio một công cụ hay thứ gì đó thực sự cần hạ tầng.
Câu hỏi thường gặp
Tôi nên xây dựng máy chủ MCP của mình bằng Python hay TypeScript?
Sử dụng bất kỳ ngôn ngữ nào mà nhóm của bạn đang triển khai. Python với FastMCP là con đường ngắn nhất để có một máy chủ chạy đầu tiên vì một decorator biến một hàm thành một công cụ. TypeScript với SDK chính thức dài dòng hơn một chút nhưng cung cấp cho bạn các kiểu dữ liệu tuyệt vời và triển khai sạch sẽ lên các host Node. Cả hai đều tạo ra các máy chủ hoạt động giống hệt nhau đối với client.
Tôi có cần một framework như FastMCP để xây dựng máy chủ MCP không?
Không, nhưng nó giúp ích. FastMCP đi kèm với Python mcp SDK chính thức và loại bỏ hầu hết các mã boilerplate của giao thức. Bạn có thể sử dụng API Server cấp thấp hơn để kiểm soát chi tiết, nhưng đối với hầu hết mọi máy chủ, FastMCP (Python) hoặc McpServer (TypeScript) là công cụ phù hợp và ít mã hơn nhiều.
Làm thế nào để gỡ lỗi một máy chủ MCP không hoạt động?
Chạy nó qua MCP Inspector trước: npx @modelcontextprotocol/inspector theo sau là lệnh chạy của bạn. Inspector liệt kê các công cụ của bạn và cho phép bạn gọi chúng trực tiếp, vì vậy bạn có thể xác nhận máy chủ hoạt động trước khi đổ lỗi cho client. Nếu Inspector ổn nhưng client thì không, hãy kiểm tra xem cấu hình của bạn có sử dụng đường dẫn tuyệt đối không và bạn đã khởi động lại client chưa.
FastMCP có phải là một phần chính thức của MCP không?
Có. FastMCP được bundled với Model Context Protocol Python SDK chính thức như là giao diện máy chủ cấp cao. Decorator @mcp.tool() mà bạn sử dụng là cách được khuyến nghị để xây dựng các máy chủ Python, không phải một add-on của bên thứ ba.
Sự khác biệt giữa máy chủ MCP cục bộ và remote là gì?
Một máy chủ cục bộ chạy trên máy của bạn qua stdio, được client khởi chạy như một tiến trình con, phù hợp nhất cho các công cụ cá nhân và phát triển. Một máy chủ remote chạy như một dịch vụ web qua Streamable HTTP và có thể truy cập được bởi nhiều client, điều này yêu cầu xác thực OAuth 2.1. Xây dựng cục bộ trước, chỉ chuyển sang remote khi cần chia sẻ.
Tôi có thể xây dựng máy chủ MCP bằng những ngôn ngữ nào?
Giao thức Ngữ cảnh Mô hình có các SDK chính thức cho Python, TypeScript, Java, Kotlin và C#, với các SDK cộng đồng bằng các ngôn ngữ khác. Vì MCP là một giao thức wire, bất kỳ ngôn ngữ nào có thể đọc và ghi JSON-RPC qua stdio hoặc HTTP đều có thể triển khai một máy chủ, nhưng các SDK chính thức giúp bạn tiết kiệm công sức đó.
Máy chủ MCP có hoạt động với ChatGPT và Gemini, hay chỉ với Claude?
MCP là một tiêu chuẩn mở được áp dụng trên toàn hệ sinh thái AI tác nhân, bao gồm ChatGPT, Gemini, Cursor và VS Code Copilot. Một máy chủ duy nhất bạn xây dựng hoạt động với bất kỳ client tương thích nào. Bạn không cần viết một tích hợp riêng cho mỗi mô hình, đó chính là điểm mấu chốt của giao thức.
Mất bao lâu để xây dựng một máy chủ MCP hoạt động?
Một máy chủ đầu tiên với một hoặc hai công cụ chạy qua stdio mất khoảng 15 phút một khi runtime của bạn đã được cài đặt. Chúng tôi đã đo được 14 phút cho người mới bắt đầu trên Node 20 và dưới 5 phút cho lần xây dựng lặp lại. Thêm xác thực, phương thức truyền tải HTTP và hosting production mới là thứ tốn thời gian thực sự, không phải bản thân máy chủ.
Về tác giả
Mert Batur Gurbuz là Đồng sáng lập của Techsy.io, nơi nhóm triển khai các tác nhân AI, hệ thống tự động hóa và pipeline voice/SDR cho các khách hàng B2B. Anh ấy đang học tại Đại học Birmingham và viết về ngăn xếp công cụ LLM mà nhóm Techsy thực sự sử dụng trong production. Kết nối trên LinkedIn.
Mert Batur Gurbuz, Đồng sáng lập, Techsy.io, Đại học Birmingham