mcpField
N
npm-package-ws-has-241560546-weekly-downloads-but-sdk

npm-package-ws-has-241560546-weekly-downloads-but-sdk

远程服务
github.com/nexus-mcp-infra开发工具08 周前更新
代码仓库

关于 npm-package-ws-has-241560546-weekly-downloads-but-sdk

ws-mcp 为需要与实时 WebSocket 端点交换帧的 Agent 提供有状态会话服务,并将会话操作作为 MCP 工具开放。它为每帧标注 Shannon 熵变化,帮助识别消息模式变化。

主要功能

  1. 01打开和关闭持久 WebSocket 会话
  2. 02发送文本和二进制帧
  3. 03读取已缓冲的入站帧
  4. 04跟踪每帧 Shannon 熵变化
  5. 05查看会话与模式遥测

适用场景

  1. 01向实时 WebSocket 端点发送命令
  2. 02轮询 WebSocket 流中缓冲的事件
  3. 03发现会话中的消息模式变化

MCP 相关

MCP 兼容客户端可连接其 streamable HTTP 端点。它提供打开会话、发送帧、读取缓冲区、查看遥测和关闭会话等五种工具;打开会话需要 x402 付款。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://npm-package-ws-has-241560546-w-production.up.railway.app/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

5
参数类型必填说明
target_urlstring是要连接的完整 WebSocket URL(必须以 ws:// 或 wss:// 开头)。
connect_timeout_secondsnumber否等待 WebSocket 握手完成的最长秒数。

详细介绍

ws-mcp

将 WebSocket 会话管理作为 MCP 工具——并跟踪每帧的 Shannon 熵。

ws 每周下载量达 241,560,546 次。目前没有 MCP 服务提供 WebSocket 基元。这就是这样的服务。


问题

AI Agent 无法与实时 WebSocket 数据流交互,除非为每种集成都编写自定义粘合代码。目前没有标准化方式让大模型打开持久连接、发送带类型的帧,并将结构化事件作为工具调用响应接收。调试消息流需要使用外部工具(Wireshark、浏览器开发者工具),而这些工具与 Agent 工作流不兼容。

ws-mcp 通过 HTTP 提供五种原子操作:打开会话、发送帧、排空缓冲帧、检查遥测数据以及关闭会话。每一帧——无论入站还是出站——都会根据会话累积的消息分布计算 Shannon 熵增量,因此 Agent 无需任何外部监控,就能检测数据流是否偏离预期的架构。


为什么熵增量不可或缺

服务会在持有套接字连接的同一进程中,为每个 session_id 维护实时令牌频率 Counter。对于每一帧,它会计算:

delta = H(t) - H(t-1)

其中,H(t) 是第 t 帧之后累积字节分布的 Shannon 熵。增量接近零表示该帧在统计特征上符合会话既有的消息模式。较大的正增量表示该帧引入了新信息——架构偏离、异常负载或新的消息类型。

这要求在同一进程中,将 MCP 工具状态与实时套接字注册表及概率帧分类器关联起来。仅用无状态代理包装 ws.send() 无法复现这一功能。


基础 URL

https://npm-package-ws-has-241560546-w-production.up.railway.app

身份验证

无。 此服务目前没有任何 API 密钥、标头或身份验证机制——无论请求携带什么标头,都会得到处理。

定价

  • POST /ws-sessions/open 需要 x402 付款:在 Base Sepolia(测试网)上支付 $0.01 USDC,方案为 exact。未付款的请求会收到 402 Payment Required,付款详情包含在 payment-required 响应标头中。
  • 所有其他操作(send-frame、drain-frames、telemetry、close)针对已在打开会话时完成付款的会话执行,不会单独收费。

端点

POST /ws-sessions/open

与目标 URL 建立持久 WebSocket 连接,并将其注册到有状态会话注册表中。返回供后续所有操作使用的 session_id。需要 x402 付款(见上文“定价”)。

当 Agent 需要在发送或接收帧之前启动长连接时使用。不要用它重新连接已打开的会话——请先调用 close,或使用现有会话的 session_id。

请求

{
  "target_url": "wss://echo.websocket.org",
  "connect_timeout_seconds": 10.0,
  "extra_headers": {
    "X-Custom-Header": "value"
  }
}

target_url 必须以 ws:// 或 wss:// 开头(会经过验证,而不只是通过架构中的正则表达式检查)。connect_timeout_seconds 默认为 10.0,范围为 0.5–60.0。extra_headers 为可选项(在升级请求中发送的 HTTP 标头)。

响应(201)

{
  "session_id": "8662044208f54095b327ab4c29e1554c",
  "target_url": "wss://echo.websocket.org",
  "state": "OPEN",
  "opened_at_unix": 1785012145.03,
  "message": "Session '8662044208f54095b327ab4c29e1554c' is OPEN. Use session_id for all subsequent operations."
}

session_id 是一个 32 个字符的十六进制字符串(uuid.uuid4().hex,不带连字符)——请在下方路径中直接使用。

错误:如果 target_url 不以 ws:///wss:// 开头,则返回 422;如果握手未能在 connect_timeout_seconds 内完成,则返回 504;如果主机无法访问或拒绝连接,则返回 502;如果服务的并发会话数已达到 NEXUS_WS_MAX_SESSIONS,则返回 503。


POST /ws-sessions/{session_id}/send-frame

通过已打开的会话发送单个文本帧或二进制帧,并返回该帧相对于会话基线的香农熵变化量。

适用于请求-响应模式,或向 WebSocket 服务端发布命令。请勿批量发送一系列帧——每帧调用一次此端点。如果 session_id 不存在,或连接未处于 OPEN 状态,则调用失败。

请求

{
  "payload": "{\"action\": \"subscribe\", \"channel\": \"trades\"}",
  "frame_type": "text"
}

frame_type 为 "text"(默认值)或 "binary"——若为二进制,payload 必须是十六进制编码的字符串。

响应(200)

{
  "session_id": "8662044208f54095b327ab4c29e1554c",
  "frame_type": "text",
  "payload_bytes": 44,
  "entropy_after": 4.237441,
  "entropy_delta": 0.245712,
  "schema_valid": true,
  "sent_at_unix": 1785012151.68
}

错误:如果注册表中没有 session_id(session_id '<id>' not found in registry),则返回 404;如果会话未处于 OPEN 状态,则返回 409;如果 frame_type 为 "binary" 且 payload 不是有效的十六进制字符串,则返回 422;如果底层套接字发送失败,则返回 502。


POST /ws-sessions/{session_id}/drain-frames

返回最多 max_frames 个自上次清空(或会话打开)以来接收并缓冲的入站帧,每个帧都附带其香农熵变化量和架构验证结果。

适用于轮询传入消息,而无需保持阻塞连接。请勿将其用作实时流传输机制——它只返回已缓冲的帧(每个会话的缓冲区最多容纳 512 帧;缓冲区满后会丢弃最旧的帧)。

请求

{
  "max_frames": 10
}

max_frames 默认为 32,范围为 1–256。

响应(200)

{
  "session_id": "8662044208f54095b327ab4c29e1554c",
  "frames_returned": 2,
  "frames": [
    {
      "payload": "{\"event\": \"trade\", \"price\": 42381.50}",
      "frame_type": "text",
      "entropy_after": 3.91,
      "entropy_delta": 0.12,
      "schema_valid": true,
      "received_at": 1785012155.203
    },
    {
      "payload": "{\"event\": \"liquidation\", \"size\": 180000, \"side\": \"long\"}",
      "frame_type": "text",
      "entropy_after": 5.38,
      "entropy_delta": 1.47,
      "schema_valid": false,
      "received_at": 1785012155.891
    }
  ],
  "buffer_remaining": 0
}

第二个帧的 entropy_delta 为 1.47,且 schema_valid: false,这表明该流引入的内容在统计上与会话已建立的字节分布不一致——Agent 可以据此决定是否升级处理或重新协商订阅。

错误:如果注册表中没有 session_id,则返回 404。


POST /ws-sessions/{session_id}/telemetry

返回会话的实时遥测信息:连接状态、帧计数、累计和滚动香农熵统计、架构违规率以及运行时间。无需请求正文。

适用于诊断数据流是否偏离预期架构,或在发送前确认会话仍然存活。请勿在紧密循环中将其用作主要的存活检查——每次调用都会重新计算滚动统计数据。

响应(200)

{
  "session_id": "8662044208f54095b327ab4c29e1554c",
  "target_url": "wss://echo.websocket.org",
  "state": "OPEN",
  "uptime_seconds": 108.77,
  "frames_sent": 1,
  "frames_received": 2,
  "current_entropy": 4.16695,
  "rolling_entropy_mean": 0.18,
  "rolling_entropy_std": 0.31,
  "rolling_entropy_max": 1.47,
  "cumulative_entropy_bits": 4.16695,
  "schema_violations": 1,
  "schema_violation_rate": 0.333333,
  "inbound_buffer_depth": 2
}

错误:如果注册表中没有 session_id,则返回 404。


POST /ws-sessions/{session_id}/close

发送包含指定状态代码的 WebSocket 关闭帧,等待服务端完成关闭握手,并从注册表中移除会话。返回最终遥测快照。调用后,session_id 会被永久释放,无法重新使用。

请求(两个字段均为可选)

{
  "status_code": 1000,
  "reason": "agent task complete"
}

status_code 默认为 1000,范围为 1000–4999(RFC 6455)。reason 默认为 "",最长 123 个字节。

响应(200)

{
  "session_id": "8662044208f54095b327ab4c29e1554c",
  "target_url": "wss://echo.websocket.org",
  "final_state": "CLOSED",
  "frames_sent": 1,
  "frames_received": 2,
  "terminal_entropy": 4.16695,
  "schema_violations": 1,
  "uptime_seconds": 310.2,
  "message": "Session '8662044208f54095b327ab4c29e1554c' closed with status 1000. Total frames exchanged: 3. session_id is permanently deallocated."
}

错误:如果注册表中没有 session_id,则返回 404。


端到端示例:打开会话、发送帧、清空缓冲区并关闭会话

import httpx

BASE = "https://npm-package-ws-has-241560546-w-production.up.railway.app"

# 1. Open a session (requires x402 payment on this call — omitted here for brevity,
#    see https://docs.x402.org for how to attach a payment header)
r = httpx.post(f"{BASE}/ws-sessions/open", json={
    "target_url": "wss://echo.websocket.org",
    "connect_timeout_seconds": 10.0,
})
r.raise_for_status()
session_id = r.json()["session_id"]

# 2. Send a frame (not billed)
httpx.post(f"{BASE}/ws-sessions/{session_id}/send-frame", json={
    "payload": '{"action": "ping"}',
    "frame_type": "text",
}).raise_for_status()

# 3. Drain buffered inbound frames, alert on entropy spikes
ENTROPY_ALERT_THRESHOLD = 1.0

drain = httpx.post(f"{BASE}/ws-sessions/{session_id}/drain-frames", json={
    "max_frames": 20,
}).json()

for frame in drain["frames"]:
    if frame["entropy_delta"] > ENTROPY_ALERT_THRESHOLD or not frame["schema_valid"]:
        print(f"[ALERT] delta={frame['entropy_delta']:.2f} schema_valid={frame['schema_valid']}")
        print(f"        payload={frame['payload'][:120]}")

# 4. Inspect session health before deciding to continue
telemetry = httpx.post(f"{BASE}/ws-sessions/{session_id}/telemetry").json()
print(f"schema_violation_rate={telemetry['schema_violation_rate']:.3f} "
      f"current_entropy={telemetry['current_entropy']:.2f}")

# 5. Close cleanly
httpx.post(f"{BASE}/ws-sessions/{session_id}/close", json={
    "status_code": 1000,
    "reason": "task complete",
}).raise_for_status()

curl 示例

# Open a session (requires x402 payment — this call alone will return 402
# without a valid payment header; see https://docs.x402.org)
curl -X POST https://npm-package-ws-has-241560546-w-production.up.railway.app/ws-sessions/open \
  -H "Content-Type: application/json" \
  -d '{"target_url": "wss://echo.websocket.org"}'

# Send a frame (replace SESSION_ID with the value returned above — not billed)
curl -X POST https://npm-package-ws-has-241560546-w-production.up.railway.app/ws-sessions/SESSION_ID/send-frame \
  -H "Content-Type: application/json" \
  -d '{"payload": "hello world", "frame_type": "text"}'

# Drain buffered inbound frames
curl -X POST https://npm-package-ws-has-241560546-w-production.up.railway.app/ws-sessions/SESSION_ID/drain-frames \
  -H "Content-Type: application/json" \
  -d '{"max_frames": 5}'

MCP

将兼容 MCP 的客户端连接到以下流式 HTTP 端点:

https://npm-package-ws-has-241560546-w-production.up.railway.app/mcp

提供与 MCP 工具相同的 5 个操作(open_websocket_session、send_typed_ws_frame、drain_ws_frame_buffer、inspect_ws_session_telemetry、close_websocket_session),参数和支付要求也相同(open_websocket_session 需要 x402 支付;其他 4 个操作不需要)。


SDK

  • sdk_wrappers/sdk.js — 通过 axios 连接到上述基础 URL 的真实 HTTP 客户端。以 @nexus-mcp-infra/npm-package-ws-has-241560546-weekly-downloads-but-sdk 为包名发布到 npm。请使用此客户端。
  • mcp_wrapper/npm_package_ws_has_241560546_weekly_downloads_but_sdk.py — **请勿使用。**其默认使用占位域名(https://api.ws-mcp.nexus.ai/v1),调用的路由(/sessions/open、/frames/send 等)并不存在于此 API 上,而且要求提供此服务不会检查的 api_key。它在初始构建后从未修复;保留在仓库中仅供历史参考,请勿使用。

如上所示,直接通过 httpx、requests 或 curl 向上述端点发起 HTTP 调用,无需 SDK。


错误参考

HTTP 状态码条件
402需要付款(仅适用于 POST /ws-sessions/open,x402)
404注册表中不存在 session_id
409会话不处于 OPEN 状态(例如,尚未连接或正在关闭)
422target_url 不是有效的 ws:///wss:// URL,或二进制 payload 不是有效的十六进制字符串
502连接 target_url 时发生网络错误,或发送帧时出错
503会话注册表已达到容量上限
504WebSocket 握手未能在 connect_timeout_seconds 内完成

技术栈

Python 3.13 — FastAPI — websockets(原生支持 asyncio)。会话注册表和每个会话的熵状态都驻留在进程内;熵跟踪器会为每个 session_id 维护一个令牌频率 Counter,每收到一帧就更新一次,且不会阻塞套接字循环。进程重启或重新部署后,会话不会保留。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。