Bỏ qua tới nội dung
Bài 1/11 · MCP cho người mới bắt đầu (Microsoft)

Xây MCP server đầu tiên

Chuẩn bị môi trường, cấu trúc một MCP server, viết server máy tính bằng TypeScript, Python, .NET, Java hoặc Rust và kiểm thử bằng MCP Inspector.

Cơ bản@shine190425 phút đọc

Bài này hướng dẫn những bước đầu tiên với Model Context Protocol (MCP): chuẩn bị môi trường, xây một MCP server cơ bản và kiểm thử nó. Dù bạn mới làm quen với MCP hay muốn hiểu sâu hơn, bạn sẽ thấy MCP giúp tích hợp (integration) liền mạch giữa model AI và ứng dụng ra sao, và nhanh chóng có môi trường sẵn sàng để xây, thử các giải pháp dùng MCP.

Tóm tắt nhanh: nếu bạn xây ứng dụng AI, bạn biết có thể thêm tool và các resource khác vào LLM để LLM hiểu biết hơn. Nhưng nếu đặt các tool và resource đó trên một server, ứng dụng và các khả năng (capability) của server có thể được dùng bởi bất kỳ client nào, có hoặc không có LLM.

Tổng quan

Bài này hướng dẫn thực hành cách thiết lập môi trường MCP và xây ứng dụng MCP đầu tiên. Bạn sẽ học cách cài công cụ và framework cần thiết, xây MCP server cơ bản, tạo ứng dụng host và kiểm thử phần cài đặt.

Model Context Protocol (MCP) là một giao thức mở chuẩn hoá cách ứng dụng cung cấp ngữ cảnh cho LLM. Hãy hình dung MCP như cổng USB-C cho ứng dụng AI: một cách chuẩn để kết nối model AI với các nguồn dữ liệu và tool khác nhau.

Mục tiêu học tập

Sau bài này, bạn sẽ có thể:

  • Thiết lập môi trường phát triển MCP bằng C#, Java, Python, TypeScript và Rust.
  • Xây và triển khai (deploy) MCP server cơ bản với các tính năng tuỳ chỉnh (resource, prompt và tool).
  • Tạo ứng dụng host kết nối tới MCP server.
  • Kiểm thử và gỡ lỗi phần cài đặt MCP.

Thiết lập môi trường MCP

Trước khi làm việc với MCP, cần chuẩn bị môi trường phát triển và hiểu quy trình (workflow) cơ bản.

Điều kiện cần

Trước khi phát triển MCP, hãy đảm bảo bạn có:

  • Môi trường phát triển: cho ngôn ngữ bạn chọn (C#, Java, Python, TypeScript hoặc Rust).
  • IDE/trình soạn thảo: Visual Studio, Visual Studio Code, IntelliJ, Eclipse, PyCharm hoặc bất kỳ trình soạn thảo hiện đại nào.
  • Trình quản lý gói: NuGet, Maven/Gradle, pip, npm/yarn hoặc Cargo.
  • API key: cho các dịch vụ AI bạn định dùng trong ứng dụng host.

Cấu trúc cơ bản của MCP server

Một MCP server thường gồm:

  • Cấu hình server: thiết lập cổng, xác thực và các cài đặt khác.
  • Resource: dữ liệu và ngữ cảnh cung cấp cho LLM.
  • Tool: chức năng model có thể gọi.
  • Prompt: mẫu để sinh hoặc cấu trúc văn bản.

Đây là ví dụ đơn giản bằng TypeScript:

typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Create an MCP server
const server = new McpServer({
  name: "Demo",
  version: "1.0.0"
});

// Add an addition tool
server.tool("add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }]
  })
);

// Add a dynamic greeting resource
server.resource(
  "file",
  // The 'list' parameter controls how the resource lists available files. Setting it to undefined disables listing for this resource.
  new ResourceTemplate("file://{path}", { list: undefined }),
  async (uri, { path }) => ({
    contents: [{
      uri: uri.href,
      text: `File, ${path}!`
    }]
  })
);

// Add a file resource that reads the file contents
server.resource(
  "file",
  new ResourceTemplate("file://{path}", { list: undefined }),
  async (uri, { path }) => {
    let text;
    try {
      text = await fs.readFile(path, "utf8");
    } catch (err) {
      text = `Error reading file: ${err.message}`;
    }
    return {
      contents: [{
        uri: uri.href,
        text
      }]
    };
  }
);

server.prompt(
  "review-code",
  { code: z.string() },
  ({ code }) => ({
    messages: [{
      role: "user",
      content: {
        type: "text",
        text: `Please review this code:\n\n${code}`
      }
    }]
  })
);

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);

Trong code trên, chúng ta:

  • Import các lớp cần thiết từ MCP TypeScript SDK.
  • Tạo và cấu hình một MCP server mới.
  • Đăng ký một tool tuỳ chỉnh (calculator) kèm hàm xử lý.
  • Khởi động server để lắng nghe các yêu cầu (request) MCP gửi tới.

Kiểm thử và gỡ lỗi

Trước khi kiểm thử MCP server, cần biết các công cụ có sẵn và best practice để gỡ lỗi. Kiểm thử hiệu quả giúp server hoạt động như mong đợi và nhanh chóng tìm ra, sửa lỗi.

MCP có các công cụ giúp kiểm thử và gỡ lỗi server:

  • Inspector: giao diện đồ hoạ cho phép kết nối tới server và thử các tool, prompt, resource.
  • curl: bạn cũng có thể kết nối tới server bằng công cụ dòng lệnh như curl hoặc các client khác tạo và chạy được lệnh HTTP.

Dùng MCP Inspector

MCP Inspector là công cụ kiểm thử trực quan, giúp bạn:

  1. Khám phá capability của server: tự động phát hiện các resource, tool và prompt có sẵn.
  2. Thử chạy tool: thử các tham số khác nhau và xem phản hồi (response) theo thời gian thực.
  3. Xem metadata của server: xem thông tin server, schema và cấu hình.
bash
# ex TypeScript, installing and running MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js

Khi chạy lệnh trên, MCP Inspector mở một giao diện web local trên trình duyệt. Bạn sẽ thấy một bảng điều khiển hiển thị các MCP server đã đăng ký, tool, resource và prompt của chúng. Giao diện cho phép thử chạy tool, xem metadata của server và phản hồi theo thời gian thực, giúp kiểm chứng và gỡ lỗi server dễ hơn.

Đây là ảnh chụp màn hình minh hoạ:

MCP Inspector đã kết nối tới server

Lỗi thiết lập thường gặp và cách xử lý

LỗiCách xử lý có thể
Connection refusedKiểm tra server có đang chạy và cổng có đúng không
Lỗi khi chạy toolXem lại phần kiểm tra tham số và xử lý lỗi
Xác thực thất bạiKiểm tra API key và quyền
Lỗi kiểm tra schemaĐảm bảo tham số khớp schema đã định nghĩa
Server không khởi độngKiểm tra xung đột cổng hoặc thiếu dependency
Lỗi CORSCấu hình header CORS phù hợp cho request khác origin
Vấn đề xác thựcKiểm tra token còn hợp lệ và quyền

Phát triển ở máy local

Để phát triển và kiểm thử ở máy local, bạn có thể chạy MCP server trực tiếp trên máy:

  1. Khởi động tiến trình server: chạy ứng dụng MCP server.
  2. Cấu hình mạng: đảm bảo server truy cập được ở cổng mong muốn.
  3. Kết nối client: dùng URL local như http://localhost:3000.
bash
# Example: Running a TypeScript MCP server locally
npm run start
# Server running at http://localhost:3000

Xây MCP server đầu tiên

Bài trước của khoá gốc đã nói về các khái niệm cốt lõi (khoá MCP của Hugging Face cũng có phần này). Giờ là lúc áp dụng kiến thức đó.

Server làm được gì

Trước khi viết code, hãy nhắc lại một server làm được gì. Ví dụ, một MCP server có thể:

  • Truy cập file và cơ sở dữ liệu local
  • Kết nối tới API từ xa
  • Thực hiện tính toán
  • Tích hợp với các tool và dịch vụ khác
  • Cung cấp giao diện để tương tác

Tốt, giờ đã biết server làm được gì, hãy bắt đầu viết code.

Bài thực hành: tạo server

Để tạo server, bạn làm theo các bước:

  • Cài MCP SDK.
  • Tạo project và cấu trúc thư mục.
  • Viết code server.
  • Kiểm thử server.

Bước 1: tạo project

sh
# Create project directory and initialize npm project
mkdir calculator-server
cd calculator-server
npm init -y

Bước 2: thêm dependency

Đã có project, giờ thêm dependency:

sh
# If not already installed, install TypeScript globally
npm install typescript -g

# Install the MCP SDK and Zod for schema validation
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript

Bước 3: tạo file project

Mở file package.json và thay nội dung bằng đoạn sau để build và chạy được server:

json
{
  "name": "calculator-server",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "npm run build && node ./build/index.js",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "A simple calculator server using Model Context Protocol",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.16.0",
    "zod": "^3.25.76"
  },
  "devDependencies": {
    "@types/node": "^24.0.14",
    "typescript": "^5.8.3"
  }
}

Tạo tsconfig.json với nội dung:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Tạo thư mục cho mã nguồn:

sh
mkdir src
touch src/index.ts

Bước 4: viết code server

Tạo file index.ts và thêm code sau:

typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
 
// Create an MCP server
const server = new McpServer({
  name: "Calculator MCP Server",
  version: "1.0.0"
});

Giờ bạn đã có server, nhưng nó chưa làm được gì nhiều; hãy sửa điều đó.

Bước 5: thêm tool và resource

Thêm một tool và một resource bằng code sau:

typescript
server.tool(
  "add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }]
  })
);

server.resource(
  "greeting",
  new ResourceTemplate("greeting://{name}", { list: undefined }),
  async (uri, { name }) => ({
    contents: [{
      uri: uri.href,
      text: `Hello, ${name}!`
    }]
  })
);

Tool nhận tham số a và b, chạy một hàm trả về phản hồi dạng:

typescript
{
  contents: [{
    type: "text", content: "some content"
  }]
}

Resource được truy cập qua chuỗi "greeting", nhận tham số name và trả về phản hồi tương tự tool:

typescript
{
  uri: "<href>",
  text: "a text"
}

Bước 6: code hoàn chỉnh

Thêm đoạn code cuối cùng để server khởi động được:

typescript
// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);

Đây là code đầy đủ:

typescript
// index.ts
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Create an MCP server
const server = new McpServer({
  name: "Calculator MCP Server",
  version: "1.0.0"
});

// Add an addition tool
server.tool(
  "add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }]
  })
);

// Add a dynamic greeting resource
server.resource(
  "greeting",
  new ResourceTemplate("greeting://{name}", { list: undefined }),
  async (uri, { name }) => ({
    contents: [{
      uri: uri.href,
      text: `Hello, ${name}!`
    }]
  })
);

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
server.connect(transport);

Bước 7: kiểm thử server

Khởi động server bằng lệnh sau:

sh
npm run build

Bước 8: chạy bằng Inspector

Inspector là công cụ tuyệt vời: nó khởi động server và cho phép bạn tương tác để kiểm tra server hoạt động. Hãy khởi động nó. Lưu ý: trường "command" trên giao diện có thể trông khác, vì nó chứa lệnh chạy server theo runtime cụ thể của bạn.

sh
npx @modelcontextprotocol/inspector node build/index.js

hoặc thêm vào package.json như sau: "inspector": "npx @modelcontextprotocol/inspector node build/index.js" rồi chạy npm run inspector.

Phần tiếp theo là tương tác với server. Bạn sẽ thấy giao diện sau:

Giao diện kết nối của MCP Inspector

  1. Kết nối tới server bằng nút Connect. Sau khi kết nối, bạn sẽ thấy:

    MCP Inspector đã kết nối

  2. Chọn "Tools" rồi "listTools", bạn sẽ thấy "Add" xuất hiện. Chọn "Add" và điền giá trị tham số. Bạn sẽ thấy phản hồi, tức kết quả từ tool "add":

    Kết quả chạy tool add

Chúc mừng, bạn đã tạo và chạy được server đầu tiên!

SDK chính thức

MCP có SDK chính thức cho nhiều ngôn ngữ:

Điểm chính

  • Thiết lập môi trường phát triển MCP khá đơn giản nhờ SDK cho từng ngôn ngữ.
  • Xây MCP server gồm tạo và đăng ký các tool với schema rõ ràng.
  • Kiểm thử và gỡ lỗi là thiết yếu để phần cài đặt MCP đáng tin cậy.

Mẫu code

Bài tập

Tạo một MCP server đơn giản với một tool do bạn chọn:

  1. Cài đặt tool bằng ngôn ngữ bạn thích (.NET, Java, Python, TypeScript hoặc Rust).
  2. Định nghĩa tham số đầu vào và giá trị trả về.
  3. Chạy inspector để đảm bảo server hoạt động như dự định.
  4. Kiểm thử phần cài đặt với nhiều đầu vào khác nhau.

Lời giải: solution.

Tài liệu thêm

Bài tiếp theo: Xây MCP client đầu tiên.

Nguồn