DEV Community

Cover image for Hướng Dẫn Kiểm Thử Máy Chủ MCP: Thủ Công & Tự Động với Apidog
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Hướng Dẫn Kiểm Thử Máy Chủ MCP: Thủ Công & Tự Động với Apidog

Một bài đăng “Ableton Live MCP” trên Show HN đã đạt 118 điểm và 78 bình luận vào đầu tuần này. Mẫu hình này ngày càng quen thuộc: ai đó viết một máy chủ Model Context Protocol (MCP) cho một công cụ thú vị, cộng đồng Claude Desktop thử ngay, rồi kéo theo hàng loạt câu hỏi “có nên viết MCP server cho X không?”. MCP đã đi từ thử nghiệm của Anthropic thành một lớp tích hợp tác nhân phổ biến trong chưa đầy một năm.

Dùng thử Apidog ngay hôm nay

Điểm còn thiếu trong hệ sinh thái này là cách kiểm thử MCP server một cách có hệ thống. Gửi JSON-RPC thủ công qua stdio có thể ổn với ví dụ “hello world”, nhưng sẽ nhanh chóng vỡ khi server có 12 tools, 3 prompts và một upstream API không ổn định. Bài viết này đưa ra quy trình thực hành để kiểm thử MCP server thủ công, sau đó tự động hóa bằng Apidog: có contract, mock server và regression test như với một API production.

Nếu bạn đang làm việc trong bối cảnh agent rộng hơn, hướng dẫn agents.md của chúng tôi cũng phù hợp với quy trình này; các quy ước trong đó giúp contract của MCP server dễ truyền đạt hơn trong nhóm.

TL;DR

  • MCP là Model Context Protocol của Anthropic: JSON-RPC 2.0 qua stdio hoặc HTTP, phơi bày tools, resourcesprompts.
  • Kiểm thử MCP server nghĩa là xác minh các response như initialize, tools/list, tools/call, resources/read, prompts/get so với một contract rõ ràng.
  • Bắt đầu bằng kiểm thử thủ công qua MCP Inspector hoặc JSON-RPC thô.
  • Sau đó lưu các request/response chuẩn vào Apidog, thêm assertion JSONPath và chạy trong CI.
  • Dùng mock server của Apidog để mô phỏng upstream API, giúp test ổn định và không phụ thuộc mạng ngoài.
  • Tải Apidog nếu bạn muốn request collection, mock server và CI runner trong cùng một nơi.

MCP thực sự là gì?

Đặc tả Model Context Protocol định nghĩa một giao thức JSON-RPC 2.0 với bề mặt tương đối nhỏ. Một MCP client như Claude Desktop, Cursor hoặc agent nội bộ sẽ khởi động MCP server, gọi initialize, sau đó tương tác qua các method chuẩn.

Các method bạn nên kiểm thử nhiều nhất:

Method Mục đích kiểm thử
initialize Đàm phán version và capabilities
tools/list Trả về danh sách tools và JSON Schema cho arguments
tools/call Gọi một tool cụ thể với arguments
resources/list Liệt kê resource có thể đọc
resources/read Đọc resource theo URI
prompts/list Liệt kê prompt templates
prompts/get Render một prompt với arguments

MCP có thể chạy qua:

  • stdio: JSON-RPC frame phân tách bằng newline trên stdin/stdout.
  • HTTP transport: thường là POST /, có thể dùng SSE cho streaming.

Phần lớn server local dùng stdio; server remote thường dùng HTTP.

Lý do cần kiểm thử nghiêm túc: nếu tools/list sai shape, mọi client sử dụng server của bạn đều hỏng cùng lúc.

Bạn nên kiểm thử những gì?

Một bộ test MCP server nên bao phủ 6 nhóm chính.

1. Tuân thủ giao thức

Kiểm tra initialize:

  • Có trả về đúng protocolVersion không?
  • Có quảng bá đúng capabilities không?
  • Có trả về lỗi hợp lệ khi client gửi version không hỗ trợ không?

Ví dụ request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2026-04-01",
    "capabilities": {}
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Tính đúng đắn của schema

Với tools/list, kiểm tra mỗi tool có:

  • name
  • description
  • inputSchema

Mô tả tool không nên rỗng hoặc quá mơ hồ. Description kém làm giảm khả năng chọn tool chính xác của client như Claude.

3. Hành vi của tool

Với mỗi tools/call, kiểm tra:

  • Response có content đúng format không?
  • Content block có type hợp lệ như text, image, resource không?
  • Lỗi nghiệp vụ có trả về isError: true không?

Ví dụ response thành công:

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Weather in Tokyo: 21°C, cloudy"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Ví dụ lỗi cấp tool:

{
  "jsonrpc": "2.0",
  "id": 43,
  "result": {
    "isError": true,
    "content": [
      {
        "type": "text",
        "text": "Missing required argument: city"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Không nên ném JSON-RPC error cho lỗi nghiệp vụ bên trong tool. JSON-RPC error nên dành cho lỗi cấp giao thức.

4. Truy cập resource

Kiểm tra:

  • URI từ resources/list có đọc được bằng resources/read không?
  • Pagination có hoạt động sau trang đầu tiên không?
  • Resource không tồn tại có trả về lỗi phù hợp không?

5. Render prompt

Với prompts/get, kiểm tra:

  • Response có mảng messages hợp lệ không?
  • Arguments được thay thế đúng vị trí không?
  • Prompt thiếu argument có trả về lỗi rõ ràng không?

6. Chế độ lỗi

Mô phỏng các tình huống production:

  • Upstream API timeout.
  • Thiếu argument bắt buộc.
  • Argument sai type.
  • Client gửi nhiều tools/call đồng thời.
  • Server bị upstream trả về response sai shape.

Kiểm thử thủ công với stdio

Bắt đầu bằng setup nhỏ nhất:

  • Một terminal.
  • File thực thi MCP server.
  • MCP Inspector hoặc JSON-RPC thô.

Nếu bạn chưa có server, hãy tạo một server mẫu theo MCP SDK quickstart chính thức. Ví dụ weather server là đủ để bắt đầu.

Chạy MCP Inspector:

npx @modelcontextprotocol/inspector node your-server.js
Enter fullscreen mode Exit fullscreen mode

Inspector mở một UI local để gửi MCP request và xem response. Dùng nó để xác nhận:

  • Server khởi động được.
  • initialize trả về đúng capabilities.
  • tools/list trả về danh sách tool hợp lệ.
  • tools/call chạy được với input mẫu.

Sau khi UI ổn, chạy lại một số call bằng stdio thô để lấy request/response chuẩn cho bộ test.

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-04-01","capabilities":{}}}' | node your-server.js
Enter fullscreen mode Exit fullscreen mode

Lưu lại các cặp request/response cho:

  • initialize
  • tools/list
  • tools/call
  • resources/list
  • resources/read
  • prompts/list
  • prompts/get

Đến cuối bước này, bạn nên có 6-12 fixture JSON-RPC mô tả contract cấp wire của server.

Từ thủ công đến tự động với Apidog

Kiểm thử thủ công giúp bắt lỗi rõ ràng. Nhưng khi server có nhiều tools, bạn cần regression test: mỗi lần push code, toàn bộ contract phải được kiểm tra lại.

Mô hình triển khai:

  1. Lưu request JSON-RPC vào Apidog.
  2. Thêm assertion cho response.
  3. Mock upstream API nếu server phụ thuộc dịch vụ ngoài.
  4. Chạy test suite trong CI.

1. Tạo project Apidog cho MCP server

Trong Apidog:

  1. Tạo project mới.
  2. Cấu hình base URL là HTTP endpoint của MCP server.
  3. Nếu server chỉ hỗ trợ stdio, chạy thêm một HTTP wrapper mỏng trong môi trường test.
  4. Tạo environment riêng cho local, CI, staging hoặc production.

Với server stdio, bạn có thể dùng MCP Inspector hoặc tự viết wrapper HTTP đơn giản để nhận JSON-RPC qua HTTP rồi forward vào process stdio. Cách tiếp cận tương tự cũng được dùng trong bài kiểm thử API không cần Postman vào năm 2026.

2. Lưu các request chuẩn

Tạo request riêng cho từng method quan trọng.

Ví dụ tools/call:

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "Tokyo"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Nên lưu ít nhất:

  • Một request happy path cho mỗi tool.
  • Một request thiếu argument bắt buộc.
  • Một request argument sai type.
  • Một request mô phỏng upstream lỗi.

3. Thêm assertion

Mục tiêu của automation không chỉ là gửi request, mà là xác minh response.

Với tools/list, thêm assertion như:

  • $.result.tools tồn tại.
  • $.result.tools.length lớn hơn 0.
  • Mỗi item có name, description, inputSchema.
  • inputSchema là JSON Schema hợp lệ.

Với tools/call thành công:

  • $.result.isErrorfalse hoặc không tồn tại.
  • $.result.content là array.
  • $.result.content[0].type tồn tại.
  • Nội dung trả về khớp expectation ổn định.

Với tools/call lỗi:

  • $.result.isErrortrue.
  • $.result.content[0].text tồn tại.
  • Nếu có error code ổn định, assert trên error code thay vì toàn bộ chuỗi lỗi.

Ví dụ expectation nên tránh:

Missing required argument city in function get_weather at line 42
Enter fullscreen mode Exit fullscreen mode

Ví dụ expectation tốt hơn:

{
  "isError": true,
  "code": "MISSING_ARGUMENT"
}
Enter fullscreen mode Exit fullscreen mode

Nếu server hiện chưa trả về error code ổn định, ít nhất hãy dùng regex thay vì so khớp toàn bộ message.

4. Mock upstream API

Phần lớn MCP server chỉ là lớp bọc quanh API khác: weather API, GitHub, Linear, database nội bộ hoặc hệ thống quan sát.

Không nên để CI gọi API thật trong mỗi commit vì:

  • Dễ bị rate limit.
  • Test chậm.
  • Response thay đổi theo thời gian.
  • Lỗi mạng ngoài làm test flaky.

Dùng mock server của Apidog để định nghĩa upstream endpoint giả.

Ví dụ server của bạn gọi:

GET https://weather.example.com/current?city=Tokyo
Enter fullscreen mode Exit fullscreen mode

Trong test, cấu hình server trỏ đến mock URL:

WEATHER_API_BASE_URL=https://mock.apidog.com/your-project/weather
Enter fullscreen mode Exit fullscreen mode

Mock response:

{
  "city": "Tokyo",
  "temperature": 21,
  "condition": "cloudy"
}
Enter fullscreen mode Exit fullscreen mode

Sau đó tools/call luôn nhận dữ liệu ổn định. Bạn có thể tạo thêm mock cho timeout, 500 error hoặc response sai schema.

Quy trình contract-first tương tự được trình bày trong bài phát triển API theo hợp đồng trước.

5. Chạy test suite trong CI

Khi request và assertion đã sẵn sàng, chạy bộ test bằng CLI trong CI.

Ví dụ GitHub Actions tối thiểu:

name: MCP server tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - run: npm ci

      - name: Start MCP HTTP wrapper
        run: node test/wrapper.js &

      - name: Run Apidog suite
        run: npx apidog run --project-id $APIDOG_PROJECT --env ci
        env:
          APIDOG_PROJECT: ${{ secrets.APIDOG_PROJECT }}
          APIDOG_TOKEN: ${{ secrets.APIDOG_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Mỗi lần push sẽ chạy lại toàn bộ contract MCP. Nếu tool thứ 7 bị đổi schema argument, CI sẽ báo lỗi trước khi merge.

Phạm vi test nên có

Một MCP server test suite trong Apidog thường bao gồm:

  • 1 request initialize.
  • 1 request tools/list.
  • 2-4 request tools/call cho mỗi tool:
    • happy path
    • thiếu argument
    • argument sai type
    • upstream lỗi
  • 1 request resources/list.
  • 1 request resources/read cho mỗi nhóm resource.
  • 1 request prompts/list.
  • 1 request prompts/get cho mỗi prompt template.

Với server có 10 tools, 3 resource groups và 4 prompts, bạn có thể có khoảng 50-70 request test. Nếu upstream được mock, bộ test này thường đủ nhanh để chạy trên mỗi pull request.

Các lỗi thường gặp khi kiểm thử MCP server

Bỏ qua initialize

Một số server chỉ build tool registry trong bước initialize. Nếu gọi tools/list trước, response có thể sai hoặc server crash.

Luôn chạy flow theo thứ tự:

initialize -> tools/list -> tools/call
Enter fullscreen mode Exit fullscreen mode

Assert quá chặt trên error message

Error message thường thay đổi. Nên assert trên:

  • isError: true
  • error code ổn định
  • regex cho phần message quan trọng

Không nên assert toàn bộ chuỗi lỗi nếu chuỗi đó chứa stack trace, line number hoặc text dễ thay đổi.

Mock lệch khỏi production

Mock trả về shape khác API thật sẽ tạo cảm giác an toàn giả.

Nên:

  • Ghi lại fixture từ response thật.
  • Cập nhật fixture sau mỗi thay đổi API.
  • Có test staging định kỳ với upstream thật nếu phù hợp.

Quên streaming

MCP HTTP server có thể truyền kết quả qua SSE. Nếu server dùng streaming, test runner phải xử lý SSE và assert trên output đã được tập hợp. Apidog hỗ trợ SSE trong saved request; hãy bật streaming ở request tương ứng.

Không kiểm thử concurrency

MCP client có thể gửi nhiều tools/call song song. Nếu server có shared state không được khóa đúng, test tuần tự sẽ pass nhưng production vẫn lỗi.

Thêm ít nhất một test chạy song song cho các tool có state hoặc cache.

Nhầm lỗi protocol với lỗi tool

Lỗi tool nên trả về result với isError: true.

Lỗi protocol mới nên dùng JSON-RPC error.

Nếu trộn hai loại này, client như Claude Desktop có thể đóng kết nối. Đây cũng là dạng lỗi contract từng được đề cập trong bài phát triển nền tảng API theo hợp đồng trước.

Ví dụ kế hoạch test cho một weather MCP server

Giả sử server có 2 tools:

  • get_weather
  • get_forecast

Bộ test tối thiểu:

01_initialize
02_tools_list
03_get_weather_success
04_get_weather_missing_city
05_get_weather_invalid_city_type
06_get_weather_upstream_500
07_get_forecast_success
08_get_forecast_missing_days
09_get_forecast_invalid_days_type
10_get_forecast_upstream_timeout
Enter fullscreen mode Exit fullscreen mode

Ví dụ request lỗi argument:

{
  "jsonrpc": "2.0",
  "id": 44,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {}
  }
}
Enter fullscreen mode Exit fullscreen mode

Assertion mong muốn:

$.result.isError == true
$.result.content[0].type == "text"
$.result.content[0].text contains "city"
Enter fullscreen mode Exit fullscreen mode

Ví dụ request upstream lỗi, với mock server trả về HTTP 500:

{
  "jsonrpc": "2.0",
  "id": 45,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "mock-upstream-error"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Assertion:

$.result.isError == true
$.result.content[0].text contains "upstream"
Enter fullscreen mode Exit fullscreen mode

Các trường hợp sử dụng thực tế

Một nhóm xây dựng MCP server nội bộ cho API quản lý sự cố đã phát hiện ba lỗi hồi quy trong một tuần nhờ assertion trên shape của tools/list trong Apidog. Nếu không có test, lỗi schema đó sẽ được đẩy đến toàn bộ kỹ sư dùng Claude Desktop cùng lúc.

Một maintainer mã nguồn mở xây dựng MCP server cho Notion dùng mock Apidog để chạy CI mà không chạm rate limit của Notion. Bộ test chạy trên mọi PR, mất vài giây và cho phép contributor phát triển mà không cần API key thật.

Một nhóm platform vận hành nhiều MCP server nội bộ đã tạo workspace Apidog dùng chung để lưu contract của từng server. Server mới kế thừa baseline test; reviewer có thể so sánh schema diff trước khi merge.

Một nhóm khác dùng environment switcher của Apidog để chạy cùng test suite trên staging và production. Mỗi environment trỏ đến fixture mock khác nhau, nên cùng một bộ assertion có thể xác minh nhiều deployment mà không cần viết lại request.

Kết luận

MCP đã phổ biến nhanh, nhưng cách kiểm thử MCP server vẫn còn khá thủ công. Cách tiếp cận bền vững là coi MCP server như một API thực sự:

  1. Xác định contract.
  2. Kiểm thử thủ công bằng Inspector hoặc JSON-RPC thô.
  3. Lưu request chuẩn vào Apidog.
  4. Thêm assertion cho response.
  5. Mock upstream API.
  6. Chạy test trong CI.

Năm điểm cần nhớ:

  • MCP server là JSON-RPC API; hãy kiểm thử nghiêm túc như REST API.
  • Luôn bắt đầu bằng initialize.
  • tools/list là contract quan trọng nhất cho tool discovery.
  • Lỗi nghiệp vụ trong tool nên trả về isError: true, không phải JSON-RPC protocol error.
  • Apidog có thể gom request, assertion, mock và CI runner vào một workflow.

Bước tiếp theo: mở Apidog, tạo project, dán các JSON-RPC request bạn đã capture, thêm assertion cho tools/list, rồi chạy suite đầu tiên. Trong vòng một giờ, bạn sẽ biết contract MCP server của mình có đủ ổn để phát hành hay chưa.

FAQ

MCP là gì?

MCP, Model Context Protocol, là đặc tả mở của Anthropic cho cách AI client như Claude Desktop gọi tools, resources và prompts bên ngoài. Nó dùng JSON-RPC 2.0 qua stdio hoặc HTTP transport. Đặc tả MCP đầy đủ được công bố trên modelcontextprotocol.io.

Tôi có thể kiểm thử MCP server mà không cần HTTP wrapper không?

Có. MCP Inspector chính thức giao tiếp trực tiếp qua stdio và phù hợp cho kiểm thử thủ công. Với kiểm thử tự động trong Apidog, bạn nên bọc stdio bằng một HTTP wrapper mỏng trong CI. Production vẫn có thể dùng stdio.

Làm sao để mock upstream API mà MCP server gọi?

Định nghĩa mỗi upstream endpoint thành một mock route trong Apidog. Khi test, trỏ cấu hình MCP server đến mock URL. Khi chạy thật, dùng production URL. Mẫu này cũng được trình bày trong bài công cụ kiểm thử API cho kỹ sư QA.

Còn tool result dạng streaming thì sao?

MCP HTTP server có thể stream kết quả qua Server-Sent Events. Apidog hỗ trợ SSE trong saved request; bật streaming ở request đó và assert trên luồng đã được tập hợp.

Có nên kiểm thử protocol version không?

Có. Hãy pin protocolVersion bạn hỗ trợ trong initialize và assert trên giá trị đó. Version mismatch có thể gây lỗi client khó phát hiện.

Có nên kiểm thử với Claude Desktop thật không?

Có, ít nhất một lần trước mỗi release. Nhưng không nên dùng Claude Desktop làm regression test chính vì nó thủ công, chậm và không deterministic. Dùng Apidog cho test tự động, Claude Desktop cho smoke test cuối cùng.

Có thể xem ví dụ MCP server thực ở đâu?

Kho MCP servers chính thức có nhiều triển khai tham chiếu như filesystem, GitHub, Slack, Postgres và các server khác. Đọc phần tool definitions trong các server đó là cách nhanh nhất để hiểu một MCP contract tốt trông như thế nào.

Top comments (0)