Token导航 LogoToken导航TokenDH.com
MCP Test Kit logo
开发工具未说明官方级别未说明来源级核验

MCP Test Kit

MCP Server

一个用于Model Context Protocol(MCP)服务器的全面测试框架,提供MCPTestClient、自定义Vitest匹配器和模拟服务器等功能。

工具数

0

提示词数

0

GitHub Stars

0

资源数

0
测试框架服务器测试TypeScriptClaudeClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

CrashBytes

提供方

CrashBytes

最后核验

2026/5/17 20:21

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

MCP测试套件

![Tests](https://github.com/CrashBytes/mcp-test-kit/actions) ![codecov](https://codecov.io/gh/CrashBytes/mcp-test-kit)

模型上下文协议(MCP)服务器的综合测试框架

](https://www.npmjs.com/package/@crashbytes/mcp-test-kit) ![License: MIT](https://opensource.org/licenses/MIT)

📖 目录

🤔 什么是MCP?

模型上下文协议(MCP) 是由Anthropic开发的一种开放协议,它使像Claude这样的人工智能助手能够安全地与外部工具、数据源和服务进行交互。将其视为AI模型的一种标准化方式:

  • 访问工具:执行搜索数据库、调用API或运行计算等功能
  • 阅读资源:从文件、数据库或外部服务获取数据
  • 使用提示:利用预构建的提示模板完成常见任务

现实世界MCP示例

以下是您可以构建的一些实用的MCP服务器:

  1. 天气服务器:提供任何城市的当前天气数据
  2. 数据库服务器:允许查询PostgreSQL/MySQL数据库
  3. 文件系统服务器:允许读取/写入磁盘上的文件
  4. API集成服务器:连接到第三方API(GitHub、Slack等)
  5. 计算器服务器:执行复杂的数学运算

MCP的工作原理

graph LR
    A[Claude
Client] |MCP| B[MCP Server
Your Code]
    B  C[Your Data
or Service]

MCP服务器充当Claude和您的数据/服务之间的桥梁,通过标准化协议公开它们。

🎯 什么是MCP测试套件?

MCP测试套件 是一个测试框架,可以轻松为MCP服务器编写自动化测试。它提供:

🔧 核心功能

  1. MCPTestClient:连接到MCP服务器并调用其工具/资源的测试客户端
  2. 定制Vitest配对器:用于验证MCP响应的专门断言
  3. 模拟服务器:创建伪造的MCP服务器以测试客户端代码
  4. TypeScript支持:完整的类型定义,以获得更好的IDE支持和类型安全

🎪 它解决的问题

没有MCP测试套件,测试MCP服务器具有挑战性:

  • ❌ 您需要手动启动服务器并与之交互
  • ❌ 没有标准化的方法来断言MCP特定的行为
  • ❌ 集成测试的复杂设置
  • ❌ 难以测试的错误条件和边缘情况

使用MCP测试套件:

  • ✅ 在测试中以编程方式启动和停止服务器
  • ✅ 使用直观的匹配器,如 toBeValidMCPTool()toMatchMCPToolResponse()
  • ✅ 在几分钟内编写全面的集成测试
  • ✅ 轻松测试错误处理和边缘情况

💡 为什么使用MCP测试套件?

面向MCP服务器开发人员

如果您正在构建MCP服务器,MCP测试套件可以帮助您:

  • 验证正确性:确保您的服务器正确实现MCP协议
  • 测试工具:验证您的工具是否返回预期结果
  • 测试资源:确认资源可访问并返回正确的数据
  • 测试错误处理:验证错误响应是否符合MCP标准
  • 回归测试:在bug进入生产环境之前将其捕获
  • 文档:测试是服务器行为的实时文档

示例用例

假设你构建了一个气象MCP服务器。使用MCP测试套件,您可以编写以下测试:

it('should return weather data for San Francisco', async () => {
  const result = await client.callTool('get-weather', { 
    city: 'San Francisco' 
  });
  
  expect(result).toMatchMCPToolResponse();
  expect(result.content[0].text).toContain('temperature');
  expect(result.content[0].text).toContain('San Francisco');
});

it('should handle invalid city names', async () => {
  await expect(
    client.callTool('get-weather', { city: '' })
  ).rejects.toMatchMCPError({
    code: -32602,
    message: /invalid.*city/i
  });
});

📦 安装

# Using npm
npm install --save-dev @crashbytes/mcp-test-kit

# Using yarn
yarn add -D @crashbytes/mcp-test-kit

# Using pnpm
pnpm add -D @crashbytes/mcp-test-kit

先决条件

  • Node.js 18+
  • 测试框架(Vitest推荐)
  • TypeScript(可选,但推荐)

🚀 快速开始

1.创建您的第一个测试

// tests/weather-server.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { createMCPTestClient } from '@crashbytes/mcp-test-kit';
import type { MCPTestClient } from '@crashbytes/mcp-test-kit';
import '@crashbytes/mcp-test-kit/matchers';

describe('Weather MCP Server', () => {
  let client: MCPTestClient;

  beforeAll(async () => {
    // Connect to your MCP server
    client = await createMCPTestClient({
      command: 'node',
      args: ['dist/server.js'],
    });
  });

  afterAll(async () => {
    await client.disconnect();
  });

  it('should list available tools', async () => {
    const tools = await client.listTools();
    
    expect(tools).toHaveLength(1);
    expect(tools[0]).toBeValidMCPTool();
    expect(tools[0].name).toBe('get-weather');
  });

  it('should get weather for a city', async () => {
    const result = await client.callTool('get-weather', {
      city: 'London',
    });

    expect(result).toMatchMCPToolResponse();
    expect(result.content[0].text).toContain('London');
  });
});

2.运行测试

npm test

就是这样!您现在正在测试MCP服务器。

🧩 核心概念

MCPTestClient

MCPTestClient 是测试MCP服务器的主界面。它

  • 将MCP服务器作为子进程生成
  • 使用MCP协议建立连接
  • 提供调用工具、列出资源等的方法。
  • 测试完成后处理清理

关键方法:

  • listTools():从服务器获取所有可用工具
  • callTool(name, args):使用参数执行工具
  • listResources():获取所有可用资源
  • readResource(uri):阅读特定资源
  • listPrompts():获取所有可用提示
  • getPrompt(name, args):获取特定提示

定制配对器

MCP测试套件为MCP特定的断言提供自定义Vitest匹配器:

toBeValidMCPTool()

验证对象是否是格式正确的MCP工具:

const tool = {
  name: 'calculate',
  description: 'Performs calculations',
  inputSchema: {
    type: 'object',
    properties: {
      expression: { type: 'string' }
    }
  }
};

expect(tool).toBeValidMCPTool();

toBeValidMCPResource()

验证对象是否是格式正确的MCP资源:

const resource = {
  uri: 'file:///data/users.json',
  name: 'Users Database',
  description: 'List of all users'
};

expect(resource).toBeValidMCPResource();

toMatchMCPToolResponse()

验证工具响应的结构:

const response = await client.callTool('get-weather', { city: 'Paris' });

expect(response).toMatchMCPToolResponse();
expect(response.content[0].text).toContain('Paris');

toMatchMCPError(error)

验证MCP错误响应:

await expect(
  client.callTool('invalid-tool', {})
).rejects.toMatchMCPError({
  code: -32601, // Method not found
  message: /not found/i
});

toHaveMCPProtocolVersion(version)

验证MCP协议版本:

const info = await client.getServerInfo();
expect(info).toHaveMCPProtocolVersion('2024-11-05');

📚 API 参考

createMCPTestClient(配置)

创建并连接到MCP测试客户端。

参数:

interface MCPTestClientConfig {
  command: string;           // Command to run (e.g., 'node', 'python')
  args?: string[];          // Arguments for the command
  env?: Record; // Environment variables
  timeout?: number;         // Timeout in milliseconds (default: 5000)
  transport?: 'stdio';      // Transport type (only stdio supported)
  debug?: boolean;          // Enable debug logging
}

退货: Promise

例子:

const client = await createMCPTestClient({
  command: 'node',
  args: ['dist/server.js'],
  env: {
    NODE_ENV: 'test',
    DATABASE_URL: 'sqlite::memory:'
  },
  timeout: 10000,
  debug: true
});

MCPTestClient方法

listTools(): Promise

列出MCP服务器上可用的所有工具。

const tools = await client.listTools();
console.log(tools[0].name); // 'get-weather'

callTool(name: string, args?: object): Promise

使用给定的参数执行工具。

const result = await client.callTool('calculate', {
  expression: '2 + 2'
});

listResources(): Promise

列出MCP服务器上可用的所有资源。

const resources = await client.listResources();
console.log(resources[0].uri); // 'file:///data/users.json'

readResource(uri: string): Promise

读取特定资源的内容。

const content = await client.readResource('file:///data/users.json');
console.log(content.text);

listPrompts(): Promise

列出MCP服务器上可用的所有提示。

const prompts = await client.listPrompts();

getPrompt(name: string, args?: Record): Promise

获取带有参数的特定提示。

const prompt = await client.getPrompt('code-review', {
  language: 'typescript'
});

disconnect(): Promise

断开与MCP服务器的连接并清理资源。

await client.disconnect();

💻 例子

示例1:测试计算器服务器

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { createMCPTestClient, MCPTestClient } from '@crashbytes/mcp-test-kit';
import '@crashbytes/mcp-test-kit/matchers';

describe('Calculator MCP Server', () => {
  let client: MCPTestClient;

  beforeAll(async () => {
    client = await createMCPTestClient({
      command: 'node',
      args: ['dist/calculator-server.js'],
    });
  });

  afterAll(async () => {
    await client.disconnect();
  });

  describe('Basic Operations', () => {
    it('should add two numbers', async () => {
      const result = await client.callTool('calculate', {
        operation: 'add',
        a: 5,
        b: 3
      });

      expect(result).toMatchMCPToolResponse();
      expect(result.content[0].text).toBe('8');
    });

    it('should handle division by zero', async () => {
      await expect(
        client.callTool('calculate', {
          operation: 'divide',
          a: 10,
          b: 0
        })
      ).rejects.toMatchMCPError({
        code: -32602,
        message: /division by zero/i
      });
    });
  });

  describe('Tool Validation', () => {
    it('should have valid tool schema', async () => {
      const tools = await client.listTools();
      const calcTool = tools.find(t => t.name === 'calculate');

      expect(calcTool).toBeValidMCPTool();
      expect(calcTool?.inputSchema.properties).toHaveProperty('operation');
      expect(calcTool?.inputSchema.properties).toHaveProperty('a');
      expect(calcTool?.inputSchema.properties).toHaveProperty('b');
    });
  });
});

示例2:测试数据库服务器

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { createMCPTestClient, MCPTestClient } from '@crashbytes/mcp-test-kit';
import '@crashbytes/mcp-test-kit/matchers';

describe('Database MCP Server', () => {
  let client: MCPTestClient;

  beforeAll(async () => {
    client = await createMCPTestClient({
      command: 'node',
      args: ['dist/db-server.js'],
      env: {
        DATABASE_URL: 'sqlite::memory:',
        NODE_ENV: 'test'
      }
    });
  });

  afterAll(async () => {
    await client.disconnect();
  });

  it('should query users from database', async () => {
    const result = await client.callTool('query', {
      sql: 'SELECT * FROM users WHERE age > 18'
    });

    expect(result).toMatchMCPToolResponse();
    const data = JSON.parse(result.content[0].text);
    expect(Array.isArray(data)).toBe(true);
  });

  it('should list database resources', async () => {
    const resources = await client.listResources();

    expect(resources.length).toBeGreaterThan(0);
    resources.forEach(resource => {
      expect(resource).toBeValidMCPResource();
    });
  });

  it('should read table schema', async () => {
    const content = await client.readResource('schema://users');
    
    expect(content.text).toContain('id');
    expect(content.text).toContain('name');
    expect(content.text).toContain('email');
  });
});

示例3:使用模拟进行测试

import { describe, it, expect } from 'vitest';
import { createMockMCPServer, mockTool } from '@crashbytes/mcp-test-kit/mocks';

describe('Mock MCP Server', () => {
  it('should create a mock server with tools', async () => {
    const server = createMockMCPServer({
      tools: [
        mockTool(
          'greet',
          async (args) => ({
            content: [{ type: 'text', text: `Hello, ${args.name}!` }]
          }),
          {
            description: 'Greets a person',
            inputSchema: {
              type: 'object',
              properties: {
                name: { type: 'string' }
              }
            }
          }
        )
      ]
    });

    const tools = server.getTools();
    expect(tools).toHaveLength(1);
    expect(tools[0].name).toBe('greet');

    const result = await server.callTool('greet', { name: 'World' });
    expect(result.content[0].text).toBe('Hello, World!');
  });
});

🎓 最佳实践

1.使用before All/after All进行连接管理

let client: MCPTestClient;

beforeAll(async () => {
  client = await createMCPTestClient({ /* config */ });
});

afterAll(async () => {
  await client.disconnect();
});

2.测试成功和失败案例

// Test success
it('should return data for valid input', async () => {
  const result = await client.callTool('tool', { valid: true });
  expect(result).toMatchMCPToolResponse();
});

// Test failure
it('should reject invalid input', async () => {
  await expect(
    client.callTool('tool', { invalid: true })
  ).rejects.toMatchMCPError({ code: -32602 });
});

3.验证工具模式

it('should have properly defined tools', async () => {
  const tools = await client.listTools();
  
  tools.forEach(tool => {
    expect(tool).toBeValidMCPTool();
    expect(tool.description).toBeTruthy();
    expect(tool.inputSchema.properties).toBeDefined();
  });
});

4.使用描述性测试名称

// ❌ Bad
it('test 1', async () => { /* ... */ });

// ✅ Good
it('should return weather data for valid city names', async () => { /* ... */ });

5.隔离测试

每个测试都应该是独立的,不依赖于其他测试的状态。

// ❌ Bad - Tests depend on order
it('creates a user', async () => { /* ... */ });
it('updates the user', async () => { /* assumes user exists */ });

// ✅ Good - Each test is independent
beforeEach(async () => {
  await client.callTool('reset-database', {});
});

it('creates a user', async () => { /* ... */ });
it('updates a user', async () => {
  await client.callTool('create-user', { name: 'Test' });
  await client.callTool('update-user', { name: 'Updated' });
});

🤝 贡献

欢迎投稿!请随时提交拉取请求。

开发设置

# Clone the repository
git clone https://github.com/crashbytes/mcp-test-kit.git
cd mcp-test-kit

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Run linter
npm run lint

📄 许可证

MIT© 黑洞软件有限责任公司

🔗 链接

  • NPM包: https://www.npmjs.com/package/@crashbytes/mcp测试套件
  • GitHub: https://github.com/crashbytes/mcp-test-kit
  • MCP规范: https://spec.modelcontextprotocol.io/
  • CrashBytes博客: https://crashbytes.com

🙏 致谢

  • Anthropic 用于创建模型上下文协议
  • 维测试 优秀的测试框架
  • MCP社区提供反馈和贡献

______________________________________________________________________

建于❤️ 通过 CrashBytes

目录标签

目录标签

测试框架服务器测试TypeScriptClaude本地部署MCP协议自动化测试工具验证

支持客户端

Claude

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

none

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明none部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP