MCP Server
Give AI agents like Claude Code, Cursor, and Windsurf direct access to your fleet — across AWS, OVH Cloud, Hetzner Cloud, and custom hosts — through a typed, audited tool surface with three guard tiers and an explicit confirmation protocol on mutating calls.
This section is for wiring up AI agents, not day-to-day use. For humans operating their
fleet, the TUI is the product — run servonaut
and everything below is optional.
What is MCP?
Model Context Protocol (MCP) is an open standard created by Anthropic that lets AI assistants connect to external tools and data sources. Think of it as a plugin system for AI agents.
Servonaut ships an MCP server in two flavours:
- Local stdio (free) —
servonaut --mcpexposes the CLI's own tool surface to an agent running on the same machine. - Hosted (Solo & Teams) — agents connect to
mcp.servonaut.devover HTTPS+SSE, and the backend relays calls back to your own CLI over a secure, authenticated relay channel. The agent can be on a colleague's laptop or in CI — but commands always run with your SSH keys, on your machine. The backend never holds your SSH keys or cloud credentials — it stores only references your CLI resolves locally.
"Spin up two Hetzner cx23 boxes in fsn1 named demo-1 and demo-2, run my cluster bootstrap script, then summarise their journalctl errors."
Claude calls hetzner_create_server twice (with a confirmation prompt), run_command for the bootstrap, and get_logs for the errors — all using your local credentials, with every call written to the audit log.
No setup at all: the TUI's built-in AI chat
If you just want an AI assistant working on your servers, you don't need to wire up an external agent.
Run servonaut and press F2 — the built-in AI chat panel opens alongside whichever
screen you're on, with tool-calling against your instances drawn from the same catalog documented below
(most tools are available in chat; a minority, such as raw file transfer, are reserved for the MCP surface).
It works with your own provider keys (OpenAI, Anthropic, Gemini, Ollama —
configure them under Tools → Settings) or with the hosted Servonaut AI gateway on Solo and Teams
plans; your remaining quota and top-up balance are shown inline, and you can switch provider per-session
from the panel header. The active instance's server memory is injected into the conversation automatically,
with a staleness banner.
Chat tool calls go through the same guard levels as everything else. Dangerous-tier tools are never offered in chat unless your account has the dangerous-AI-tools opt-in — enforced server-side and in the client. The rest of this page is for connecting external agents — Claude Code, Cursor, CI jobs — to the same guarded, audited tool surface.
Quick install
The fastest way to wire Servonaut into your agent of choice is the auto-installer. It detects supported clients (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, OpenCode) and writes the right config block.
The MCP server requires the mcp Python package. Fresh install: pipx install 'servonaut[mcp]' pulls it in automatically. Existing install: add it with pipx inject servonaut mcp before running --mcp-install.
Install from the MCP Registry
Servonaut is listed in the official MCP Registry
as dev.servonaut/servonaut, so any registry-aware MCP client or aggregator can discover and
install it directly. The registry launch command runs the server straight from PyPI:
Agent-only / headless install
No TUI required — you can install Servonaut purely as an MCP backend for your coding agent.
The MCP server runs fully headless: servonaut --mcp never loads the terminal UI,
so it works on a server or CI box with no display and no interactive session.
Configure credentials and servers the same way as a TUI install — edit
~/.servonaut/config.json directly (see the Configuration reference).
Everything an agent does goes through the same guard levels and is logged to
~/.servonaut/mcp_audit.jsonl, exactly as on a full install.
To connect a Servonaut Cloud account (config sync, hosted MCP relay, Servonaut AI), run
servonaut login — a fully headless OAuth device flow. It prints a verification URL
and short code; approve in any browser on any device (--no-browser skips the local
browser launch, --force re-authenticates over an existing session). Tokens are stored at
~/.servonaut/auth.json (permissions 0600) and shared by every CLI subcommand, the MCP
server, and the TUI — sign in once per machine. servonaut logout revokes the
session and removes the stored token.
Manual setup
Each client stores its MCP config in a different file. The simplest path is to let the auto-installer figure it out: servonaut --mcp-install <client> writes the correct block in the correct file. Common locations:
- Claude Code:
~/.claude.json - Cursor:
~/.cursor/mcp.json - Windsurf:
~/.codeium/windsurf/mcp_config.json - VS Code:
~/.config/Code/User/mcp.jsonon Linux. The location differs on macOS and Windows — runservonaut --mcp-install vscodeand it writes the correct file for your OS.
The MCP server block itself is the same in every file:
{
"mcpServers": {
"servonaut": {
"command": "servonaut",
"args": ["--mcp"],
"env": {}
}
}
}
After saving the file, restart the agent. The Servonaut tools appear in the tools panel.
Available tools
The catalog is grouped into ten families: core relay, AWS observability & security, AWS EC2, Amazon S3, incident response & diagnostics, Hetzner Cloud, OVH Cloud, Server Memory, orchestration, and session & backend. The list is filtered to what's actually usable for you: by plan, by guard level, and by configuration — Hetzner and OVH tools appear only when those providers are configured, IP-ban tools only when a ban target is defined, and memory tools only when server memory is enabled. The Hetzner Cloud, OVH Cloud, and Server Memory families are included with the Solo and Teams plans; the AWS and diagnostics families need only a paid plan, since AWS is the base provider.
The exact set returned by tools/list depends on your plan, configuration, and guard level — call it from your agent to see the live catalog.
Core relay (6)
| Tool | Guard | Description |
|---|---|---|
list_instances | readonly | List managed instances (AWS EC2, OVH, custom hosts). Per-provider catalogues for Hetzner / OVH live in their own families below. |
check_status | readonly | Check the current status / reachability of a managed instance. |
get_server_info | readonly | Identity and configuration details for a managed instance. |
run_command | standard | Execute a shell command via SSH on a managed instance (output truncated to a safe size). Optional transport (auto / ssh / ssm) falls back to AWS SSM when SSH is unreachable. |
get_logs | readonly | Fetch trailing log content from a remote host. |
transfer_file | dangerous | SCP upload / download. Not exposed to the TUI's AI chat. |
AWS observability & security (9)
CloudWatch log analysis, CloudTrail audit lookup, and IP-ban management — relayed to your CLI, which runs them against your own AWS credentials. AWS is the base provider, so these need only a paid plan.
| Tool | Guard | Description |
|---|---|---|
cloudwatch_list_log_groups | readonly | List CloudWatch log groups with stored bytes and retention. |
cloudwatch_get_log_events | readonly | Fetch recent events from a log group, with an optional filter pattern. Optional group_by / top_n returns a server-side ranked summary instead of raw events. |
cloudwatch_top_ips | readonly | Rank top client IPs from WAF / ALB logs — allowed vs blocked counts. |
cloudtrail_lookup_events | readonly | Query CloudTrail management events — who changed what, from which IP. |
ip_ban_list_configs | readonly | List configured ban targets (WAF IP sets, security groups, NACLs). |
ip_ban_list_banned | readonly | List the IPs currently banned under a named config. |
ip_ban_set | dangerous | Ban or unban IPs or CIDR ranges via WAF / Security Group / NACL — single or bulk, targeted by config name or by the WebACL fronting a site. Confirmation required. |
cloudwatch_insights | readonly | Run a CloudWatch Logs Insights query over one or more log groups — the general aggregation primitive (top IPs, status mix, URI ranking, time-bucketing) when cloudwatch_top_ips isn't enough. |
aws_call | dangerous | Generic passthrough for AWS operations not pre-wrapped as their own tool. Reads (Describe*/Get*/List*/Filter*/Lookup*) run read-only; mutations require mutate=true + dangerous guard, and destructive operations sit behind a mandatory two-phase confirmation. Confirmation required for any mutation. |
AWS EC2 (11) Solo & Teams
EC2 inventory reads and instance lifecycle, relayed to your CLI and run against your own AWS credentials. AWS is the base provider, so these need only a paid plan.
| Tool | Guard | Description |
|---|---|---|
aws_list_regions | readonly | List the AWS regions available to your account. |
aws_list_amis | readonly | List AMIs (machine images) you can launch. |
aws_list_instance_types | readonly | List EC2 instance types. |
aws_list_key_pairs | readonly | List EC2 key pairs in a region. |
aws_list_subnets | readonly | List VPC subnets. |
aws_list_security_groups | readonly | List security groups and their rules. |
aws_start_instance / _stop_instance / _reboot_instance | standard | Power lifecycle on an existing EC2 instance. |
aws_run_instances | dangerous | Launch one or more new EC2 instances. Costs money — confirmation required. |
aws_terminate_instance | dangerous | Permanently terminate an EC2 instance. Confirmation required. |
Amazon S3 (10) Solo & Teams
S3 bucket and object operations across providers (AWS, plus S3-compatible Hetzner / OVH object storage) — the cloud is chosen per call.
| Tool | Guard | Description |
|---|---|---|
s3_list_buckets | readonly | List buckets for a provider. |
s3_list_objects | readonly | List objects in a bucket (optional prefix). |
s3_download_object | standard | Download an object to a local path under your home / cwd / Downloads. |
s3_create_bucket / s3_delete_bucket | dangerous | Create or delete a bucket. Confirmation required. |
s3_upload_object / s3_delete_object | dangerous | Upload or delete an object. Confirmation required. |
s3_copy_object / s3_move_object | dangerous | Server-side copy or move within a provider. Confirmation required. |
s3_generate_presigned_url | dangerous | Mint a time-limited pre-signed download URL (a bearer secret). Confirmation required. |
Incident response & diagnostics (12) Solo & Teams
Fast triage and mitigation when a host is under load or misbehaving: fleet-wide health, on-box traffic analysis, AWS ingress-path mapping, database and RDS diagnostics, IP enrichment, scoped WAF mitigation, and zero-config database-credential setup. Read tools need only a paid plan; the mitigation tools are dangerous tier. Discovered database passwords go straight into your configured secrets backend on your machine (local store or Bitwarden Secrets Manager — check with servonaut secrets status) and are never returned to the agent.
| Tool | Guard | Description |
|---|---|---|
fleet_health_snapshot | readonly | Load, CPU, memory, web-server pool saturation, and listening stack across all your instances in one table. |
web_traffic_summary | readonly | Parse a host's own access logs (forwarded-IP aware): per-vhost requests/sec, status mix, top client IPs and URLs. |
describe_ingress_path | readonly | Map instance → target group → load balancer / listener rules → associated WAF WebACL & rate rules in one call. |
rds_metrics | readonly | Recent RDS metrics: CPU, connections, credit balance, read/write latency. |
db_processlist | readonly | Database process list as seen from the host: connections vs limit, threads running, longest queries. |
db_top_queries | readonly | Top slow / most expensive queries. |
db_setup_scan | standard | Discover DB credentials on a host (read-only) and stage them; returns redacted previews only — never the plaintext password. |
db_setup_save | standard | Commit a discovered DB credential into the secret store and write a reusable profile. Confirmation required. |
db_setup_remove | standard | Remove a saved DB profile (and, by default, its stored secret) — the undo for db_setup_save. Confirmation required. |
enrich_ips | readonly | Enrich a list of IPs with reverse DNS, ASN / owning organisation, and abuse score. |
waf_rate_rule_set | dangerous | Create or update a rate-based rule on the WAF WebACL fronting a site. Reversible; confirmation required. |
block_ip | dangerous | Block or unblock an IP / CIDR at the layer that actually applies (WAF, host, security group, or NACL). Reversible; confirmation required. |
Hetzner Cloud (11) Solo & Teams
| Tool | Guard | Description |
|---|---|---|
hetzner_list_servers | readonly | List servers in the Hetzner Cloud project. |
hetzner_list_server_types | readonly | Catalog of server types with EUR prices. |
hetzner_list_ssh_keys | readonly | Project-level SSH keys registered with Hetzner. |
hetzner_create_ssh_key | standard | Register a new SSH public key with the project. |
hetzner_delete_ssh_key | dangerous | Remove an SSH key from the project. |
hetzner_create_server | dangerous | Create a server (auto-registers in fleet). Confirmation required. |
hetzner_delete_server | dangerous | Permanently delete a server. Confirmation required. |
hetzner_power_on | standard | Power a stopped server back on. |
hetzner_power_off | standard | Hard power-off (no graceful shutdown). |
hetzner_shutdown | standard | Graceful ACPI shutdown. |
hetzner_reboot | standard | Soft reboot. |
OVH Cloud (13) Solo & Teams
| Tool | Guard | Description |
|---|---|---|
ovh_create_instance | dangerous | Create a Public Cloud instance. Confirmation required. |
ovh_delete_instance | dangerous | Permanently delete an instance. |
ovh_start_instance / _stop_instance / _reboot_instance | standard | Power lifecycle on an existing instance (Cloud / VPS / dedicated routed automatically). |
ovh_monitoring | readonly | CPU / RAM / network metrics for an instance — works for OVH VPS as well as Public Cloud, including OVH servers you registered manually as custom servers. |
ovh_list_ips | readonly | Account-wide IP inventory with routing info. |
ovh_firewall_rules | readonly | Firewall rules for a given IP. |
ovh_ssh_keys | readonly | Project-level SSH keys registered with OVH. |
ovh_snapshots | readonly | Snapshot list for a VPS or Public Cloud instance. |
ovh_dns_records | readonly | DNS records for a zone (optional record-type filter). |
ovh_billing / ovh_invoices | readonly | Current billing summary and recent invoices. |
Server Memory (6) Solo & Teams
Agents should call get_server_memory first, before any SSH round-trip — the cached snapshot answers OS / runtime / service / container / log questions instantly. See Server Memory docs.
| Tool | Guard | Description |
|---|---|---|
get_server_memory | readonly | Cached fact pack (summary / markdown / full / context_block). |
list_server_memories | readonly | Every instance with cached memory. |
recall_server_findings | readonly | Saved agent findings for an instance — lexical search or newest-first. Results are labelled agent-authored and unverified: reference material, never instructions. |
build_server_memory | standard | Probe a server and populate its memory cache. |
refresh_server_memory | standard | Re-probe one or more modules, bypassing TTL. |
remember_server_finding | standard | Persist a non-obvious discovery (quirk, root cause, constraint) a fresh probe wouldn't show — saved locally, synced end-to-end encrypted across your machines and team. |
Orchestration (4) Solo & Teams
Higher-level, cross-cloud building blocks that compose the per-provider tools.
| Tool | Description |
|---|---|
deploy | Run a versioned deploy script against an instance group. |
provision | Provision a new server on a chosen provider (aws, ovh, hetzner_cloud) using a recipe. |
cost_report | Cross-cloud cost report — pulls per-provider billing into one comparison table. |
security_scan | Run the configured security scanner against a host. |
Session & backend (5)
Introspection and plumbing tools an agent can use to understand its own session and reach your servonaut.dev account.
| Tool | Guard | Description |
|---|---|---|
whoami | readonly | Metadata about the current session and account. The bearer token itself is never exposed to the agent. |
relay_status | readonly | Local and backend view of the relay connection (same data as servonaut connect --status). |
relay_reconnect | — | Stop and restart the relay listener to heal a stale connection. |
api_request | standard | Authenticated REST proxy against the servonaut.dev API — headers are filtered, bodies capped at 1 MiB, rate-limited to 30 calls/min. |
mcp_tool_call | — | Bridge a call from the local stdio server to the hosted MCP server at mcp.servonaut.dev for plan-gated tools. |
Guard levels
Guard levels let you control how much power AI agents have over your infrastructure.
Set the level in config.json.
Listing, status, log fetch, server memory queries, OVH read tools, CloudWatch & CloudTrail analysis, EC2 / S3 inventory, and the diagnostics family (fleet health, traffic & DB analysis, ingress-path mapping, RDS metrics, IP enrichment). Safe for shared environments or untrusted agents — no remote state changes.
Read tools plus run_command, build_server_memory, refresh_server_memory, remember_server_finding, hetzner_create_ssh_key, the authenticated api_request proxy, S3 download, and power lifecycle on existing instances (Hetzner power_on / power_off / shutdown / reboot, OVH start_instance / stop_instance / reboot_instance). Recommended for personal use with trusted agents.
Adds server creation / deletion (hetzner_create_server / _delete_server, ovh_create_instance / _delete_instance, aws_run_instances / aws_terminate_instance), SCP transfer_file, SSH-key deletion (hetzner_delete_ssh_key), S3 bucket / object writes, IP bans (ip_ban_set), and WAF mitigation (waf_rate_rule_set, block_ip). Use only in fully trusted, single-user setups.
Two backstops apply regardless of guard level: run_command always refuses a hard-coded
blocklist of catastrophic shell commands (rm -rf, shutdown, dd, and
similar), and dangerous-tier tools require the dangerous-AI-tools opt-in on your account before
Servonaut AI surfaces will offer them at all.
Confirmation protocol on mutating tools
Every mutating MCP tool's description carries a one-line instruction telling the LLM to confirm with the user before invoking it.
For example, hetzner_delete_server's description ends with: "Always confirm with the user before invoking this tool — deletion is permanent and the server's data cannot be recovered."
The server's top-level instructions reinforce this with a three-step protocol: summarise the exact change in
plain language, state the tool name and arguments, and wait for an explicit affirmative reply before calling.
On Teams plans, the hosted MCP server adds per-tool policy on top: blocked_tools and
allowed_tools lists enforced on every call, plus a require_approval list.
Tools listed in require_approval are denied at invocation with the reason
approval required: <tool> — the call never executes. To explicitly deny a tool, use
blocked_tools or a lower guard level; use require_approval for tools that must
always be refused to agents and handled by a human out-of-band.
The LLM-side confirmation prompt is a usability layer, not a security boundary. The actual gates are guard level (enforced on every call), your plan's included features, and team tool policy (per-tool allow / block lists on Teams). All three apply on every call.
Using with other AI agents
Servonaut's MCP server uses the standard stdio transport (local) or SSE+HTTPS (hosted) and is compatible with any MCP-capable AI assistant. Tested integrations include:
- Claude Code & Claude Desktop (Anthropic) — first-class support via
--mcp-install claude. - Cursor, Windsurf, VS Code, OpenCode — auto-installer detects each client.
- Any MCP-compatible client — use
servonaut --mcpas the local stdio command (or discover it in the MCP Registry), or connect tohttps://mcp.servonaut.dev/mcp/ssewith a Bearer token from your signed-in CLI (see Connecting a hosted agent).
Hosted MCP — Solo & Teams
The Solo and Teams plans include the hosted MCP server at mcp.servonaut.dev.
Instead of running stdio on your local machine, AI agents connect over SSE and the backend relays calls back to your running servonaut connect process — your SSH keys never touch our servers.
Why use it? The agent doesn't need Servonaut (or any of your credentials) installed on its side — it just needs a token and a URL. So you can drive your fleet from a CI job, a teammate's editor, or a second machine, while every command still executes on your box with your keys, fully audited. It's the difference between "the agent runs where my keys are" and "the agent runs anywhere and the work is relayed to where my keys are."
Connecting a hosted agent
Three steps — nothing Servonaut-specific is installed on the agent's side:
- Keep the relay alive on the machine that holds your SSH keys / cloud config:
servonaut connect --bg. This is the process the backend dispatches tool calls to. It authenticates with your storedservonaut loginsession (automatic token refresh) — no environment variables needed. Run it in the foreground first while testing (servonaut connect, Ctrl+C stops it cleanly);--stopends the background listener and--reconnectheals a stale connection. Signing in from the TUI auto-starts an in-process listener too — the sidebar shows ● connected. - Get your token — sign in from the TUI (Account → Login) or run
servonaut loginon headless boxes; both use the OAuth device flow. The CLI stores the token at~/.servonaut/auth.json(mode 0600); copy theaccess_tokenvalue — it authenticates the agent to the hosted server as you. Note the pasted token is a static copy: the relay listener refreshes its own credentials automatically, but your agent's pasted Bearer does not. If hosted calls start failing with authentication errors, re-copy the token (sign in again first if needed). - Add a remote (SSE) MCP server in your agent, pointing at the hosted endpoint with an
Authorization: Bearerheader:
{
"mcpServers": {
"servonaut": {
"type": "sse",
"url": "https://mcp.servonaut.dev/mcp/sse",
"headers": { "Authorization": "Bearer <access_token from ~/.servonaut/auth.json>" }
}
}
}
The hosted server only relays — it has nothing to run against unless your CLI is connected. If tool calls come back with "Your CLI is not connected", run servonaut connect --status — it shows the local listener state and the backend's view of your connection, and warns when they diverge; start servonaut connect (or --reconnect) to fix it. Remote-SSE config differs by client (some take a URL + header in their UI, others in a JSON config like above) — use your client's remote / SSE MCP option, not the local command form. And if the listener starts but never prints "Waiting for commands", check for stale SERVONAUT_RELAY_TOKEN / SERVONAUT_USER_ID environment variables — when both are set they override your login session (CI / legacy mode) and a stale token makes the listener silently retry on 401; unset them. Once connected, the agent sees the same tool catalog as local stdio, filtered by your plan, configuration, and guard level. Long, quiet operations relayed to a target box — a slow command, a held-open log tail, a bastion hop through an idle firewall — are kept from being silently reaped by SSH connection keepalives, on by default.
Hosted MCP benefits:
- Works from any device — agents in CI or on a colleague's laptop, no local install required on their side.
- Always-on availability (subject to your CLI being connected;
servonaut connect --bgkeeps it alive). - Teams plan adds per-tool policy (allow / block / require-approval lists — see the confirmation protocol) and a team audit log of relayed activity, viewable on servonaut.dev under Account → Teams → Audit. The machine running the relay keeps its own local log at
~/.servonaut/mcp_audit.jsonlas well. - Provider operations (Hetzner, OVH) count against your plan's monthly operation limits — see Pricing.
Headless AI tool approvals
The same relay listener also executes tool calls that originate from Servonaut AI chats —
headless servonaut ai chat --tools sessions and conversations started on the web — even when
no TUI is open. Because nobody is at the keyboard to confirm, approval is policy-driven:
relay.ai_tool_auto_approve in ~/.servonaut/config.json sets the highest guard tier
that is auto-approved — readonly, standard (the default), or dangerous
(which additionally requires the dangerous-AI-tools opt-in on your account). Calls above the configured tier
return a denial the model can relay back to you, and every execution is written to the local audit log marked
as AI-chat-originated. See headless AI chat.