36 MCP tools your AI agent can call: the Servonaut catalog
The MCP catalog has grown. As of this week we ship 36 tools across five families, every mutating call carrying a "confirm with the user" instruction in its description, and every call audited. This is a tour of what's there, why it's grouped the way it is, and what we deliberately don't expose.
The five families
| Family | Tools | Notes |
|---|---|---|
| Core relay | 4 | list_instances, run_command, get_logs, transfer_file. The basics that work on any managed instance regardless of provider. |
| Hetzner Cloud | 11 | Full lifecycle (create / delete / power on / power off / shutdown / reboot) plus SSH-key registry CRUD. |
| OVH Cloud | 13 | Lifecycle (create / delete / start / stop / reboot) plus 8 read-only inspection tools (DNS, IPs, billing, snapshots, …). |
| Server Memory | 4 | get, list, build, refresh — the cached fact pack for every server. |
| Router-premium | 4 | deploy, provision, cost_report, security_scan. Higher-level recipes. |
Plus a handful of authenticated session tools (whoami, relay_status, api_request) that are MCP-only — the chat panel doesn't surface them, because you don't want an LLM hitting arbitrary REST endpoints.
Three guard tiers
Every tool has a guard tier — a coarse label for how dangerous it is:
readonly(default): listings, status, log fetch, server-memory queries, OVH read tools. No remote state changes, ever.standard: read tools plusrun_command,build_server_memory,refresh_server_memory,hetzner_create_ssh_key. Recommended for personal use with a trusted agent.dangerous: full lifecycle (create / delete / power state), SSH-key deletion,transfer_file(SCP). Use only in fully trusted, single-user setups.
Set the level in ~/.servonaut/config.json under mcp.guard_level. The MCP server filters its tools/list response server-side based on the configured level — the agent literally cannot see tools outside its guard.
Account-scoped vs server-scoped
A subtle distinction worth calling out: Hetzner / OVH / Memory tools are account-scoped — they operate on cloud-provider IDs (project IDs, server IDs, IP addresses, zones), not on rows in the Servonaut shared-server database. The dispatcher routes them through a generic handleAccountScopedTool() helper that:
- Resolves the user's team (first accepted membership, fallback to owned team)
- Checks the per-tier entitlement (
hetzner_mcp_operations,ovh_mcp_operations,memory_sync) - Consults the team's
McpPolicy— does this tool need approval? - If yes (and policy says so), routes to
ApprovalServiceinstead of executing - Otherwise, dispatches to the user's CLI via the Mercure relay
- Logs every step to the JSONL audit trail
The core relay tools (run_command, get_logs, etc.) operate on Servonaut's own server records and use a slightly different dispatch path, but the audit and policy machinery is the same.
The confirmation protocol
Every mutating tool's description ends with a one-line instruction telling the LLM to confirm before invoking. For example, hetzner_delete_server:
"Always confirm with the user before invoking this tool — deletion is
permanent and the server's data cannot be recovered."
This is not a security boundary. It's a usability layer. Real security comes from three layers under it:
- Guard level (server-side): the tool is filtered out of
tools/listif the user's guard is too low. - Entitlement (server-side): the tool returns "your plan does not include …" if the user is on the wrong tier.
- Team policy (server-side, Teams plan only): per-tool approval list. Mutating calls return an "Approval required" envelope and wait in the audit log until a teammate clicks Approve / Deny.
Together: defence-in-depth. The LLM prompt is what stops the good-faith accidents; the server-side gates stop everything else.
What we don't expose
A few things by deliberate omission:
- AWS lifecycle tools. No
aws_create_instanceoraws_terminate_instancein the catalog yet. Reason: AWS fleets are typically long-lived and managed by Terraform / CloudFormation. The disposable-fleet pattern that justifies create/destroy on Hetzner doesn't fit AWS workflows. We'll add them when there's a clear need. - OVH dedicated server lifecycle. OVH dedicated servers have a different API surface and a much longer billing cycle (monthly, not hourly) — wrong fit for "agent creates and destroys boxes". Manage these in the OVH Console.
- Generic
sql_queryordb_dumptools. The agent doesn't need direct DB access. If you want it to run a query, that'srun_commandwithpsql -c '...'. Keeps the audit trail in one place. - Tools that take free-text Bash from the model. All shell execution goes through
run_command, which is gated by the on-serverCommandGuardblocklist (rm -rf,shutdown,dd, etc.). The agent can't bypass it.
Adding a tool
For agents that build their own MCP servers: tools in Servonaut are defined in src/Service/Mcp/ToolRouter.php (the catalog) and dispatched in src/Service/Mcp/ProxiedToolHandler.php (the per-tool handler). Adding a new account-scoped tool is one entry in OVH_ACCOUNT_TOOLS (or the equivalent map for the new provider) plus the entitlement key plumbing — the generic dispatcher handles policy, approval, audit, and relay automatically.
Trying it
servonaut --mcp-install claude (or cursor, windsurf, vscode, opencode, all) installs the local stdio MCP server. For the hosted variant, log in, run servonaut connect, and point your agent at https://mcp.servonaut.dev/mcp/sse with a Bearer token from servonaut login. Full reference at /docs/mcp.
Comments 0
No comments yet. Be the first to comment!
Edit Comment