MCP监视器
代理AI管道的透明可观察性。
MCP Monitor拦截AI代理发出的每个工具调用——无论代理是否使用 模型上下文协议(MCP) 或者直接调用Python函数,并通过本地web仪表板显示指标、会话回放和警报。
您的代理没有任何更改。MCP服务器无任何更改。
______________________________________________________________________
特性
- ⚡ 实时订阅源 --所有工具调用的实时SSE驱动流,带有状态徽章和延迟
- 📋 会话重放 --浏览会话,使用甘特图查看通话时间线,展开任何通话以检查参数和响应
- 📊 工具分析 --通过Chart.js查看P50/P95/P99延迟图、呼叫量和错误率趋势
- 🖥️ 服务器运行状况 --具有自动刷新功能的每台服务器状态卡(正常/降级/停机)
- 🔔 警报 --可配置的P95延迟和错误率阈值,带有基于冷却的警报
- 🔒 秘密消毒 -自动编辑存储参数中的令牌、密码和API密钥
- 🐍 开发包 --零依赖pip包,用于监控任何Python代理(QwenAgent、LangChain、自定义)
- 💾 SQLite存储 --具有WAL模式的单文件数据库,可实现快速并发读取
______________________________________________________________________
建筑
Agent (Claude, Cursor, etc.)
│
├── Multiplexer mode
│ mcp-monitor serve
│ ├── spawns Server A ──┐
│ ├── spawns Server B ──┤── POST /api/ingest ──► Dashboard Server ──► SQLite
│ └── spawns Server C ──┘ │
│ EventBus.emit()
├── Per-server proxy mode │
│ mcp-monitor proxy SSE push to
│ └── spawns Server ──────► Dashboard UI
│
└── Python SDK ──► POST /api/ingest多路转换方式 是一种方法:在MCP配置中添加一个条目并监视所有服务器。这 serve 命令生成每个配置的服务器,合并它们的工具,路由调用,并记录所有内容。
每服务器代理模式 封装单个服务器——当您希望对监视的服务器进行细粒度控制时非常有用。
______________________________________________________________________
快速开始
先决条件
- Node.js 18+
- npm
通过GitHub软件包安装
- 对GitHub包进行身份验证:您需要一个个人访问令牌(经典)
read:packages范围。 - 告诉npm在哪里可以找到包:
echo "@partha-sust16:registry=https://npm.pkg.github.com" >> ~/.npmrc- 全局安装软件包:
npm install -g @partha-sust16/mcp-monitor您现在已准备好跑步 mcp-monitor start!
从源代码安装
git clone https://github.com/Partha-SUST16/mcp_monitor.git
cd mcp_monitor
# Install backend dependencies
npm install
# Build the backend and the dashboard UI automatically
npm run build
# Link globally to use the 'mcp-monitor' command anywhere
npm link
# Start the dashboard server
mcp-monitor start仪表板将在 http://localhost:4242.
发送测试事件
curl -X POST http://localhost:4242/api/ingest \
-H 'Content-Type: application/json' \
-d '{
"sessionId": "test-session",
"agentType": "python-sdk",
"serverName": "my-server",
"toolName": "read_file",
"method": "read_file",
"arguments": {"path": "/tmp/test.txt"},
"response": null,
"status": "success",
"latencyMs": 150,
"timestamp": "2026-03-09T10:00:00Z"
}'______________________________________________________________________
连接代理
多路转换方式
监视器 全部 具有单个配置项的MCP服务器。无需单独包装每台服务器。
步骤1。 在中列出您的服务器 mcp-monitor.config.json:
{
"servers": [
{ "name": "filesystem", "transport": "stdio", "command": "npx @modelcontextprotocol/server-filesystem /tmp" },
{ "name": "github", "transport": "stdio", "command": "npx @modelcontextprotocol/server-github", "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" } }
],
"dashboard": { "port": 4242 }
}步骤2。 将代理配置中的所有MCP服务器条目替换为一个:
{
"mcpServers": {
"mcp-monitor": {
"command": "mcp-monitor",
"args": ["serve", "-c", "/absolute/path/to/mcp-monitor.config.json"]
}
}
}步骤3。 单独启动仪表板服务器:
mcp-monitor start代理看到一个包含所有工具的MCP服务器。MCP Monitor在内部生成每个真实服务器,路由每个 tools/call 并记录通话。
关于工具名称的说明:为了防止不同MCP服务器之间发生命名冲突,这些服务器恰好暴露了相同的工具,多路复用器会在所有工具名称前加上其原始服务器的名称。例如,如果你filesystem服务器有一个名为的工具read_file,LLM将看到它暴露为filesystem_read_file.
每服务器代理模式
或者,通过替换命令来包装单个服务器:
{
"mcpServers": {
"filesystem": {
"command": "mcp-monitor",
"args": ["proxy", "--name", "filesystem",
"--cmd", "npx @modelcontextprotocol/server-filesystem /tmp"]
}
}
}Python代理(QwenAgent)
from agent_monitor import patch_qwen_agent
patch_qwen_agent(server_name="my-agent") # call once before creating agent
# rest of agent code unchanged通用Python工具
from agent_monitor import monitor
@monitor(server_name="my-tools")
def query_database(sql: str) -> dict:
...Python SDK安装
cd sdk/python
pip install -e .SDK具有 零外部依赖 --它只使用Python stdlib(urllib, threading, json).
______________________________________________________________________
配置
创建 mcp-monitor.config.json 在项目根目录中:
{
"servers": [
{
"name": "filesystem",
"transport": "stdio",
"command": "npx @modelcontextprotocol/server-filesystem /tmp"
},
{
"name": "github",
"transport": "stdio",
"command": "npx @modelcontextprotocol/server-github",
"env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" }
},
{
"name": "remote-tools",
"transport": "http",
"targetUrl": "https://my-mcp-server.com",
"listenPort": 4243
}
],
"dashboard": {
"port": 4242
},
"alerts": {
"latencyP95Ms": 2000,
"errorRatePercent": 10,
"cooldownMinutes": 5
}
}中支持环境变量替换 env 字段-- $VAR_NAME 被替换为 process.env.VAR_NAME.
______________________________________________________________________
CLI命令
# Start dashboard server + alert engine
mcp-monitor start [-c path/to/config.json]
# Run as a multiplexing MCP server (add as single entry in agent config)
mcp-monitor serve [-c path/to/config.json] [--dashboard-url http://localhost:4242]
# Start a single MCP proxy (wrap one server)
mcp-monitor proxy --name filesystem --cmd "npx @modelcontextprotocol/server-filesystem /tmp"
# List recent sessions
mcp-monitor sessions [--limit 20]
# Replay a session's tool calls
mcp-monitor replay
# Show per-tool stats
mcp-monitor stats [--sort latency_p95|error_rate|call_count] [--since 1h|6h|24h|7d]
# Export data
mcp-monitor export [--format json|csv] [--since 24h] [--output file.json]______________________________________________________________________
REST API
| 端点 | 描述 |
|---|---|
GET /api/overview | 汇总统计数据:总呼叫数、错误率、平均延迟/p95、最近呼叫数 |
GET /api/sessions | 带有呼叫计数的分页会话列表(?limit=20&offset=0) |
GET /api/sessions/:id/calls | 按时间顺序调用会话的所有工具 |
GET /api/tools/stats | 每个工具的延迟百分比和错误率(?since=24h) |
GET /api/servers | 根据最后5分钟的数据得出的服务器运行状况 |
GET /api/alerts | 已触发警报历史记录(?limit=50&offset=0) |
GET /api/stream | SSE端点--推送 tool_call 和 alert 实时事件 |
POST /api/ingest | 接受 CollectorEvent JSON(Python SDK使用) |
______________________________________________________________________
项目结构
mcp-monitor/
├── src/
│ ├── types.ts # All shared TypeScript interfaces
│ ├── config.ts # Config loader with env var substitution
│ ├── cli.ts # Commander.js entry point
│ ├── core/
│ │ ├── Store.ts # SQLite (better-sqlite3) CRUD
│ │ ├── Collector.ts # Sanitize → truncate → persist → emit
│ │ ├── RemoteCollector.ts # HTTP POST to dashboard /api/ingest
│ │ ├── SessionManager.ts # Session lifecycle + idle timeout
│ │ ├── EventBus.ts # Node.js EventEmitter singleton
│ │ └── AlertEngine.ts # P95 latency & error rate monitoring
│ ├── ingestion/
│ │ ├── mcp/
│ │ │ ├── MuxServer.ts # Multiplexing MCP server (aggregates all servers)
│ │ │ ├── ProtocolInterceptor.ts # JSON-RPC request/response matching
│ │ │ ├── StdioProxy.ts # MCP stdio transport proxy
│ │ │ └── HttpProxy.ts # MCP HTTP reverse proxy
│ │ └── IngestEndpoint.ts # POST /api/ingest handler
│ └── dashboard/
│ ├── server.ts # Express + SSE + static serving
│ ├── routes/ # API route handlers
│ └── ui/ # React + Vite dashboard
│ └── src/pages/
│ ├── LiveFeed.tsx
│ ├── SessionReplay.tsx
│ ├── ToolAnalytics.tsx
│ ├── ServerHealth.tsx
│ └── Alerts.tsx
├── sdk/python/
│ ├── pyproject.toml
│ └── agent_monitor/
│ ├── __init__.py
│ ├── collector.py # Fire-and-forget POST to /api/ingest
│ └── decorators.py # patch_qwen_agent() + @monitor
├── mcp-monitor.config.json
├── package.json
└── tsconfig.json______________________________________________________________________
技术栈
| 层 | 技术 |
|---|---|
| MCP代理 | TypeScript(子进程,JSON-RPC解析) |
| 核心 | TypeScript+Express 5 |
| 数据库 | SQLite通过 better-sqlite3 (WAL模式) |
| 仪表板UI | React 19+Vite+Chart.js |
| 实时推送 | 服务器发送事件(SSE) |
| Python SDK | Python 3.9+(仅限stdlib) |
| CLI | Commander.js |
______________________________________________________________________
会话管理
会话是自动创建和管理的:
- MCP连接: 每一天都有一个新的会议开始
initializeJSON-RPC消息 - 空闲超时: 如果两次工具调用之间相隔5分钟以上,则会创建一个新会话
- 显式会话ID: 集
MCP_MONITOR_SESSION_IDenv-var用于确定性会话分组 - Python SDK: 每个Python进程都会获得一个唯一的UUID会话或设置
AGENT_MONITOR_SESSION_ID - 会话结束: 标记代理进程退出或连接关闭的时间
______________________________________________________________________
警报系统
AlertEngine完全由事件驱动-- 无投票它倾听每一个 tool_call 事件总线中的事件,并实时评估阈值:
- P95延迟 每个工具→ 火灾,如果以上
latencyP95Ms阈值 - 错误率 每个工具→ 火灾,如果以上
errorRatePercent阈值(需要≥5个电话)
冷却逻辑可防止同一警报在内部重新触发 cooldownMinutes (默认值:5分钟)。警报被持久化到SQLite,并通过SSE推送到仪表板。
______________________________________________________________________
许可证
麻省理工学院
