x402 mcp验证器
端到端验证MCP服务器:通过StreamableHTTP或SSE连接,发现功能,探测每个工具的x402支付要求,根据x402规范验证支付选项,测量延迟,并返回一个包含12个布尔类别和13个输入字段的结构化快照。
快速启动
git clone https://github.com/agentprobe/x402-mcp-validator.git
cd x402-mcp-validator
npm iimport { McpServerValidator } from 'x402-mcp-validator'
const { status, messages, categories, entries } = await McpServerValidator.start( {
endpoint: 'https://your-mcp-server.example.com/mcp',
timeout: 15000
} )特性
- 使用SSE回退通过StreamableHTTP连接到MCP服务器
- 发现工具、资源、提示和功能
- 探测每个工具的x402支付要求(HTTP 402/JSON-RPC-32402)
- 验证付款选项:方案、网络、金额、资产、付款对象、支票金额
- 对12个布尔类别进行分类(可达、MCP、x402、EVM、Solana、任务、mcpApps)
- 测量ping和listTools延迟
- 比较两个快照并生成结构化差异
- 连接失败时返回包含所有错误类别的空快照
建筑
验证管道按六个顺序步骤处理MCP服务器:
flowchart LR
A[endpoint] --> B[McpConnector.connect]
B --> C[McpConnector.discover]
C --> D[CapabilityClassifier.classify]
D --> E[X402Prober.probe]
E --> F[PaymentValidator.validate]
F --> G[SnapshotBuilder.build]目录
- .start() - .compare()
方法
所有方法都是静态的。参数作为对象传递,返回值是对象。
.start()
连接到MCP服务器,发现功能,探测x402支付支持,验证支付要求,测量延迟,并返回结构化快照。
方法
.start( { endpoint, timeout } )| 密钥 | 类型 | 描述 | 必填 |
|---|---|---|---|
| endpoint | string | MCP服务器的URL。示例 'https://server.example.com/mcp' | 是的 |
| timeout | number | 连接超时(毫秒)。默认 10000 | 没有 |
示例
import { McpServerValidator } from 'x402-mcp-validator'
const { status, messages, categories, entries } = await McpServerValidator.start( {
endpoint: 'https://your-mcp-server.example.com/mcp',
timeout: 15000
} )
console.log( `Status: ${status ? 'PASS' : 'FAIL'}` )
console.log( `Tools: ${entries['tools'].length}` )
console.log( `x402: ${categories['supportsX402']}` )
console.log( `Networks: ${JSON.stringify( entries['x402']['networks'] )}` )退货
{ status, messages, categories, entries }______________________________________________________________________
.compare()
比较由生成的两个快照 .start() 并返回一个结构化的diff,每个部分包含添加、删除和修改的项目。
方法
.compare( { before, after } )| 密钥 | 类型 | 描述 | 必填 |
|---|---|---|---|
| before | object | 以前的快照 .start() 电话。必须包含 categories 和 entries | 是的 |
| after | 对象 | 以后的快照 .start() 电话。必须包含 categories 和 entries | 是的 |
示例
import { McpServerValidator } from 'x402-mcp-validator'
const before = await McpServerValidator.start( { endpoint: 'https://server.example.com/mcp' } )
const after = await McpServerValidator.start( { endpoint: 'https://server.example.com/mcp' } )
const { status, messages, hasChanges, diff } = McpServerValidator.compare( { before, after } )
console.log( `Changes detected: ${hasChanges}` )
console.log( `Tools added: ${diff['tools']['added'].length}` )
console.log( `Tools removed: ${diff['tools']['removed'].length}` )退货
{ status, messages, hasChanges, diff }| 密钥 | 类型 | 描述 |
|---|---|---|
| 状态 | 布尔值 | true 比较完成时 |
| messages | 字符串数组 | 完整性警告(URL不匹配、时间戳问题) |
| hasChanges | 布尔值 | true 当任何差异部分发生变化时 |
| diff | object | 带节的结构化diff: server, capabilities, tools, x402, latency, categories |
分类
返回了12个布尔标志 categories:
| 密钥 | 描述 |
|---|---|
| isReachable | 服务器已响应HEAD请求 |
| supportsMcp | MCP握手已完成 |
| hasTools | 服务器至少公开一个工具 |
| hasResources | 服务器至少公开一个资源 |
| hasPrompts | 服务器至少公开一个提示 |
| supportsX402 | 至少有一个工具返回了402支付错误 |
| hasValidPayment要求 | 至少有一个付款选项通过了验证 |
| supportsExactScheme | 具有付款选项 scheme: 'exact' |
| supportsEvm | 具有付款选项 network: 'eip155:*' |
| supportsSolana | 有付款选项 network: 'solana:*' |
| supportsTasks | 服务器通告任务功能 |
| 支持mcpApps | 服务器通告mcpApps功能 |
条目
中返回了13个数据字段 entries:
| 密钥 | 类型 | 描述 |
|---|---|---|
| endpoint | string | 已验证的MCP服务器端点URL |
| serverName | string | 来自MCP握手的服务器名称 |
| 服务器版本 | 字符串 | 服务器版本 |
| 服务器描述 | 字符串 | 服务器描述 |
| protocolVersion | string | MCP协议版本 |
| 功能 | 对象 | 原始服务器功能 |
| 指令 | 字符串 | 服务器指令 |
| tools | array | 发现的具有名称、描述、inputSchema的工具 |
| 资源 | 数组 | 已发现的资源 |
| 提示 | 数组 | 发现的提示 |
| x402 | 对象 | 付款数据: version, restrictedCalls, paymentOptions, networks, schemes, perTool |
| 延迟 | 对象 | ping 和 listTools 以毫秒为单位 |
| timestamp | string | ISO 8601验证时间戳 |
验证码
VAL——输入验证
| 代码 | 严重性 | 描述 |
|---|---|---|
| VAL-001 | 错误 | 端点:缺少值 |
| VAL-002 | 错误 | 端点:必须是字符串 |
| VAL-003 | 错误 | 端点:不能为空 |
| VAL-004 | 错误 | 端点:必须是有效的URL |
| VAL-005 | 错误 | 超时:必须是数字 |
| VAL-006 | 错误 | 超时:必须大于0 |
| VAL-010 | 错误 | 之前:缺少值 |
| VAL-011 | 错误 | 之前:必须是对象 |
| VAL-012 | 错误 | 之前:缺少类别或条目 |
| VAL-013 | 错误 | 之后:缺少值 |
| VAL-014 | 错误 | 之后:必须是对象 |
| VAL-015 | 错误 | 之后:缺少类别或条目 |
CON-MCP连接
| 代码 | 严重性 | 描述 |
|---|---|---|
| CON-001 | 错误 | 端点:无法访问服务器 |
| CON-004 | 错误 | mcp:初始化握手失败 |
| CON-008 | 警告 | 工具/列表:请求失败 |
| CON-009 | 警告 | 工具/列表:响应格式无效 |
| CON-010 | 信息 | 资源/列表:请求失败 |
| CON-011 | 信息 | 提示/列表:请求失败 |
PAY——付款验证
| 代码 | 严重性 | 描述 |
|---|---|---|
| PAY-001 | 错误 | 受限呼叫:付款缺少所需数据 |
| PAY-002 | 错误 | 受限调用:PaymentRequired不是对象 |
| PAY-010 | 错误 | x402版本:缺少必填字段 |
| PAY-011 | 错误 | x402版本:必须是数字 |
| PAY-012 | 错误 | x402版本:应为2 |
| PAY-020 | 错误 | 资源:必须是字符串或对象 |
| PAY-021 | 错误 | 资源:不能为空/resource.url:缺少值 |
| PAY-022 | 错误 | resource.url:必须是字符串 |
| PAY-023 | 错误 | resource.url:url格式无效 |
| PAY-024 | 错误 | 资源:未知字段 |
| PAY-030 | 错误 | 接受:缺少必填字段 |
| PAY-031 | 错误 | 接受:必须是数组 |
| PAY-032 | 错误 | 接受:为空数组 |
| PAY-040 | 错误 | 方案:缺少值 |
| PAY-041 | 错误 | 方案:必须是字符串 |
| PAY-042 | 错误 | 方案:无效值 |
| PAY-050 | 错误 | 网络:缺少值 |
| PAY-051 | 错误 | 网络:必须是字符串 |
| PAY-052 | 错误 | 网络:未知前缀 |
| PAY-053 | 错误 | 网络:前缀后缺少链ID |
| PAY-060 | 错误 | 所需最大金额:缺少值 |
| PAY-061 | 错误 | maxAmount必填项:必须是字符串 |
| PAY-062 | 错误 | maxAmount必填项:必须是数字字符串 |
| PAY-063 | 错误 | 所需最大金额:必须为正 |
| PAY-070 | 错误 | 资产:缺少值 |
| PAY-071 | 错误 | 资产:必须是字符串 |
| PAY-072 | 错误 | 资产:EVM地址格式无效 |
| PAY-080 | 错误 | payTo:缺少值 |
| PAY-081 | 错误 | payTo:必须是字符串 |
| PAY-082 | 错误 | payTo:EVM地址格式无效 |
| PAY-083 | 警告 | 付款对象:未进行校验和 |
| PAY-090 | 错误 | 最大超时秒数:缺少值 |
| PAY-091 | 错误 | 最大超时秒数:必须是数字 |
| PAY-092 | 错误 | 最大超时秒数:必须大于0 |
| PAY-100 | 信息 | 额外:必须是一个对象 |
| PAY-101 | 信息 | 外部名称:缺失(建议用于EVM) |
| PAY-102 | 信息 | 外部版本:缺失(建议用于EIP-3009) |
PRB--探头
| 代码 | 严重性 | 描述 |
|---|---|---|
| PRB-004 | 信息 | 探测:意外异常 |
| PRB-005 | 信息 | 探测:没有可用于探测的工具 |
OAuth--OAuth
| 代码 | 严重性 | 描述 |
|---|---|---|
| AUTH-002 | 信息 | 找不到或不完整的授权服务器元数据 |
| AUTH-003 | 信息 | 不支持PKC S256(MCP规范必须) |
| AUTH-004 | 信息 | 受保护资源元数据中缺少授权服务器 |
| AUTH-005 | 信息 | 没有可用的客户端注册机制 |
| AUTH-010 | 信息 | 服务器需要身份验证 |
| AUTH-011 | 信息 | 找到范围 |
CMP——比较
| 代码 | 严重性 | 描述 |
|---|---|---|
| CMP-001 | 警告 | 快照来自不同的服务器 |
| CMP-002 | 警告 | 快照之前没有时间戳 |
| CMP-003 | 警告 | 快照后比以前旧 |
许可证
麻省理工学院
