If you've used MCP servers with Claude Code or Cursor before, you've probably noticed most of them fall into one of two buckets:

  1. Fully in-process — the agent runs the tool directly on the same machine (local files, local shell). Great for personal dev work, doesn't scale to production ops.
  2. Fully managed — the service runs everything on its own infrastructure with its own credentials. Fast, but you just handed a third party long-lived SSH keys for your prod servers. Hard pass.

We wanted a third option. Servonaut's hosted MCP server takes the best of both: the agent talks to mcp.servonaut.dev over a normal HTTPS SSE connection, but when it calls a tool like run_command or get_logs, the backend does not execute it. Instead, it publishes the request to a Mercure hub on a private per-user topic, where your own locally-running servonaut connect process picks it up and runs the command using your SSH keys, your cloud credentials, your hostnames.

The shape of a round-trip

  Claude Code                  servonaut.dev                Your laptop
  ───────────                  ─────────────                ───────────

  POST /mcp/message  ───►  ToolRouter (auth + entitlements)
  "run_command"             │
                            ▼
                           MercureCliRelay ──publish──►  Mercure hub
                            │ poll Redis                       │
                            │ for response                     │ SSE
                            │                                  ▼
                            │                       servonaut connect
                            │                       (subscribed via JWT)
                            │                         │
                            │                         │ SSH to target
                            │                         ▼
                            │                       execute locally
                            │                         │
                            │                         ▼
                           /api/cli/command-result ◄──POST──┘
                            │
  ◄───  output  ────────────┘

The backend is a coordinator. Your CLI is the executor. That means:

  • Your SSH keys never leave your machine
  • Your cloud credentials never leave your machine
  • The backend's worst-case breach reveals pending command requests, not keys
  • If servonaut connect isn't running, the agent gets an informative error — not a silent "I'll just run it myself with some default key" surprise

Private topics, short-lived JWTs

Subscribers authenticate to the Mercure hub with a JWT scoped to exactly /cli/{your_user_id}/commands. The token is minted by the backend only after your CLI has authenticated with its OAuth bearer, lives for 1 hour, and refreshes automatically. Another user can't even subscribe to your topic, let alone receive your commands.

What you can do with it

  • Ask an AI agent to grep logs across 10 servers and summarise anomalies
  • Have CI bots call get_server_info without shipping SSH keys into CI secrets
  • Let support agents (with scoped credentials) run pre-approved commands on customer fleets

The CLI-side relay is in final testing; the hosted endpoint goes live at launch.