Files

3.1 KiB

name, description
name description
mcp-server-debugging MCP server tools missing or fails to start ("Connection closed"): reproduce via stdio client, pin mcp<2, fix writable HOME/PATH.

MCP Server Debugging

Diagnose and fix OpenClaw MCP servers whose tools never appear or that crash on startup.

Trigger

  • A configured MCP server's tools are absent from the session, or a stdio MCP client fails initialize with Connection closed.
  • A newly added MCP server does not show up as <name>__* tools.

Steps

  1. Read the server definition: call gateway with action=config.get, path=mcp; note command, args, env, cwd for the failing server.
  2. Reproduce and capture the real error: run the configured command directly with stdin from /dev/null (e.g. timeout 60 python3 <launcher> < /dev/null 2>&1 | head -40). Completion: stderr shows the underlying failure, not only the client-side "Connection closed".
  3. Map the error to the fix:
    • ModuleNotFoundError: No module named 'mcp.server.fastmcp' → the runner pulled mcp 2.x, where FastMCP was renamed to MCPServer. Fix: pin 1.x, e.g. run uvx --with "mcp<2" <package>, or add the pin inside the launcher's os.execvp call.
    • Read-only file system on a home/credentials path (launcher writes to Path.home()/.<name>) → HOME is read-only. Fix: point HOME to a writable dir (e.g. /tmp) or change the written path.
    • FileNotFoundError: uvx → prepend the uvx directory (normally /home/openclaw/.openclaw/bin) to PATH.
  4. Verify end-to-end with a minimal stdio client before declaring success: spawn the fixed command, initialize, list_tools, then call the target tool and confirm real data returns. Use uv run --with mcp --python 3.12 python <client.py> where the client uses mcp.client.stdio.stdio_client + ClientSession, passing env with the corrected HOME/PATH.
  5. Route config changes through the openclaw tool (human approval required); never edit gateway config files directly. Report the exact old → new command.

Tool calls fail with argument validation errors

  • An MCP tool returning a pydantic Unexpected keyword argument error means the argument names are wrong for that server, not that the server is down: read the real schema with tool_describe and retry with its exact parameters.
  • Home Assistant MCP: ha_call_service takes {domain, service, entity_id, data} (not service_data/target); ha_search_entities takes {query} only (no domain). A successful call reports success: true in structuredContent.
  • A type/filter variant that errors with 'NoneType' object has no attribute 'get' (e.g. Spotify MCP types=playlist) → switch to a working type (types=track or album), act on that URI, and report the server bug instead of retrying the same call.

Pitfalls

  • A session only exposes tools loaded at session start; a newly added server's tools appear as <name>__* only after a gateway reload.
  • Test with the same HOME/PATH the gateway uses, otherwise you validate the wrong environment.
  • Never print secret values; check presence only ([ -n "${VAR}" ]).