Skip to main content
MCP involves two processes talking over HTTP or stdio. Here’s how to debug them.

The tmux pattern

Run server and client in split terminals:
tmux new-session -d -s mcp
tmux split-window -h
tmux send-keys -t mcp:0.0 'python server.py' C-m
sleep 2
tmux send-keys -t mcp:0.1 'python client.py' C-m
tmux attach -t mcp
See both outputs side by side. Kill when done: tmux kill-session -t mcp

Structured logging

Log from inside tools:
from dedalus_mcp import get_context, tool

@tool(description="Process data")
async def process(data: str) -> dict:
    ctx = get_context()
    await ctx.debug("Starting", data={"length": len(data)})
    # ... work ...
    await ctx.info("Done", data={"result": 42})
    return {"ok": True}

Verbose mode

await server.serve(verbose=True, log_level="debug")
Or via environment:
LOG_LEVEL=debug python server.py

Client-side log capture

from dedalus_mcp.client import MCPClient, ClientCapabilitiesConfig

def log_handler(params):
    print(f"[{params.level}] {params.data}")

config = ClientCapabilitiesConfig(logging=log_handler)
client = await MCPClient.connect(url, capabilities=config)

Common issues

“Client does not advertise the sampling capability” Pass a sampling handler:
config = ClientCapabilitiesConfig(sampling=sampling_handler)
client = await MCPClient.connect(url, capabilities=config)
“Tool mutation attempted after server startup” Enable dynamic tools:
server = MCPServer("my-server", allow_dynamic_tools=True)
Connection refused Check the port: lsof -i :8000 Kill orphans: lsof -ti :8000 | xargs kill -9 Wrong URL The endpoint is http://127.0.0.1:8000/mcp, not just :8000.

When stuck

  1. Strip to minimal reproduction
  2. Check MCP spec compliance
  3. Test with MCP Inspector: npx @anthropic/mcp-inspector
  4. Read server logs