Openclaw Mcp Proxy — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Openclaw Mcp Proxy (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
OpenClaw MCP Proxy is a small FastAPI + FastMCP service that exposes app-registered tools as an MCP server for OpenClaw, while forwarding actual tool execution back to the app over a WebSocket bridge.
It has two responsibilities:
sequenceDiagram
participant AppClient
participant ProxyServer
participant OpenClawClient
AppClient->>ProxyServer: POST /v1/chat/sessions
ProxyServer-->>AppClient: mcpSessionId, bridge_url, mcp_url
AppClient->>ProxyServer: WS /v1/chat/sessions/{session_id}/bridge
OpenClawClient->>ProxyServer: POST /v1/mcp/{session_id}
ProxyServer->>AppClient: invoke_tool
AppClient-->>ProxyServer: invoke_result
ProxyServer-->>OpenClawClient: MCP tool result
AppClient->>ProxyServer: DELETE /v1/chat/sessions/{session_id}POST /v1/chat/sessionsCreates a session and returns the bridge and MCP endpoints for that session.
Request body:
{
"device_id": "device-1",
"device_name": "desktop",
"app_version": "1.0.0",
"chat_id": "chat-1",
"tools": [
{
"name": "echo_text",
"path": "/tools/echo_text",
"description": "Echo text.",
"input_schema": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
}
}
]
}Response body:
{
"mcpSessionId": "session-id",
"bridge_url": "ws://127.0.0.1:8000/v1/chat/sessions/session-id/bridge",
"mcp_url": "http://127.0.0.1:8000/v1/mcp/session-id"
}DELETE /v1/chat/sessions/{session_id}Deletes a session.
Response body:
{
"ok": true
}WS /v1/chat/sessions/{session_id}/bridgeConnects the app-side execution bridge for a registered session.
Bridge messages:
invoke_toolinvoke_resultpingpongProxy -> app:
{
"type": "invoke_tool",
"mcpSessionId": "session-id",
"request_id": "session-id:1",
"tool_name": "echo_text",
"arguments": {
"text": "hello"
}
}App -> proxy:
{
"type": "invoke_result",
"mcpSessionId": "session-id",
"request_id": "session-id:1",
"ok": true,
"content": {
"echoed_text": "hello"
}
}POST /v1/mcp/{session_id}Exposes the registered tools for a specific session as a stateless HTTP MCP endpoint.
This is the simplest way to connect OpenClaw to a specific registered session.
POST /v1/mcp/ with MCP-Session-IdThe MCP endpoint also supports header-based session routing:
MCP-Session-Id: <session_id>This is useful when the MCP client configuration prefers a stable URL and injects the session ID through headers.
The proxy now supports two MCP-facing transports:
MCP-Session-Idinitialize via mcpSessionIdThe stdio transport is implemented as a local proxy process in front of the HTTP MCP endpoint. The actual tool execution path is unchanged:
initialize.params.mcpSessionId and proxies MCP traffic to POST /v1/mcp with header MCP-Session-Id.GET /healthReturns plain text ok.
The proxy uses two independent bearer tokens:
OPENCLAW_PROXY_APP_TOKENUsed by:
POST /v1/chat/sessionsDELETE /v1/chat/sessions/{session_id}WS /v1/chat/sessions/{session_id}/bridgeOPENCLAW_PROXY_OPENCLAW_TOKENUsed by:
/v1/mcp/...Important:
OPENCLAW_PROXY_APP_TOKEN is empty, app-facing endpoints accept requests without authentication.OPENCLAW_PROXY_OPENCLAW_TOKEN is empty, MCP-facing endpoints accept requests without authentication.Do not leave either token empty outside local development.
WebSocket close codes:
4401: invalid app token4404: unknown session_idEnvironment variables:
| Variable | Default | Description |
|---|---|---|
OPENCLAW_PROXY_APP_TOKEN | "" | Bearer token for app registration and bridge endpoints. |
OPENCLAW_PROXY_OPENCLAW_TOKEN | "" | Bearer token for MCP requests from OpenClaw. |
OPENCLAW_PROXY_SERVER_URL | http://127.0.0.1:8000 | Base URL used by the stdio proxy process to reach the HTTP proxy. |
OPENCLAW_PROXY_SESSION_TTL_SECONDS | 300 | Session time-to-live in seconds. |
OPENCLAW_PROXY_TOOL_TIMEOUT_SECONDS | 120 | Tool call timeout in seconds. |
Example .env:
OPENCLAW_PROXY_APP_TOKEN=replace-me
OPENCLAW_PROXY_OPENCLAW_TOKEN=replace-me
OPENCLAW_PROXY_SERVER_URL=http://127.0.0.1:8000
OPENCLAW_PROXY_SESSION_TTL_SECONDS=300
OPENCLAW_PROXY_TOOL_TIMEOUT_SECONDS=120pippip install -r requirements.txtuvicorn app.main:app --host 0.0.0.0 --port 8000After creating a session and connecting the app bridge, you can expose that session over stdio:
python -m app.stdio_mainOptional flags:
python -m app.stdio_main \
--proxy-base-url http://127.0.0.1:8000The stdio client must send mcpSessionId in initialize.params, for example:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {
"name": "your-client",
"version": "1.0.0"
},
"mcpSessionId": "<session_id>"
}
}curl http://127.0.0.1:8000/healthExpected output:
okHeader-routed example:
{
"mcpServers": {
"otakuroom-chat-mcp": {
"transport": "http",
"url": "https://your-proxy-host.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${OPENCLAW_PROXY_OPENCLAW_TOKEN}",
"MCP-Session-Id": "${SESSION_ID}"
}
}
}
}You can also connect directly to the session-specific URL returned by session creation, for example:
https://your-proxy-host.example.com/v1/mcp/<session_id>Stdio example:
{
"mcpServers": {
"otakuroom-chat-mcp": {
"transport": "stdio",
"command": "python",
"args": [
"-m",
"app.stdio_main"
],
"env": {
"OPENCLAW_PROXY_SERVER_URL": "http://127.0.0.1:8000",
"OPENCLAW_PROXY_OPENCLAW_TOKEN": "${OPENCLAW_PROXY_OPENCLAW_TOKEN}"
}
}
}
}invoke_tool over the WebSocket bridge.invoke_result.Run the proxy integration tests:
python -m unittest tests.test_proxy_integrationCurrent coverage includes:
mcp_urlMCP-Session-IdThe proxy is not currently designed for stateless multi-instance deployment without sticky routing or shared session state.
If the session exists but the bridge is disconnected, tool calls fail with Bridge is not connected.
A background cleanup loop runs every 15 seconds and removes expired sessions.
AuthorizationMCP-Session-Idinput_schema.Only trusted app clients should be allowed to register tool definitions.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.