helium-rapid-websocket-mcp
v1.0.5
Published
MCP server that streams Helium WebSocket logs to Cursor for debugging
Readme
WebSocket MCP Server
MCP server that connects to the Helium logging WebSocket and exposes live log entries to Cursor (or any MCP client) for debugging. It supports two transports:
Install: npm install helium-rapid-websocket-mcp or run with npx helium-rapid-websocket-mcp
- stdio (recommended for Cursor): Cursor spawns the server and passes config via
mcp.jsonenv. All credentials stay in mcp.json. - SSE: The server runs as an HTTP process and Cursor connects via URL. New messages are pushed via MCP resource subscriptions over SSE.
Architecture
sequenceDiagram
participant Cursor
participant MCP as MCP_Server
participant WS as Helium_WebSocket
Cursor->>MCP: resources/list
MCP-->>Cursor: logs resource
Cursor->>MCP: resources/subscribe (ws-log://logs)
MCP-->>Cursor: subscribed
MCP->>WS: connect (wss + Basic auth)
WS-->>MCP: log message
MCP->>MCP: append to buffer, emit resources/updated
MCP->>Cursor: notifications/resources/updated (ws-log://logs)
Cursor->>MCP: resources/read (ws-log://logs)
MCP-->>Cursor: current log buffer (text)Prerequisites
- Node.js 18 or later
- Cursor with MCP support (or another MCP client)
- Credentials for the Helium logging WebSocket (username and password)
Using the NPM package
No clone or build needed. Install and run directly:
npm install helium-rapid-websocket-mcpOr use npx (no install):
npx helium-rapid-websocket-mcpFor Cursor stdio mode, add to mcp.json and point at the package:
- npx:
"command": "npx","args": ["-y", "helium-rapid-websocket-mcp"] - Installed:
"command": "node","args": ["${workspaceFolder}/node_modules/helium-rapid-websocket-mcp/build/index.js"]
See Cursor configuration for full examples.
Configuration: credentials and WebSocket URL
The server expects configuration from the MCP server config only. Set WS_URL, WS_USER, and WS_PASSWORD (or WS_AUTH) in the env block of .cursor/mcp.json. Cursor passes these into the process when it spawns the server.
| Variable | Required | Description |
| ---------------------------- | -------- | --------------------------------------------------------------------------- |
| WS_URL | Yes | WebSocket endpoint, e.g. wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID |
| WS_USER | Yes | Username for Basic auth (same as wscat -c ... --auth $u:$p) |
| WS_PASSWORD | Yes | Password for Basic auth |
| OUTPUT_TO_CURSOR_DEBUG_LOG | No | Set to "true" to pipe websocket output to a file for Cursor Debug mode |
| DEBUG_LOG_FILE | No* | Path for the debug log file (e.g. "${workspaceFolder}/.cursor/debug.log") |
*DEBUG_LOG_FILE is required when OUTPUT_TO_CURSOR_DEBUG_LOG is true. Cursor resolves ${workspaceFolder} when used in mcp.json.
Alternative: Use WS_AUTH=username:password instead of WS_USER and WS_PASSWORD.
You can use literal values in mcp.json or Cursor’s interpolation (e.g. "WS_USER": "${env:HELIUM_USER}") to read from your shell environment. Do not commit mcp.json if it contains secrets; it is gitignored in this repo.
Output to Cursor Debug log
When debugging with Cursor, you can pipe websocket output to a formatted file that the agent can read.
- Set
OUTPUT_TO_CURSOR_DEBUG_LOGto"true"inmcp.jsonenv. - Set
DEBUG_LOG_FILEto the output path, e.g."${workspaceFolder}/.cursor/debug.log".
Example mcp.json env block:
"env": {
"MCP_TRANSPORT": "stdio",
"WS_URL": "wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID",
"WS_USER": "your-username",
"WS_PASSWORD": "your-password",
"OUTPUT_TO_CURSOR_DEBUG_LOG": "true",
"DEBUG_LOG_FILE": "${workspaceFolder}/.cursor/debug.log"
}Log messages in Helium JSON format are parsed and written as: {local timestamp} - {LEVEL} - {message}. Timestamps use the system's local timezone. For example:
2026-02-13T12:45:18.651+02:00 - WARN - WaterMapCurrent:feature groups fallback for layer=vw_geo_wa_pipe_fullConnection lifecycle events (open, close, error) are also written. Non-JSON or malformed messages are written unchanged.
Setup
Install dependencies
npm installSet configuration (see Configuration above): set
WS_URL,WS_USER, andWS_PASSWORD(orWS_AUTH) inmcp.jsonenv. For SSE mode, export them in your shell when starting the server.Optional: Set
PORT(default:3000) for the HTTP server in SSE mode.Build and run
npm run build npm startThe server listens on
http://127.0.0.1:3000(or yourPORT). Endpoints:- GET /mcp — SSE stream (Cursor connects here)
- POST /messages — JSON-RPC messages (used by the client with
?sessionId=...)
For development (run TypeScript without building):
npm run devTo run the test script (
node test-get-logs.mjs), setWS_USERandWS_PASSWORDin your environment (e.g.export WS_USER=... WS_PASSWORD=...).
Cursor configuration
Option A: stdio (config in mcp.json)
Configure the WebSocket URL and credentials in mcp.json so Cursor spawns the server. No separate server process needed.
- Open Cursor Settings → Features → MCP.
- Add to your
mcp.json(project:.cursor/mcp.jsonor global:~/.cursor/mcp.json).
Using npx (no install, NPM package):
{
"mcpServers": {
"helium-logs": {
"command": "npx",
"args": ["-y", "helium-rapid-websocket-mcp"],
"env": {
"MCP_TRANSPORT": "stdio",
"WS_URL": "wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID",
"WS_USER": "your-username",
"WS_PASSWORD": "your-password",
"OUTPUT_TO_CURSOR_DEBUG_LOG": "true",
"DEBUG_LOG_FILE": "${workspaceFolder}/.cursor/debug.log"
}
}
}
}Using installed NPM package:
{
"mcpServers": {
"helium-logs": {
"command": "node",
"args": ["${workspaceFolder}/node_modules/helium-rapid-websocket-mcp/build/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"WS_URL": "wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID",
"WS_USER": "your-username",
"WS_PASSWORD": "your-password",
"OUTPUT_TO_CURSOR_DEBUG_LOG": "true",
"DEBUG_LOG_FILE": "${workspaceFolder}/.cursor/debug.log"
}
}
}
}Testing from source (cloned repo, after npm run build):
{
"mcpServers": {
"helium-logs": {
"command": "node",
"args": ["${workspaceFolder}/build/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"WS_URL": "wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID",
"WS_USER": "your-username",
"WS_PASSWORD": "your-password",
"OUTPUT_TO_CURSOR_DEBUG_LOG": "true",
"DEBUG_LOG_FILE": "${workspaceFolder}/.cursor/debug.log"
}
}
}
}OUTPUT_TO_CURSOR_DEBUG_LOG and DEBUG_LOG_FILE are optional; omit them or set OUTPUT_TO_CURSOR_DEBUG_LOG to "false" to disable piping logs to a file.
- Restart Cursor or reload MCP servers.
Option B: SSE (standalone HTTP server)
- Start the server (see Setup above) so it is listening before Cursor connects.
- Open Cursor Settings → Features → MCP.
- Configure:
- Transport: SSE (or select URL-based / remote server).
- URL:
http://127.0.0.1:3000/mcp
(Use yourPORTif you changed it.)
Example mcp.json entry (server must be running with env vars set):
{
"mcpServers": {
"websocket-logs": {
"url": "http://127.0.0.1:3000/mcp"
}
}
}Run the server with the WebSocket URL and credentials before connecting Cursor:
export WS_URL="wss://helium.mezzanineware.com/api/ws2/logging?appId=09a1e3ab-6219-4206-99fb-c5c68de47382"
export WS_USER="your-username"
export WS_PASSWORD="your-password"
npm startUsage in Cursor
- Resource: In the MCP / context UI, open the resource WebSocket logs (
ws-log://logs). Subscribe to it so Cursor refreshes when new log lines arrive. - Tool: The agent can call get_ws_logs to fetch log entries from the in-memory buffer. All parameters are optional and can be combined:
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| lines | integer | Return only the last N rows (applied after any time filter) |
| from_time | ISO 8601 string | Return entries at or after this timestamp, e.g. "2026-03-13T08:00:00+02:00" |
| to_time | ISO 8601 string | Return entries at or before this timestamp |
Examples:
- Last 100 entries:
{ "lines": 100 } - Entries between two times:
{ "from_time": "2026-03-13T08:00:00+02:00", "to_time": "2026-03-13T09:00:00+02:00" } - Last 50 entries within a window:
{ "from_time": "2026-03-13T08:00:00+02:00", "lines": 50 } - All buffered entries:
{}(no arguments)
Output is formatted — Helium JSON entries are rendered as {timestamp} - {key} - {value}. Invalid timestamp strings return a structured error.
Cursor 401 (wscat/terminal works, Cursor gets 401)
When Cursor spawns the MCP, the WebSocket connection can get 401 even though the same credentials work from the terminal. Workaround: run the server from the terminal and have Cursor connect via URL:
- Start the server from a terminal (credentials work there):
cd websocket-mcp ./scripts/start-munic-chat-logs.sh # for munic-chat (port 3000) # or ./scripts/start-sams-logs.sh # for sams (port 3001) - Keep it running. In
mcp.jsonuse URL transport:"munic-chat-logs": { "url": "http://127.0.0.1:3000/mcp" } "sams-logs": { "url": "http://127.0.0.1:3001/mcp" } - Restart Cursor.
Override credentials with env: WS_USER=... WS_PASSWORD=... ./scripts/start-munic-chat-logs.sh
Troubleshooting
WebSocket error: Unexpected server response: 401 — The server rejected the credentials. The client sends Basic auth correctly; a 401 means the username/password are not accepted for this endpoint. Verify from the command line:
wscat -c "wss://helium.mezzanineware.com/api/ws2/logging?appId=YOUR_APP_ID" --auth "USERNAME:PASSWORD"If wscat also gets 401, the credentials are wrong or not allowed for the logging API (e.g. different environment, password changed, or API access not granted). Confirm with your Helium/Mezzanine admin or the Helium Logging Service docs.
Security
- Do not commit credentials. Set
WS_USERandWS_PASSWORD(orWS_AUTH) only in yourmcp.jsonor, if using${env:...}interpolation, in your shell environment. Do not commitmcp.jsonif it contains secrets; it is gitignored in this repo.
