Giới thiệu
Trong thế giới phát triển phần mềm hiện đại, việc kết nối các mô hình ngôn ngữ lớn (LLM) với dữ liệu thời gian thực, dữ liệu cá nhân và các nguồn dữ liệu khác là rất quan trọng. Một trong những cách hiệu quả để thực hiện điều này là thông qua việc tạo ra một máy chủ Model Context Protocol (MCP). Bài viết này sẽ hướng dẫn bạn cách tạo một máy chủ MCP và các công cụ MCP từ đầu, cùng với các mẹo và thực tiễn tốt nhất.
Tại sao chúng ta cần tạo máy chủ MCP?
Máy chủ MCP cho phép chúng ta kết nối một LLM với dữ liệu thực tế. Chúng ta sẽ xây dựng một máy chủ để giải quyết một trong những lỗi phổ biến mà LLM thường gặp: không thể đếm số lượng chữ "r" trong các biến thể của từ "strawberry". Chẳng hạn, nó sẽ gặp khó khăn khi phải xác định số lượng chữ "r" trong các từ như strawberrrry hay strawberrrrrrry.
Điều này nghe có vẻ đơn giản với con người, nhưng đối với một LLM, đó là một thách thức do cách thức hoạt động của nó—dựa trên các token. AI có thể tạo ra nghệ thuật và mã, nhưng lại không thể đếm được các chữ cái. Thật mâu thuẫn phải không?
Bây giờ, hãy biến điều này thành một bài tập giáo dục về cách triển khai một máy chủ MCP.
Yêu cầu để tạo máy chủ MCP bằng JavaScript
Để bắt đầu, bạn cần cài đặt Node.js. Đầu tiên, bạn tạo một dự án mới với lệnh sau trong terminal:
bash
npm init -y
Sau đó, tạo tệp index.js bằng lệnh touch trong Linux:
bash
.
├── index.js
├── package.json
└── package-lock.json
Thiết lập package.json dưới dạng mô-đun
Mở tệp package.json, thay đổi hoặc thêm thuộc tính type với giá trị module để npm nhận diện đây là mô-đun.
json
"type": "module"
Cài đặt thư viện cần thiết
Máy chủ MCP cần SDK chính thức của MCP server. Bạn có thể cài đặt nó qua npm cùng với thư viện zod để xác thực dữ liệu:
bash
npm install @modelcontextprotocol/sdk@1.16.0 zod@3.25.76
Tạo máy chủ MCP
Bây giờ chúng ta sẽ tạo một máy chủ MCP bằng cách khởi tạo một đối tượng McpServer mới:
javascript
import {McpServer} from "@modelcontextprotocol/sdk/server/mcp.js";
const server = new McpServer({
name: 'Đếm Strawberry',
version: '1.0.0'
});
Tạo công cụ MCP trong máy chủ MCP
Tiếp theo, chúng ta sẽ định nghĩa các công cụ, hay còn gọi là mcp tools, cho phép nhận tham số từ LLM để thực hiện chức năng—trong trường hợp này là đếm số chữ "r".
javascript
server.tool("Đếm Strawberry", "Đếm số lượng chữ r có trong một biến thể strawberry", {
param: z.string().describe("Biến thể strawberry, có thể có số lượng chữ r thay đổi")
},
async ({ param }) => {
return {
content: [
{
type: 'text',
text: `Từ có: ${param.toLowerCase().split("").filter(letter => letter == "r").length} chữ r`
}
]
};
}
);
Chúng ta đang đếm số chữ "r" một cách thủ công—không có mẹo gì ở đây. Chúng ta xử lý chuỗi nhận được và trả về số lượng chữ "r".
Điều thú vị là LLM có thể phát hiện tham số mà chúng ta muốn nhận từ thông tin mô tả mà chúng ta đã truyền vào phương thức describe.
Tất nhiên, công cụ mcp tool của bạn không chỉ dừng lại ở việc đếm chữ "r"—bạn có thể lấy dữ liệu từ API, xử lý nó hoặc thậm chí kết nối với một LLM khác.
LLM lấy ngữ cảnh từ đâu?
Trong ví dụ này, chúng ta sẽ sử dụng STDIO (Standard Input Output) làm nguồn ngữ cảnh.
javascript
const transport = new StdioServerTransport();
Chạy máy chủ MCP để đọc từ STDIO
Bây giờ chúng ta sẽ kết nối transport này đến máy chủ MCP để nó có thể đọc trực tiếp từ STDIO.
javascript
await server.connect(transport);
Kết nối MCP với các ứng dụng khác
Máy chủ MCP có thể kết nối với bất kỳ chương trình nào hỗ trợ MCP. Ví dụ, để kết nối với Claude Desktop, bạn cần điền thông tin vào tệp claude_desktop_config.json:
json
{
"mcpservers": {
"name": {
"command": "npx",
"args": [
"-y",
"node",
"<đường_dẫn_đầy_đủ_tới_tệp_js>"
]
}
}
}
Nếu bạn muốn sử dụng TypeScript thay vì JavaScript, bạn có thể làm như sau:
json
{
"mcpservers": {
"name": {
"command": "npx",
"args": [
"-y",
"tsx",
"<đường_dẫn_đầy_đủ_tới_tệp_ts>"
]
}
}
}
Phân tích máy chủ MCP với Inspector
Làm thế nào để kiểm tra máy chủ MCP của chúng ta hoạt động như thế nào? Claude’s inspector cho phép bạn kiểm tra và gỡ lỗi các máy chủ MCP. Bạn có thể xem các công cụ đã tạo và mô phỏng chức năng của chúng.
Để chạy nó, bạn có thể sử dụng npx và truyền lệnh máy chủ:
bash
npx -y @modelcontextprotocol/inspector <lệnh_mcp_server>
Tuy nhiên, tôi đã không thể chạy lệnh này bằng cách thay thế. Tôi đã thử sử dụng thư mục tương đối và tuyệt đối, nhưng không kết nối được với máy chủ. Tuy nhiên, tôi đã có thể làm việc bằng cách điền dữ liệu vào giao diện đồ họa của Inspector.
Sau khi chạy inspector, chúng ta sẽ có một máy chủ hoạt động trên cổng 6274 (mặc định, nhưng có thể thay đổi).
bash
npx -y @modelcontextprotocol/inspector npm index.js
npx -y @modelcontextprotocol/inspector npm /home/dir/mcp-server/index.js
Tiếp theo, điền loại transport và lệnh nếu bạn gặp vấn đề tương tự như tôi.
Nếu bạn nhấn vào “list tools”, nó sẽ phát hiện công cụ mà chúng ta vừa tạo.
Bằng cách nhấn vào List tools, và sau đó vào tên của công cụ, bạn sẽ có thể truyền tham số: một biến thể strawberry với bất kỳ số lượng chữ "r" nào mà bạn muốn.
Hãy nhớ rằng, tham số này sẽ được nhận trực tiếp từ LLM—nó sẽ có trách nhiệm phân tích đầu vào của người dùng và trả về tham số một cách chính xác.
Như bạn có thể thấy, mã hoạt động. Máy chủ MCP trả về thông điệp của chúng ta. Trong một môi trường thực tế, thông điệp này sẽ được LLM nhận và thông báo cho người dùng số lượng chữ "r" chính xác trong biến thể strawberry của họ—mà không làm cho chính nó trở nên ngớ ngẩn như thường lệ.