Token导航 LogoToken导航TokenDH.com
MCP Server Mock logo
AI代理未说明官方级别未说明来源级核验

MCP Server Mock

MCP Server

一个用于集成测试的可编程MCP服务器模拟工具,支持JSON-RPC请求处理和响应配置,适用于测试MCP客户端代码。

工具数

1

提示词数

0

GitHub Stars

0

资源数

0
测试框架TypeScriptSession认证

安装说明

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

作者 / 组织

SiluPanda

提供方

SiluPanda

最后核验

2026/5/17 20:20

快速接入

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

详细介绍

mcp服务器模拟

用于集成测试的可编程模拟MCP服务器。

](https://www.npmjs.com/package/mcp-server-mock) ](https://www.npmjs.com/package/mcp-server-mock) ![license](https://github.com/SiluPanda/mcp-server-mock/blob/master/LICENSE) ](https://nodejs.org)

描述

mcp-server-mock 是一个完全可控的、进程内模拟MCP(模型上下文协议)服务器,专为测试MCP客户端代码而设计。它处理JSON-RPC请求并返回配置的响应,从而在不运行真实服务器的情况下实现确定性集成测试。

该包提供了一个流畅的生成器API,用于注册具有罐装响应、动态处理程序函数、错误注入、可配置延迟和场景状态机的工具、资源和提示处理程序。每个请求都会记录时间戳和响应详细信息,以便进行事后断言。

当您需要测试MCP客户端库、代理框架、MCP主机应用程序或任何使用MCP服务器的代码时,请使用此包。它在进程内运行,立即启动,并在每个平台上产生相同的结果。

零运行时依赖关系。

安装

npm install --save-dev mcp-server-mock

需要Node.js>=18。

快速开始

import { MockMCPServer } from 'mcp-server-mock';

// Create a mock server
const server = new MockMCPServer({ name: 'test-server', version: '1.0.0' });

// Register a tool with a static response
server.tool('search', {
  description: 'Search the web',
  inputSchema: {
    type: 'object',
    properties: { query: { type: 'string' } },
    required: ['query'],
  },
}).returns({
  content: [{ type: 'text', text: 'TypeScript is a typed superset of JavaScript' }],
});

// Complete the MCP initialization handshake
await server.handleRequest({
  jsonrpc: '2.0', id: 1, method: 'initialize',
  params: { protocolVersion: '2025-03-26', capabilities: {}, clientInfo: { name: 'my-client', version: '1.0.0' } },
});
server.handleNotification({ jsonrpc: '2.0', method: 'notifications/initialized' });

// Call the tool
const response = await server.handleRequest({
  jsonrpc: '2.0', id: 2, method: 'tools/call',
  params: { name: 'search', arguments: { query: 'TypeScript' } },
});

// Assert interactions
server.assertToolCalled('search', 1);
server.assertToolCalledWith('search', { query: 'TypeScript' });

特性

  • Fluent生成器API --使用可链接的配置方法注册工具、资源和提示。
  • 请求录制 --每个请求都包含序列号、ISO 8601时间戳、参数、响应结果或错误以及以毫秒为单位的持续时间。
  • 断言助手 --用于验证工具调用、资源读取、提示检索、方法调用和总请求计数的内置方法。所有断言在失败时都会抛出描述性错误。
  • 场景状态机 --定义由特定请求触发的命名状态和转换。工具、资源和提示根据当前状态返回不同的响应。
  • 误差仿真 --为所有标准JSON-RPC错误和自定义应用程序错误预先构建的工厂。为每个处理程序或全局注入错误。
  • 延迟和抖动注入 --模拟具有固定延迟、随机抖动范围或无限超时的慢速服务器。
  • 处理器耗尽 --将处理程序限制为N次调用,然后返回耗尽错误。
  • 夹具装载 --从JSON夹具对象以声明方式配置整个模拟服务器。
  • 响应拦截器 --在返回任何方法之前拦截并修改其响应。可用于模拟畸形或注入的字段。
  • 动态处理程序修改 --在测试过程中的任何时候添加或删除工具、资源和提示。
  • 自动能力推导 --服务器的 initialize 响应准确地反映了注册了哪些处理程序,与真实的MCP服务器行为相匹配。
  • 完整的MCP协议生命周期 --强制执行 initialize / notifications/initialized 握手。手柄 ping, logging/setLevel, resources/subscribe, resources/unsubscribe, completion/complete,以及所有标准MCP方法。
  • 零运行时依赖关系 --仅依赖于开发进行构建和测试。

API 参考

MockMCPServer

主要类。创建实例、注册处理程序、处理请求并运行断言。

import { MockMCPServer } from 'mcp-server-mock';

const server = new MockMCPServer(options);

构建器选项(MockServerOptions)

选项类型默认值描述
namestring*必需的*中报告的服务器名称 initialize 回应。
versionstring*必需的*中报告的服务器版本 initialize 回应。
protocolVersionstring'2025-03-26'要通告的MCP协议版本。
capabilitiesPartial*自动衍生*覆盖自动能力推导。
defaultDelayMsnumber0全局延迟应用于所有响应,除非每个处理程序都被覆盖。
recordNotificationsbooleantrue是否记录客户端通知。
enforceInitializationbooleantrue要求 initialize / notifications/initialized 在接受请求之前握手。

处理程序注册

// Tools
server.tool(name: string, definition?: ToolDefinition): ToolBuilder

// Resources
server.resource(uri: string, definition?: ResourceDefinition): ResourceBuilder

// Resource templates
server.resourceTemplate(definition: ResourceTemplateDefinition): void

// Prompts
server.prompt(name: string, definition?: PromptDefinition): PromptBuilder

// Completions
server.completion(handler: CompletionHandlerFn): void

请求处理

// Process a JSON-RPC request (returns a JSON-RPC response)
await server.handleRequest(request: JsonRpcRequest): Promise

// Process a JSON-RPC notification (no response)
server.handleNotification(notification: JsonRpcNotification): void

请求录制

server.requests                        // All recorded requests
server.notifications                   // All recorded notifications
server.requestsFor(method: string)     // Requests filtered by method
server.toolCalls(toolName: string)     // Tool call requests filtered by tool name
server.resourceReads(uri: string)      // Resource read requests filtered by URI
server.promptGets(promptName: string)  // Prompt get requests filtered by prompt name

断言

所有断言方法都抛出描述性 Error 当期望未得到满足时的消息。

server.assertToolCalled(toolName: string, times?: number): void
server.assertToolCalledWith(toolName: string, args: Record): void
server.assertToolNotCalled(toolName: string): void
server.assertResourceRead(uri: string, times?: number): void
server.assertPromptRetrieved(promptName: string, times?: number): void
server.assertMethodCalled(method: string, times?: number): void
server.assertNoRequests(): void
server.assertRequestCount(count: number): void

场景状态机

server.scenario(definition: ScenarioDefinition): void
server.currentState: string | undefined   // Current scenario state (readonly)
server.setState(stateName: string): void  // Manually set state

动态修改

server.removeTool(name: string): void
server.removeResource(uri: string): void
server.removePrompt(name: string): void
server.interceptResponse(method: string, fn: (response) => response): void

生命周期

server.resetRecordings(): void   // Clear recorded requests and notifications
server.resetAll(): void          // Reset handlers, recordings, scenario, and initialization state
server.loadFixture(fixture: FixtureFile): void  // Configure server from a fixture object
await server.close(): Promise             // Close the mock server

createMockServer

工厂功能相当于 new MockMCPServer(options).

import { createMockServer } from 'mcp-server-mock';

const server = createMockServer({ name: 'test', version: '1.0.0' });

ToolBuilder

返回者 server.tool().所有方法返回 this 为了实现流畅的链接。

方法说明
.returns(response: ToolResponse)设置静态响应。
.handlerFn(fn: ToolHandlerFn)设置一个动态处理函数,用于接收 (args, extra).
.throws(error: MockError)使此工具返回JSON-RPC错误。
.withDelay(ms: number)在响应之前添加固定延迟。
.withJitter(minMs: number, maxMs: number)在给定范围内添加随机延迟。
.timesOut()从不响应(模拟超时)。
.times(n: number)仅回复 n 次,然后返回耗尽错误。
.inState(stateName: string, response: ToolResponse)当场景处于给定状态时,返回不同的响应。

ResourceBuilder

返回者 server.resource().所有方法返回 this 为了实现流畅的链接。

方法说明
.returns(response: ResourceResponse)设置静态内容。
.handlerFn(fn: ResourceHandlerFn)设置一个动态处理函数,用于接收 (uri, extra).
.throws(error: MockError)使此资源返回JSON-RPC错误。
.withDelay(ms: number)在响应之前添加固定延迟。
.timesOut()从不响应(模拟超时)。
.inState(stateName: string, response: ResourceResponse)当场景处于给定状态时,返回不同的内容。

PromptBuilder

返回者 server.prompt().所有方法返回 this 为了实现流畅的链接。

方法说明
.returns(response: PromptResponse)设置静态响应。
.handlerFn(fn: PromptHandlerFn)设置一个动态处理函数,用于接收 (args, extra).
.throws(error: MockError)使此提示返回JSON-RPC错误。
.withDelay(ms: number)在响应之前添加固定延迟。
.inState(stateName: string, response: PromptResponse)当场景处于给定状态时,返回不同的响应。

MockErrors

为常见JSON-RPC错误预构建错误工厂。

import { MockErrors } from 'mcp-server-mock';

MockErrors.methodNotFound(method?: string)          // -32601
MockErrors.invalidParams(message?: string)           // -32602
MockErrors.internalError(message?: string)           // -32603
MockErrors.parseError()                              // -32700
MockErrors.invalidRequest(message?: string)          // -32600
MockErrors.custom(code: number, message: string, data?: unknown)  // Any code

RequestRecorder

捕获所有传入的请求和通知。通过访问 server.requestsserver.notifications,或单独使用。

import { RequestRecorder } from 'mcp-server-mock';

const recorder = new RequestRecorder();
recorder.recordRequest(method, params, id, result, error, durationMs);
recorder.recordNotification(method, params, direction);

recorder.requests          // ReadonlyArray
recorder.notifications     // ReadonlyArray
recorder.requestsFor(method)
recorder.toolCalls(toolName)
recorder.resourceReads(uri)
recorder.promptGets(promptName)
recorder.lastRequests(n)
recorder.requestCount      // number
recorder.reset()

HandlerRegistry

工具、资源、提示、资源模板和完成处理程序的内部注册表。处理能力推导。

import { HandlerRegistry } from 'mcp-server-mock';

const registry = new HandlerRegistry();
registry.registerTool(name, definition);
registry.registerResource(uri, definition);
registry.registerResourceTemplate(definition);
registry.registerPrompt(name, definition);
registry.setCompletionHandler(handler);

registry.getTool(name)
registry.getResource(uri)
registry.getPrompt(name)
registry.removeTool(name)
registry.removeResource(uri)
registry.removePrompt(name)

registry.listTools()
registry.listResources()
registry.listResourceTemplates()
registry.listPrompts()
registry.deriveCapabilities()
registry.resetAll()

ScenarioManager

管理场景状态机以进行多步骤交互测试。

import { ScenarioManager } from 'mcp-server-mock';

const manager = new ScenarioManager();
manager.configure({ initialState: 'idle', transitions: [...] });
manager.currentState       // string | undefined
manager.isConfigured       // boolean
manager.setState('active');
manager.processRequest(method, params);  // Returns new state
manager.reset();           // Reset to initial state
manager.clear();           // Remove configuration entirely

AssertionHelper

用于验证模拟服务器交互的断言助手。当期望未得到满足时,所有方法都会产生描述性错误。

import { AssertionHelper } from 'mcp-server-mock';

const helper = new AssertionHelper(recorder);
helper.assertToolCalled(toolName, times?);
helper.assertToolCalledWith(toolName, args);
helper.assertToolNotCalled(toolName);
helper.assertResourceRead(uri, times?);
helper.assertPromptRetrieved(promptName, times?);
helper.assertMethodCalled(method, times?);
helper.assertNoRequests();
helper.assertRequestCount(count);

配置

服务器功能

默认情况下,功能会自动从注册的处理程序中派生出来:

  • tools 注册任何工具时都会声明功能。
  • resources 能力(与 subscribe: truelistChanged: true)在注册任何资源或资源模板时声明。
  • prompts 当注册任何提示时,都会声明功能。
  • logging 能力总是被宣布的。
  • completions 当设置完成处理程序时,会声明功能。

通过传递来覆盖自动推导 capabilities 在构造函数选项中:

const server = new MockMCPServer({
  name: 'test',
  version: '1.0.0',
  capabilities: {
    tools: { listChanged: false },
    resources: undefined,  // Explicitly disable
  },
});

全局延迟

对所有处理程序应用默认延迟:

const server = new MockMCPServer({
  name: 'test',
  version: '1.0.0',
  defaultDelayMs: 100,
});

每处理程序延迟(通过 .withDelay().withJitter())优先于全局默认值。

初始化强制

默认情况下,服务器会拒绝之前的所有请求 initialize / notifications/initialized 握手完成。禁用此选项以进行更简单的测试设置:

const server = new MockMCPServer({
  name: 'test',
  version: '1.0.0',
  enforceInitialization: false,
});

错误处理

JSON-RPC错误注入

使用以下命令在特定处理程序上注入错误 MockErrors 工厂:

import { MockErrors } from 'mcp-server-mock';

// Standard JSON-RPC errors
server.tool('broken').throws(MockErrors.internalError('Database crashed'));
server.tool('missing').throws(MockErrors.methodNotFound('search'));
server.tool('bad_input').throws(MockErrors.invalidParams('Missing required field'));

// Custom application errors with data payload
server.tool('rate_limited').throws(
  MockErrors.custom(-32000, 'Rate limited', { retryAfter: 60 })
);

处理器耗尽

将处理程序限制为固定的调用次数:

server.tool('limited')
  .returns({ content: [{ type: 'text', text: 'ok' }] })
  .times(3);

// First 3 calls succeed; the 4th returns:
// { code: -32603, message: "Handler exhausted after 3 calls" }

超时模拟

模拟一个从不响应的处理程序:

server.tool('black_hole').timesOut();
// The returned promise never resolves

未处理的错误

如果一个动态处理函数抛出一个正则 Error,它被捕获并包装为JSON-RPC内部错误(-32603).如果它抛出一个与 MockError 形状({ code: number, message: string }),则直接返回该错误。

初始化错误

enforceInitializationtrue (默认),在握手完成之前发送的任何请求都会收到 -32600 (无效请求)错误,消息为“服务器未初始化”。

高级用法

动态处理函数

对计算响应使用处理函数:

server.tool('add', {
  inputSchema: {
    type: 'object',
    properties: { a: { type: 'number' }, b: { type: 'number' } },
  },
}).handlerFn((args) => ({
  content: [{ type: 'text', text: String(Number(args.a) + Number(args.b)) }],
}));

处理函数接收 (args: Record, extra: RequestExtra)The extra 对象提供:

  • extra.state --当前场景状态(string | undefined).
  • extra.server --参考 MockMCPServer 呼叫实例 setState()resetRecordings() 从处理器内部。

场景状态机

定义多步骤交互测试的状态和转换:

server.scenario({
  initialState: 'unauthenticated',
  transitions: [
    { from: 'unauthenticated', method: 'tools/call', match: { name: 'login' }, to: 'authenticated' },
    { from: 'authenticated', method: 'tools/call', match: { name: 'logout' }, to: 'unauthenticated' },
  ],
});

server.tool('get_data')
  .inState('unauthenticated', {
    content: [{ type: 'text', text: 'Access denied' }],
    isError: true,
  })
  .inState('authenticated', {
    content: [{ type: 'text', text: '{"users": 42}' }],
  });

过渡支持三种匹配模式:

  • 无匹配 --任何具有指定方法的请求都会触发转换。
  • 对象匹配 --根据请求参数进行浅层部分匹配。匹配对象中的所有键值对都必须出现在参数中。
  • 功能匹配 --谓词函数 (params) => boolean 用于复杂的匹配逻辑。
// Function matcher example
{
  from: 'start',
  method: 'tools/call',
  match: (params) => params.name === 'step1' && params.arguments?.mode === 'fast',
  to: 'running',
}

状态转换发生在处理程序执行后,因此处理程序可以看到请求时的状态。

夹具装载

以声明方式配置整个模拟服务器:

server.loadFixture({
  server: { name: 'test', version: '1.0.0', defaultDelayMs: 10 },
  tools: [
    {
      name: 'search',
      description: 'Search tool',
      inputSchema: { type: 'object', properties: { q: { type: 'string' } } },
      response: { content: [{ type: 'text', text: 'result' }] },
    },
    {
      name: 'fail',
      error: { code: -32603, message: 'broken' },
    },
    {
      name: 'stateful',
      states: {
        idle: { content: [{ type: 'text', text: 'idle data' }] },
        active: { content: [{ type: 'text', text: 'active data' }] },
      },
    },
  ],
  resources: [
    {
      uri: 'file:///config.json',
      name: 'Config',
      mimeType: 'application/json',
      response: { contents: [{ uri: 'file:///config.json', text: '{"debug": true}' }] },
    },
  ],
  resourceTemplates: [
    { name: 'User', uriTemplate: 'db://users/{id}', description: 'User by ID' },
  ],
  prompts: [
    {
      name: 'review',
      description: 'Code review',
      arguments: [{ name: 'language', required: true }],
      response: {
        messages: [{ role: 'user', content: { type: 'text', text: 'Review this code.' } }],
      },
    },
  ],
  scenario: {
    initialState: 'idle',
    transitions: [
      { from: 'idle', method: 'tools/call', match: { name: 'stateful' }, to: 'active' },
    ],
  },
});

响应拦截器

拦截并修改任何方法的响应。可用于测试客户端如何处理格式错误或意外的响应字段:

server.interceptResponse('tools/call', (response) => {
  const result = response.result as Record;
  result.extraField = 'injected';
  return response;
});

完工处理人员

为注册处理程序 completion/complete 请求:

server.completion((ref, argument) => ({
  completion: {
    values: ['typescript', 'terraform'].filter(v => v.startsWith(argument.value)),
    hasMore: false,
  },
}));

测试生命周期模式

import { describe, it, beforeEach, afterEach } from 'vitest';
import { MockMCPServer } from 'mcp-server-mock';

describe('my MCP client', () => {
  let server: MockMCPServer;

  beforeEach(async () => {
    server = new MockMCPServer({ name: 'test', version: '1.0.0' });

    // Complete initialization handshake
    await server.handleRequest({
      jsonrpc: '2.0', id: 1, method: 'initialize',
      params: { protocolVersion: '2025-03-26', capabilities: {}, clientInfo: { name: 'client', version: '1.0.0' } },
    });
    server.handleNotification({ jsonrpc: '2.0', method: 'notifications/initialized' });

    // Register handlers for this test suite
    server.tool('search').returns({
      content: [{ type: 'text', text: 'result' }],
    });
  });

  afterEach(async () => {
    await server.close();
  });

  it('should call the search tool', async () => {
    // ... exercise your client code ...

    server.assertToolCalled('search', 1);
    server.assertToolCalledWith('search', { query: 'test' });
  });

  it('should handle errors', async () => {
    server.resetRecordings();
    // ... different test ...
  });
});

支持的MCP方法

模拟服务器处理所有标准MCP请求方法:

方法说明
initialize协议握手。返回服务器信息和功能。
ping活体检查。返回空结果。
tools/list返回所有已注册的带有模式的工具。
tools/call按名称执行工具处理程序。
resources/list返回所有已注册的资源。
resources/read按URI读取资源
resources/templates/list返回所有已注册的资源模板。
resources/subscribe接受订阅(返回空结果)。
resources/unsubscribe接受取消订阅(返回空结果)。
prompts/list返回所有已注册的提示。
prompts/get按名称检索提示。
completion/complete委托给已注册的完成处理程序。
logging/setLevel接受日志级别更改。

未知方法返回a -32601 (找不到方法)错误。

TypeScript

mcp-server-mock 是用TypeScript编写的,并在编译后的JavaScript中附带类型声明。所有公共类型都从包入口点导出。

导出类型

import type {
  MockServerOptions,
  ServerCapabilities,
  ToolDefinition,
  ToolAnnotations,
  ToolContent,
  ToolResponse,
  ToolHandlerFn,
  ResourceDefinition,
  ResourceContent,
  ResourceResponse,
  ResourceHandlerFn,
  ResourceTemplateDefinition,
  PromptDefinition,
  PromptArgument,
  PromptMessage,
  PromptResponse,
  PromptHandlerFn,
  CompletionResponse,
  CompletionHandlerFn,
  MockError,
  RecordedRequest,
  RecordedNotification,
  RequestExtra,
  ScenarioDefinition,
  ScenarioTransition,
  JsonRpcRequest,
  JsonRpcNotification,
  JsonRpcResponse,
  JsonRpcMessage,
  FixtureFile,
  FixtureTool,
  FixtureResource,
  FixtureResourceTemplate,
  FixturePrompt,
  RegisteredHandler,
  MockMCPServerInterface,
} from 'mcp-server-mock';

导出的类和函数

import {
  MockMCPServer,
  createMockServer,
  MockErrors,
  ToolBuilder,
  ResourceBuilder,
  PromptBuilder,
  RequestRecorder,
  HandlerRegistry,
  ScenarioManager,
  AssertionHelper,
} from 'mcp-server-mock';

编译器目标

该包通过CommonJS模块输出编译为ES2022。包括声明文件和源代码映射。

许可证

麻省理工学院

目录标签

目录标签

测试框架TypeScriptSession认证集成测试本地部署JSON-RPCMCP协议模拟工具

接入字段

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

未说明

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

session

工具数量(toolCount,工具数)

1

资源数量(resourceCount,资源数)

0

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

0

权限和风险

未说明session部署方式未说明

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

安装前确认

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

仍需确认:installCommand

来源信息

继续浏览同类 MCP