| English | 中文 |
一个 TypeScript 工具,用于审计 MCP (Model Context Protocol) 服务器的所有交互。通过透明代理方式拦截并记录所有 MCP 服务器的输入/输出操作,生成完整的审计日志,帮助开发者调试、监控和合规审查 MCP 应用。
本工具支持两种使用模式:
在你的 TypeScript/Node.js 代码中使用 MCPWrapper 类来包装和调用 MCP 服务器。
作为独立的 MCP 服务器运行,可以被 Claude Desktop 或其他 MCP 客户端连接。
👉 服务器模式详细文档: 查看 SERVER.md
mcp-auditor/
├── src/
│ ├── core/ # 核心包装功能
│ │ ├── wrapper.ts # MCPWrapper 核心类
│ │ ├── logger.ts # 日志记录器
│ │ └── types.ts # TypeScript 类型定义
│ ├── server/ # 服务器专用代码
│ │ ├── server.ts # MCP 服务器实现 ⭐
│ │ └── config.ts # 服务器配置加载
│ └── index.ts # 主入口文件
├── examples/
│ ├── library/ # 库使用示例
│ │ ├── basic-usage.ts # 基础使用示例
│ │ └── test-wrapper.ts # 测试脚本
│ └── server/ # 服务器示例
│ ├── server-wrapper.ts # 代理服务器示例
│ └── config-example.ts # 配置示例
├── docs/ # 文档
│ ├── README.md # 英文文档
│ ├── README.zh.md # 中文文档
│ └── SERVER.md # 服务器模式文档 ⭐
├── logs/ # 日志文件目录
├── dist/ # 编译输出
├── config.example.json # 服务器配置示例
└── package.json
作为库使用(推荐):
npm install mcp-auditor
全局 CLI 安装:
npm install -g mcp-auditor
从源码安装:
git clone https://github.com/algovate/mcp-auditor.git
cd mcp-auditor
npm install
npm run build
# 1. 安装依赖并构建
npm install
npm run build
# 2. 配置环境变量
export MCP_WRAPPED_SERVER_COMMAND=npx
export MCP_WRAPPED_SERVER_ARGS="-y,@modelcontextprotocol/server-filesystem,/tmp"
export MCP_LOG_FILE=./logs/mcp-server.log
# 3. 启动服务器
npm start
在 Claude Desktop 配置文件中添加 (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"wrapped-filesystem": {
"command": "node",
"args": ["/path/to/mcp-auditor/dist/server/server.js"],
"env": {
"MCP_WRAPPED_SERVER_COMMAND": "npx",
"MCP_WRAPPED_SERVER_ARGS": "-y,@modelcontextprotocol/server-filesystem,/Users/yourname/Documents",
"MCP_LOG_FILE": "/Users/yourname/logs/mcp-wrapper.log"
}
}
}
}
📖 完整服务器文档: SERVER.md
import { MCPWrapper } from 'mcp-auditor';
async function main() {
// 创建审计器实例
const wrapper = new MCPWrapper({
serverCommand: 'npx',
serverArgs: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
logFilePath: './logs/mcp-wrapper.log',
logToolCalls: true,
logToolResults: true
});
// 连接到 MCP 服务器
await wrapper.connect();
// 获取可用工具
const tools = wrapper.getTools();
console.log('可用工具:', tools.map(t => t.name));
// 调用工具
const result = await wrapper.callTool('list_directory', {
path: '/tmp'
});
console.log('结果:', result);
// 断开连接
await wrapper.disconnect();
}
main().catch(console.error);
创建一个 MCP 服务器来包装另一个 MCP 服务器:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { MCPWrapper } from 'mcp-auditor';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
async function main() {
// 创建审计器
const wrapper = new MCPWrapper({
serverCommand: 'npx',
serverArgs: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
logFilePath: './logs/proxy.log'
});
await wrapper.connect();
// 创建代理服务器
const server = new Server({
name: 'mcp-proxy',
version: '1.0.0'
}, {
capabilities: { tools: {} }
});
// 暴露被包装服务器的工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: wrapper.getTools() };
});
// 代理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
return await wrapper.callTool(
request.params.name,
request.params.arguments as Record<string, unknown>
);
});
// 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
new MCPWrapper(config: MCPWrapperConfig)
连接管理:
| 方法 | 描述 | 返回值 |
|——|——|——–|
| connect() | 连接到被包装的 MCP 服务器 | Promise<void> |
| disconnect() | 断开连接并关闭日志记录器 | Promise<void> |
| isConnected() | 检查是否已连接 | boolean |
工具操作:
| 方法 | 描述 | 返回值 |
|——|——|——–|
| getTools() | 获取所有可用工具的列表 | Tool[] |
| getTool(name) | 通过名称获取特定工具 | Tool \| undefined |
| hasTool(name) | 检查工具是否存在 | boolean |
| callTool(toolName, params?) | 调用工具 | Promise<CallToolResult> |
资源操作:
| 方法 | 描述 | 返回值 |
|——|——|——–|
| getResources() | 获取所有可用资源的列表 | Resource[] |
| getResource(uri) | 通过 URI 获取特定资源 | Resource \| undefined |
| hasResource(uri) | 检查资源是否存在 | boolean |
| readResource(uri) | 读取资源 | Promise<ReadResourceResult> |
提示词操作:
| 方法 | 描述 | 返回值 |
|——|——|——–|
| getPrompts() | 获取所有可用提示词的列表 | Prompt[] |
| getPromptDefinition(name) | 通过名称获取特定提示词定义 | Prompt \| undefined |
| hasPrompt(name) | 检查提示词是否存在 | boolean |
| getPrompt(name, args?) | 获取带参数的提示词 | Promise<GetPromptResult> |
日志记录:
| 方法 | 描述 | 返回值 |
|——|——|——–|
| getLogger() | 获取日志记录器实例 | MCPLogger |
interface MCPWrapperConfig {
// 必需参数
serverCommand: string; // MCP 服务器命令或可执行文件路径
logFilePath: string; // 日志文件路径
// 可选参数
serverArgs?: string[]; // 传递给 MCP 服务器的参数
serverEnv?: Record<string, string>; // 环境变量
logToolCalls?: boolean; // 是否记录工具调用(默认:true)
logToolResults?: boolean; // 是否记录工具结果(默认:true)
logAppend?: boolean; // 是否追加到日志文件(默认:true)
logFormat?: 'structured' | 'jsonrpc'; // 日志格式(默认:'structured')
}
通用日志:
| 方法 | 描述 |
|——|——|
| logEntry(entry) | 记录结构化日志条目 |
| log(level, message, data?) | 记录普通消息 |
| logError(error, context?) | 记录错误 |
| close() | 关闭日志记录器 |
工具日志:
| 方法 | 描述 |
|——|——|
| logToolCall(toolName, params) | 记录工具调用请求 |
| logToolResult(toolName, result, error?) | 记录工具结果 |
资源日志:
| 方法 | 描述 |
|——|——|
| logResourceListRequest() | 记录资源列表请求 |
| logResourceListResponse(resources) | 记录资源列表响应 |
| logResourceReadRequest(uri) | 记录资源读取请求 |
| logResourceReadResponse(uri, result, error?) | 记录资源读取响应 |
提示词日志:
| 方法 | 描述 |
|——|——|
| logPromptListRequest() | 记录提示词列表请求 |
| logPromptListResponse(prompts) | 记录提示词列表响应 |
| logPromptGetRequest(name, args?) | 记录提示词获取请求 |
| logPromptGetResponse(name, result, error?) | 记录提示词获取响应 |
服务器日志:
| 方法 | 描述 |
|——|——|
| logServerRequest(method, params?) | 记录服务器请求 |
| logServerResponse(method, result, error?) | 记录服务器响应 |
MCP Auditor 支持两种日志格式:
包含时间戳、方向和元数据的详细审计日志。最适合调试和分析。
const wrapper = new MCPWrapper({
serverCommand: 'npx',
serverArgs: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
logFilePath: './logs/audit.log',
logFormat: 'structured' // 默认
});
每个条目包含:
interface LogEntry {
timestamp: string; // ISO 8601 时间戳
direction: 'input' | 'output'; // 数据流方向
type: 'tool_call' | 'tool_result' | 'resource_list' | 'resource_read' | 'prompt_list' | 'prompt_get' | 'server_request' | 'server_response' | 'error';
data: any; // 日志数据
}
工具调用 (输入):
{
"timestamp": "2024-01-15T10:30:00.000Z",
"direction": "input",
"type": "tool_call",
"data": {
"toolName": "read_file",
"params": {
"path": "/tmp/example.txt"
}
}
}
工具结果 (输出):
{
"timestamp": "2024-01-15T10:30:00.123Z",
"direction": "output",
"type": "tool_result",
"data": {
"toolName": "read_file",
"result": {
"content": [
{
"type": "text",
"text": "文件内容..."
}
]
}
}
}
原始 JSON-RPC 协议消息。最适合协议调试和网络分析。
const wrapper = new MCPWrapper({
serverCommand: 'npx',
serverArgs: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
logFilePath: './logs/jsonrpc.log',
logFormat: 'jsonrpc' // 原始 JSON-RPC 消息
});
每行是一个完整的 JSON-RPC 消息:
请求:
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
响应:
{"jsonrpc":"2.0","id":1,"result":{"tools":["read_file","write_file"...]}}
工具调用:
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"read_file","arguments":{"path":"/tmp/file.txt"}}}
错误:
{"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":"文件未找到","data":{"context":"readFile"}}}
JSON-RPC 格式特点:
记录所有 I/O 操作,方便调试和问题排查:
const wrapper = new MCPWrapper({
serverCommand: 'your-mcp-server',
logFilePath: './logs/debug.log',
logToolCalls: true,
logToolResults: true
});
跟踪哪些工具被调用、频率和参数:
const wrapper = new MCPWrapper({
serverCommand: 'your-mcp-server',
logFilePath: './logs/monitoring.log'
});
// 日志会记录所有工具调用
await wrapper.callTool('some_tool', params);
在多个 MCP 服务器之间路由请求,或添加额外功能层。
保留所有 MCP 交互的完整审计日志。
npm run build
npm run dev examples/library/basic-usage.ts
npm run build
npm run dev examples/server/server-wrapper.ts
# 安装依赖
npm install
# 构建
npm run build
# 监视模式(自动重新编译)
npm run watch
# 运行开发模式
npm run dev examples/basic-usage.ts
logAppend: false 时,每次启动都会覆盖日志文件disconnect() 以正确关闭连接和日志文件MIT
欢迎提交 Issue 和 Pull Request!