mcp健康检查
MCP(模型上下文协议)服务器的程序化健康和活性探针。
](https://www.npmjs.com/package/mcp-healthcheck) ](https://www.npmjs.com/package/mcp-healthcheck)  ](https://nodejs.org)
______________________________________________________________________
描述
mcp-healthcheck 通过任何支持的传输(stdio、Streamable HTTP或传统SSE)连接到MCP服务器,执行协议握手,枚举服务器的功能(工具、资源、提示),测量每个操作的延迟,并返回结构化的健康报告。它被设计为在自动化环境中无头运行——Kubernetes活性/就绪性探针、CI管道门、监控仪表板——在这些环境中,交互式调试工具是不可行的。
该包提供了用于编程的TypeScript/JavaScriptneneneba API,以及用于终端和shell脚本的CLI。API返回结构化 HealthReport 具有每次检查状态、延迟和错误详细信息的对象。CLI打印人类可读或JSON输出,并使用常规代码退出(0表示健康,1表示不健康,2表示配置错误,3表示降级)。
唯一的运行时依赖关系是 @modelcontextprotocol/sdk.
______________________________________________________________________
安装
npm install mcp-healthcheck @modelcontextprotocol/sdk@modelcontextprotocol/sdk 是对等依赖,必须与此软件包一起安装。
仅用于CLI而不在本地安装:
npx mcp-healthcheck --stdio 'node ./server.js'______________________________________________________________________
快速开始
程序化(TypeScript)
import { checkHealth } from 'mcp-healthcheck';
const report = await checkHealth({
transport: {
type: 'stdio',
command: 'node',
args: ['./my-mcp-server.js'],
},
timeout: 10_000,
});
console.log(report.status); // 'healthy' | 'unhealthy' | 'degraded'
console.log(report.totalMs); // 342
console.log(report.checks); // individual check results命令行界面
# stdio transport
mcp-healthcheck --stdio 'node ./server.js'
# Streamable HTTP transport
mcp-healthcheck --url https://mcp.example.com/mcp --header 'Authorization:Bearer sk-...'
# Legacy SSE transport
mcp-healthcheck --sse http://localhost:3000/sse
# JSON output for scripting
mcp-healthcheck --stdio 'node ./server.js' --format json
# Quiet mode (exit code only)
mcp-healthcheck --url http://localhost:3000/mcp --quiet______________________________________________________________________
特性
- 三种运输方式 --stdio(子进程)、流式HTTP和传统SSE。
- 完整的MCP生命周期验证 --传输连接、协议握手和功能枚举(工具、资源、提示)。
- 每次检查延迟测量 --每次检查都使用高分辨率计时
performance.now(). - 可配置阈值 --最小/最大工具计数、最小资源/提示计数和每次检查的最大延迟。
- 自定义检查 --用户定义的异步函数,用于接收连接的MCP
Client例如,针对特定领域的断言。 - 超时执行 --每次检查超时和总超时,并自动清理剩余的检查。
- 中止信号支持 --通过标准进行外部取消
AbortSignal界面。 - 自动跳过 --对于服务器未声明的功能的检查将自动跳过,并传递结果。
- 结构化健康报告 --机器可读
HealthReport具有状态、每次检查结果、摘要计数和服务器信息的对象。 - HTTP处理程序工厂 --在Express、Koa、Fastify或raw中挂载健康端点
http.createServer只需一次函数调用。 - 具有确定性退出代码的CLI --0(健康),1(不健康),2(配置错误),3(降级)。
- 环境变量配置 --所有CLI标志都具有容器和CI环境的环境变量等效值。
- 子流程清理 --stdio传输总是终止(SIGTERM,然后是5秒后的SIGKILL),以防止僵尸进程。
- 从不投掷 --
checkHealth()总是返回aHealthReport,捕获报告结构中的所有错误。
______________________________________________________________________
API 参考
checkHealth(options: HealthCheckOptions): Promise
主要API。连接到MCP服务器,运行所有健康检查,并返回结构化报告。此函数从不抛出;所有错误都记录在返回的报告中。
import { checkHealth } from 'mcp-healthcheck';
const report = await checkHealth({
transport: {
type: 'stdio',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
},
});
if (report.status === 'healthy') {
console.log(`${report.summary.passed}/${report.summary.total} checks passed in ${report.totalMs}ms.`);
} else {
for (const check of report.checks.filter(c => !c.passed)) {
console.error(`FAIL: ${check.name} -- ${check.error?.message}`);
}
}isHealthy(options: HealthCheckOptions): Promise
运行的便利功能 checkHealth 并返回 true 仅当状态为 'healthy'.退货 false 对两者 'unhealthy' 和 'degraded'.
import { isHealthy } from 'mcp-healthcheck';
const healthy = await isHealthy({
transport: { type: 'stdio', command: 'node', args: ['./server.js'] },
});
if (!healthy) {
process.exit(1);
}createHttpHandler(options: HealthCheckOptions): (req: IncomingMessage, res: ServerResponse) => void
创建一个公开健康检查端点的HTTP请求处理程序。适用于安装在任何Node.js HTTP框架或原始 http.createServer.
- 获取 请求:运行
checkHealth(options)并作出回应200 OK(健康或退化)或503 Service Unavailable(不健康),与Content-Type: application/json和那个HealthReport作为响应体。 - 任何其他方法:回复如下
405 Method Not Allowed.
import http from 'node:http';
import { createHttpHandler } from 'mcp-healthcheck';
const handler = createHttpHandler({
transport: { type: 'stdio', command: 'node', args: ['./server.js'] },
timeout: 10_000,
});
const server = http.createServer(handler);
server.listen(8080);类型
HealthCheckOptions
传递给的主配置对象 checkHealth, isHealthy,以及 createHttpHandler.
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
transport | TransportConfig | *必需的* | 用于连接到MCP服务器的传输配置。 |
timeout | number | 30000 | 整个健康检查的总超时时间(毫秒)。 |
checkTimeout | number | 10000 | 每次检查超时(毫秒)。 |
skip | Array | [] | 选中以跳过。 connect 和 initialize 不能跳过。 |
thresholds | Thresholds | {} | 通过/失败评估的阈值断言。 |
customChecks | Array | [] | 在标准检查后运行的自定义检查功能。 |
clientInfo | { name: string; version: string } | `{ name: 'mcp-healthcheck', version: ' | |
| ' }` | MCP中发送的客户端信息 initialize 请求。 | ||
signal | AbortSignal | undefined | AbortSignal用于外部取消。 |
TransportConfig
三种运输配置的区别性结合:
StdioTransportConfig
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
type | 'stdio' | -- | 运输鉴别器。 |
command | string | *必需的* | 要执行的命令(例如。, 'node', 'python', 'npx'). |
args | string[] | [] | 要传递给命令的参数。 |
env | Record | process.env | 子流程的环境变量。已合并 process.env. |
cwd | string | process.cwd() | 子流程的工作目录。 |
HttpTransportConfig
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
type | 'http' | -- | 运输鉴别器。 |
url | string | *必需的* | MCP服务器的流式HTTP端点的URL。 |
headers | Record | undefined | 其他HTTP标头(例如授权)。 |
SseTransportConfig
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
type | 'sse' | -- | 运输鉴别器。 |
url | string | *必需的* | SSE端点的URL。 |
headers | Record | undefined | 其他HTTP标头。 |
Thresholds
| 属性 | 类型 | 描述 |
|---|---|---|
maxLatencyMs | number | 任何单个检查的最大允许延迟(ms)。超过此值将整体状态设置为 'degraded'. |
minTools | number | 服务器必须公开的最小工具数。 |
maxTools | number | 服务器可以公开的最大工具数。 |
minResources | number | 服务器必须公开的最小资源数。 |
minPrompts | number | 服务器必须公开的最小提示数。 |
CustomCheckFn
type CustomCheckFn = (client: Client) => Promise;用户定义的异步函数,用于接收连接的MCP Client 实例并返回a CustomCheckResult.
CustomCheckResult
| 属性 | 类型 | 描述 |
|---|---|---|
passed | boolean | 检查是否通过。 |
message | string | 结果的人类可读描述。 |
details | Record | 可选的任意元数据要包含在报告中。 |
HealthReport
返回的完整健康报告 checkHealth.
| 属性 | 类型 | 描述 |
|---|---|---|
status | HealthStatus | 总体健康状况: 'healthy', 'unhealthy',或 'degraded'. |
totalMs | number | 整个健康检查的挂钟总时间(毫秒)。 |
timestamp | string | 执行健康检查的ISO 8601时间戳。 |
checks | CheckResult[] | 按执行顺序显示每个单独检查的结果。 |
summary | { total: number; passed: number; failed: number; skipped: number } | 摘要很重要。 |
server | { name: string; version: string; protocolVersion: string } | 服务器信息,成功后填充 initialize 检查。 |
HealthStatus
type HealthStatus = 'healthy' | 'unhealthy' | 'degraded';healthy--所有必需的检查均已通过,所有阈值均已满足。unhealthy--一个或多个必需的检查失败。degraded--所有必需的检查都通过了,但可选检查或延迟阈值失败。
CheckResult
| 属性 | 类型 | 描述 |
|---|---|---|
name | string | 检查名称(例如。, 'connect', 'initialize', 'tools'). |
passed | boolean | 检查是否通过。 |
durationMs | number | 此检查所用的时间(毫秒)。 |
message | string | 人类可读的结果描述。 |
error | { code: string; message: string; stack?: string } | 检查失败时的错误详细信息。对成功没有定义。 |
details | Record | 查看具体细节(见下文)。 |
专业检查结果详情:
| 检查 | 详细信息形状 | ||
|---|---|---|---|
connect | `{ transportType: 'stdio' \ | 'http' \ | 'sse' }` |
initialize | { protocolVersion: string; serverName: string; serverVersion: string; capabilities: { tools?: boolean; resources?: boolean; prompts?: boolean; logging?: boolean } } | ||
tools | { toolCount: number; toolNames: string[] } | ||
resources | { resourceCount: number; resourceUris: string[] } | ||
prompts | { promptCount: number; promptNames: string[] } |
______________________________________________________________________
配置
默认值
| 选项 | 默认值 | 描述 |
|---|---|---|
timeout | 30000 | 整个健康检查的总超时时间(毫秒)。 |
checkTimeout | 10000 | 每次检查超时(ms)。 |
skip | [] | 没有跳过检查。 |
thresholds | {} | 没有阈值断言。 |
customChecks | [] | 没有自定义检查。 |
clientInfo.name | 'mcp-healthcheck' | 客户端名称已发送至 initialize 请求。 |
clientInfo.version | 包版本 | 发送的客户端版本 initialize 请求。 |
检查顺序
检查按此固定顺序运行。每次检查都取决于之前要求的检查是否成功。
| 订单 | 检查 | 可以跳过吗? | 取决于 | 验证 |
|---|---|---|---|---|
| 1 | connect | 否 | -- | 传输级连接 |
| 2 | initialize | 没有 | connect | MCP协议握手 |
| 3 | tools | 是的 | initialize | tools/list 成功,达到阈值 |
| 4 | resources | 是的 | initialize | resources/list 成功,达到阈值 |
| 5 | prompts | 是的 | initialize | prompts/list 成功,达到阈值 |
| 6+ | 自定义 | 不适用 | initialize | 用户定义逻辑 |
如果 connect 或 initialize 如果失败,则跳过所有后续检查。
如果服务器没有声明能力(例如。, resources),相应的检查将自动跳过 passed: true.
超时策略
超时在两个层面上执行:
- 每次检查超时 (
checkTimeout):每张支票都包裹在Promise.race有一个超时。如果检查超出此范围,则失败并返回错误代码CHECK_TIMEOUT. - 总体超时 (
timeout):主计时器为整个时间运行checkHealth()电话。如果它在所有检查完成之前触发,则跳过剩余的检查并返回错误代码OVERALL_TIMEOUT.
两个超时级别都使用 AbortController 在内部与提供的任何来电者进行沟通 signal.
______________________________________________________________________
错误处理
checkHealth() 从不投掷。所有错误都在返回的 HealthReport未通过的检查包括 error 带有分类代码、消息和可选堆栈跟踪的对象。
错误代码
| 代码 | 来源 | 含义 |
|---|---|---|
TRANSPORT_ERROR | 传输层 | 无法建立传输连接(ECONNREFUSED、DNS故障、TLS错误、子进程崩溃)。 |
SPAWN_ERROR | stdio传输 | 生成子进程失败(ENOENT 未找到命令, EACCES 拒绝许可)。 |
HANDSHAKE_ERROR | MCP协议 | initialize 握手失败(JSON-RPC错误、版本不匹配、响应格式错误)。 |
PROTOCOL_ERROR | MCP协议 | A tools/list, resources/list,或 prompts/list 请求返回JSON-RPC错误。 |
CHECK_TIMEOUT | 超时系统 | 超过单个检查 checkTimeout. |
OVERALL_TIMEOUT | 超时系统 | 超过整个健康检查 timeout;跳过了其余的检查。 |
ABORTED | 外部信号 | 呼叫者的 AbortSignal 被触发。 |
THRESHOLD_VIOLATION | 阈值评估 | 阈值断言失败(例如,工具计数低于 minTools). |
CUSTOM_CHECK_ERROR | 自定义检查 | 自定义检查函数抛出异常。 |
UNKNOWN_ERROR | 回退 | 与任何已知分类都不匹配的意外错误。 |
依赖失败传播
如果需要检查(connect 或 initialize)如果失败,则跳过所有后续检查,并记录一条指示先前失败的消息。即使早期检查失败,这也提供了一个完整的报告结构。
______________________________________________________________________
高级用法
自定义检查
自定义检查在标准检查后运行,并接收连接的MCP Client 例子每个检查都可以标记为 required (失败使状态 'unhealthy')或可选(失败使状态 'degraded',这是默认设置)。
import { checkHealth } from 'mcp-healthcheck';
const report = await checkHealth({
transport: { type: 'stdio', command: 'node', args: ['./server.js'] },
customChecks: [
{
name: 'has-search-tool',
required: true,
fn: async (client) => {
const { tools } = await client.listTools();
const hasSearch = tools.some(t => t.name === 'search');
return {
passed: hasSearch,
message: hasSearch ? 'search tool is registered' : 'search tool is missing',
};
},
},
],
});引发异常的自定义检查被视为失败,并带有错误代码 CUSTOM_CHECK_ERROR同步抛出和拒绝的promise都会被处理。
中止信号取消
通过A AbortSignal 要从外部取消健康检查:
import { checkHealth } from 'mcp-healthcheck';
const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);
const report = await checkHealth({
transport: { type: 'stdio', command: 'node', args: ['./server.js'] },
signal: controller.signal,
});中止时,健康检查立即停止,并返回一个包含错误代码的不健康报告 ABORTED.
带阈值的HTTP传输
import { checkHealth } from 'mcp-healthcheck';
const report = await checkHealth({
transport: {
type: 'http',
url: 'https://mcp.example.com/mcp',
headers: { 'Authorization': 'Bearer sk-...' },
},
timeout: 15_000,
checkTimeout: 5_000,
thresholds: {
maxLatencyMs: 2_000,
minTools: 3,
},
});HTTP健康端点
在任何Node.js应用程序中将健康检查作为HTTP端点公开:
import http from 'node:http';
import { createHttpHandler } from 'mcp-healthcheck';
const handler = createHttpHandler({
transport: { type: 'stdio', command: 'node', args: ['./server.js'] },
timeout: 10_000,
});
const server = http.createServer(handler);
server.listen(8080);
// GET http://localhost:8080 -> 200 (healthy/degraded) or 503 (unhealthy)Kubernetes生存性和就绪性探测
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
spec:
template:
spec:
containers:
- name: mcp-server
image: my-mcp-server:latest
ports:
- containerPort: 3000
- name: healthcheck
image: node:20-slim
command: ['sleep', 'infinity']
livenessProbe:
exec:
command:
- mcp-healthcheck
- '--url'
- 'http://localhost:3000/mcp'
- '--timeout'
- '5000'
- '--skip'
- 'resources'
- '--skip'
- 'prompts'
- '--quiet'
initialDelaySeconds: 15
periodSeconds: 30
timeoutSeconds: 8
failureThreshold: 3
readinessProbe:
exec:
command:
- mcp-healthcheck
- '--url'
- 'http://localhost:3000/mcp'
- '--timeout'
- '5000'
- '--min-tools'
- '5'
- '--quiet'
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 8
failureThreshold: 1CI管道闸门
- name: Wait for MCP server to be healthy
run: |
for i in $(seq 1 10); do
npx mcp-healthcheck \
--url http://localhost:3000/mcp \
--timeout 5000 \
--min-tools 3 \
--format json \
&& exit 0
echo "Attempt $i failed, retrying in 2s..."
sleep 2
done
echo "MCP server failed to become healthy"
exit 1监控仪表板集成
import { checkHealth } from 'mcp-healthcheck';
const servers = [
{ name: 'search-server', transport: { type: 'http' as const, url: 'https://search.internal/mcp' } },
{ name: 'db-server', transport: { type: 'http' as const, url: 'https://db.internal/mcp' } },
];
const results = await Promise.all(
servers.map(async (s) => ({
name: s.name,
report: await checkHealth({ transport: s.transport, timeout: 10_000 }),
})),
);
for (const { name, report } of results) {
console.log(`${name}: ${report.status} (${report.totalMs}ms)`);
}______________________________________________________________________
CLI参考
mcp-healthcheck [options]
Transport (exactly one required):
--stdio Spawn an MCP server via stdio transport.
--url Connect via Streamable HTTP transport.
--sse Connect via legacy SSE transport.
Transport options:
--header Add an HTTP header (repeatable). For --url and --sse only.
--cwd
Working directory for --stdio subprocess.
--env Environment variable for --stdio subprocess (repeatable).
Check options:
--timeout Overall timeout in milliseconds. Default: 30000.
--check-timeout Per-check timeout in milliseconds. Default: 10000.
--skip Skip a check (repeatable). Values: tools, resources, prompts.
--min-tools Minimum expected tool count.
--max-tools Maximum expected tool count.
--min-resources Minimum expected resource count.
--min-prompts Minimum expected prompt count.
--max-latency Maximum allowed latency per check.
Output options:
--format Output format: human, json. Default: human.
--quiet Suppress all output except the exit code.
--verbose Show detailed check information.
Meta:
--version Print version and exit.
--help Print help and exit.退出代码
| 代码 | 含义 |
|---|---|
0 | 健康。所有检查均已通过,所有阈值均已满足。 |
1 | 不健康。一个或多个必需的检查失败。 |
2 | 配置错误。标志无效、缺少传输或传输配置无效。 |
3 | 降级。所有必需的检查都通过了,但可选阈值或自定义检查失败。 |
环境变量
所有CLI标志都可以通过环境变量设置。显式CLI标志覆盖环境变量。
| 环境变量 | 等效标志 |
|---|---|
MCP_HEALTHCHECK_STDIO | --stdio |
MCP_HEALTHCHECK_URL | --url |
MCP_HEALTHCHECK_SSE | --sse |
MCP_HEALTHCHECK_TIMEOUT | --timeout |
MCP_HEALTHCHECK_CHECK_TIMEOUT | --check-timeout |
MCP_HEALTHCHECK_FORMAT | --format |
MCP_HEALTHCHECK_MIN_TOOLS | --min-tools |
MCP_HEALTHCHECK_MAX_TOOLS | --max-tools |
MCP_HEALTHCHECK_MIN_RESOURCES | --min-resources |
MCP_HEALTHCHECK_MIN_PROMPTS | --min-prompts |
MCP_HEALTHCHECK_MAX_LATENCY | --max-latency |
MCP_HEALTHCHECK_SKIP | --skip (逗号分隔) |
人类可读输出示例
$ mcp-healthcheck --stdio 'node ./server.js' --min-tools 2
mcp-healthcheck v0.2.0
Target: stdio -- node ./server.js
Status: healthy
PASS connect 12ms stdio transport connected
PASS initialize 45ms protocol v2025-06-18, server: my-server v1.0.0
PASS tools 28ms 5 tools: search, create, update, delete, list
PASS resources 15ms 2 resources
PASS prompts 8ms 1 prompt
Summary: 5/5 passed in 108ms______________________________________________________________________
TypeScript
这个包是用TypeScript编写的,并附带了类型声明(dist/index.d.ts).所有公共类型都从主入口点导出:
import {
checkHealth,
isHealthy,
createHttpHandler,
// Types
type HealthCheckOptions,
type HealthReport,
type HealthStatus,
type CheckResult,
type ConnectCheckResult,
type InitializeCheckResult,
type ToolsCheckResult,
type ResourcesCheckResult,
type PromptsCheckResult,
type CustomCheckCheckResult,
type TransportConfig,
type StdioTransportConfig,
type HttpTransportConfig,
type SseTransportConfig,
type Thresholds,
type CustomCheckFn,
type CustomCheckResult,
} from 'mcp-healthcheck';需要TypeScript 5.0或更高版本。该包使用CommonJS模块编译为ES2022。
______________________________________________________________________
许可证
麻省理工学院
