JSON-RPC代理网关

MCP Proxy Gateway 是一个支持JSON-RPC协议、提供请求验证、记录回放功能的代理服务,适用于确定性测试和流量监控场景。

  • by sarveshkapre
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 sarveshkapre/mcp-proxy-gateway

使用说明

MCP代理网关

通过模式验证观察和门控MCP工具调用,并记录/回放确定性测试。

它的作用

  • HTTP JSON-RPC代理(POST /rpc,与 POST /mcp 兼容性别名),转发到上游MCP服务器
  • 验证 tools/call JSON模式参数
  • 记录对NDJSON的请求/响应
  • 在没有上游服务器的情况下回放录制的通话
  • 当客户端请求时,流式传输上游SSE响应(Accept: text/event-stream)
  • 状态检查的健康端点(GET /healthz)
  • 本地运行时计数器的度量端点(GET /metricsz)
  • 可选的Prometheus公开端点(GET /metrics)启用时(标志/策略)
  • 支持JSON-RPC批处理请求(按项目顺序处理)
  • 实现JSON-RPC通知语义(204 No Content 当请求省略时 id)
  • 将重放的响应ID重写为传入请求ID,以确保相关性安全

快速入门

make setup
make build
./bin/mcp-proxy-gateway \
  --listen :8080 \
  --upstream http://localhost:8090/rpc \
  --policy ./policy.example.yaml \
  --record ./records.ndjson

将JSON-RPC请求发送到 http://localhost:8080/rpc (或 http://localhost:8080/mcp). 检查健康状况 http://localhost:8080/healthz. 检查以下指标 http://localhost:8080/metricsz. 启用Prometheus指标 http://localhost:8080/metrics 随着 --prometheus-metrics (或 policy.http.prometheus_metrics: true).

演示(重播)

make build
./bin/mcp-proxy-gateway --listen :8080 --replay ./records.example.ndjson --replay-strict
curl -sS -X POST http://localhost:8080/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"tool":"web.search","arguments":{"query":"hello","max_results":3}}}'

回放模式

./bin/mcp-proxy-gateway \
  --listen :8080 \
  --replay ./records.example.ndjson \
  --replay-strict

重播查找匹配可在策略中配置:

replay:
  match: signature # signature (default), method, or tool

流媒体/SSE直通

如果上游工具响应长时间运行,并且上游服务器支持SSE,则客户端可以通过以下方式请求:

curl -sS -N -X POST http://localhost:8080/rpc \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"tool":"web.search","arguments":{"query":"hello"}}}'

笔记:

  • 仅当客户端请求SSE时,网关才按原样流式传输上游响应字节(Accept: text/event-stream)上游以 Content-Type: text/event-stream.
  • 如果上游返回SSE,但客户端没有请求SSE,则网关返回JSON-RPC上游错误。
  • 流式响应不会被记录(记录/回放仅为JSON)。
  • 流式回复仍受 --max-body (提高它以获得更长的流量)。
  • 流式处理仅支持单个JSON-RPC请求(不支持批处理)。
  • 回放模式从不流式传输;它只提供记录的JSON响应。
  • 对于批处理请求,网关不转发 Accept: text/event-stream 上游;如果上游仍然响应 text/event-stream,网关将其视为该批处理项的上游错误。

政策示例

version: 1
mode: enforce
allow_tools:
  - web.search
  - fs.read

http:
  # Optional CSRF-style hardening for browser-initiated requests: if a request
  # includes an `Origin` header not in this list, it is rejected (403). Requests
  # without an Origin header are allowed.
  origin_allowlist: ["http://localhost:3000"]
  # Optional explicit allowlist of headers to forward upstream. This is
  # intentionally narrow to avoid becoming a generic HTTP proxy.
  # Notes:
  # - `Authorization` is forwarded regardless to support authenticated upstreams.
  # - `Accept` is forwarded only for SSE requests (`Accept: text/event-stream`).
  forward_headers: ["Traceparent", "Tracestate", "Baggage", "X-Request-Id"]
  # Optional Prometheus text exposition endpoint at GET /metrics.
  prometheus_metrics: false

record:
  # Redaction is applied before writing NDJSON recordings.
  redact_keys: ["token", "access_token", "api_key", "authorization"]
  redact_key_regex: ["(?i)secret|password"]
  # Optional recorder lifecycle controls:
  # - max_bytes rotates the active file when the next append would exceed this size.
  # - max_files retains up to N rotated backups as `records.ndjson.1..N`.
  max_bytes: 10485760 # 10 MiB
  max_files: 3

tools:
  web.search:
    schema:
      type: object
      properties:
        query:
          type: string
        max_results:
          type: integer
          minimum: 1
          maximum: 10
      required: [query]
      additionalProperties: false

上游报头转发

  • 网关转发 Authorization 如果存在,则向上游请求发送。
  • 对于其他标头(例如分布式跟踪),请配置 policy.http.forward_headers.
  • 网关故意不转发传输/逐跳报头(例如 Host, Connection, Content-Length).

示例文件

  • policy.example.yaml
  • records.example.ndjson

烟雾测试

make smoke

文档

看 docs/ 有关架构、命令和贡献的详细信息。

许可证

麻省理工学院