Home / Docs / MCP Server

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.

Who this page is for

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 --mcp exposes the CLI's own tool surface to an agent running on the same machine.
  • Hosted (Solo & Teams) — agents connect to mcp.servonaut.dev over 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.
Example

"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.

bash
# Pick one client, or `all` to install into every detected client $ servonaut --mcp-install claude $ servonaut --mcp-install cursor $ servonaut --mcp-install all ✓ MCP server registered in Claude Code config Name: servonaut Transport: stdio Guard: standard
Dependency check

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:

bash
$ uvx --from 'servonaut[mcp]' servonaut --mcp

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.

bash
$ pipx install 'servonaut[mcp]' $ servonaut --mcp-install claude # or cursor, windsurf, opencode, vscode, all

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.json on Linux. The location differs on macOS and Windows — run servonaut --mcp-install vscode and it writes the correct file for your OS.

The MCP server block itself is the same in every file:

mcp server block
{
  "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)

ToolGuardDescription
list_instancesreadonlyList managed instances (AWS EC2, OVH, custom hosts). Per-provider catalogues for Hetzner / OVH live in their own families below.
check_statusreadonlyCheck the current status / reachability of a managed instance.
get_server_inforeadonlyIdentity and configuration details for a managed instance.
run_commandstandardExecute 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_logsreadonlyFetch trailing log content from a remote host.
transfer_filedangerousSCP 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.

ToolGuardDescription
cloudwatch_list_log_groupsreadonlyList CloudWatch log groups with stored bytes and retention.
cloudwatch_get_log_eventsreadonlyFetch 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_ipsreadonlyRank top client IPs from WAF / ALB logs — allowed vs blocked counts.
cloudtrail_lookup_eventsreadonlyQuery CloudTrail management events — who changed what, from which IP.
ip_ban_list_configsreadonlyList configured ban targets (WAF IP sets, security groups, NACLs).
ip_ban_list_bannedreadonlyList the IPs currently banned under a named config.
ip_ban_setdangerousBan 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_insightsreadonlyRun 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_calldangerousGeneric 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.

ToolGuardDescription
aws_list_regionsreadonlyList the AWS regions available to your account.
aws_list_amisreadonlyList AMIs (machine images) you can launch.
aws_list_instance_typesreadonlyList EC2 instance types.
aws_list_key_pairsreadonlyList EC2 key pairs in a region.
aws_list_subnetsreadonlyList VPC subnets.
aws_list_security_groupsreadonlyList security groups and their rules.
aws_start_instance / _stop_instance / _reboot_instancestandardPower lifecycle on an existing EC2 instance.
aws_run_instancesdangerousLaunch one or more new EC2 instances. Costs money — confirmation required.
aws_terminate_instancedangerousPermanently 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.

ToolGuardDescription
s3_list_bucketsreadonlyList buckets for a provider.
s3_list_objectsreadonlyList objects in a bucket (optional prefix).
s3_download_objectstandardDownload an object to a local path under your home / cwd / Downloads.
s3_create_bucket / s3_delete_bucketdangerousCreate or delete a bucket. Confirmation required.
s3_upload_object / s3_delete_objectdangerousUpload or delete an object. Confirmation required.
s3_copy_object / s3_move_objectdangerousServer-side copy or move within a provider. Confirmation required.
s3_generate_presigned_urldangerousMint 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.

ToolGuardDescription
fleet_health_snapshotreadonlyLoad, CPU, memory, web-server pool saturation, and listening stack across all your instances in one table.
web_traffic_summaryreadonlyParse a host's own access logs (forwarded-IP aware): per-vhost requests/sec, status mix, top client IPs and URLs.
describe_ingress_pathreadonlyMap instance → target group → load balancer / listener rules → associated WAF WebACL & rate rules in one call.
rds_metricsreadonlyRecent RDS metrics: CPU, connections, credit balance, read/write latency.
db_processlistreadonlyDatabase process list as seen from the host: connections vs limit, threads running, longest queries.
db_top_queriesreadonlyTop slow / most expensive queries.
db_setup_scanstandardDiscover DB credentials on a host (read-only) and stage them; returns redacted previews only — never the plaintext password.
db_setup_savestandardCommit a discovered DB credential into the secret store and write a reusable profile. Confirmation required.
db_setup_removestandardRemove a saved DB profile (and, by default, its stored secret) — the undo for db_setup_save. Confirmation required.
enrich_ipsreadonlyEnrich a list of IPs with reverse DNS, ASN / owning organisation, and abuse score.
waf_rate_rule_setdangerousCreate or update a rate-based rule on the WAF WebACL fronting a site. Reversible; confirmation required.
block_ipdangerousBlock 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

ToolGuardDescription
hetzner_list_serversreadonlyList servers in the Hetzner Cloud project.
hetzner_list_server_typesreadonlyCatalog of server types with EUR prices.
hetzner_list_ssh_keysreadonlyProject-level SSH keys registered with Hetzner.
hetzner_create_ssh_keystandardRegister a new SSH public key with the project.
hetzner_delete_ssh_keydangerousRemove an SSH key from the project.
hetzner_create_serverdangerousCreate a server (auto-registers in fleet). Confirmation required.
hetzner_delete_serverdangerousPermanently delete a server. Confirmation required.
hetzner_power_onstandardPower a stopped server back on.
hetzner_power_offstandardHard power-off (no graceful shutdown).
hetzner_shutdownstandardGraceful ACPI shutdown.
hetzner_rebootstandardSoft reboot.

OVH Cloud (13) Solo & Teams

ToolGuardDescription
ovh_create_instancedangerousCreate a Public Cloud instance. Confirmation required.
ovh_delete_instancedangerousPermanently delete an instance.
ovh_start_instance / _stop_instance / _reboot_instancestandardPower lifecycle on an existing instance (Cloud / VPS / dedicated routed automatically).
ovh_monitoringreadonlyCPU / 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_ipsreadonlyAccount-wide IP inventory with routing info.
ovh_firewall_rulesreadonlyFirewall rules for a given IP.
ovh_ssh_keysreadonlyProject-level SSH keys registered with OVH.
ovh_snapshotsreadonlySnapshot list for a VPS or Public Cloud instance.
ovh_dns_recordsreadonlyDNS records for a zone (optional record-type filter).
ovh_billing / ovh_invoicesreadonlyCurrent 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.

ToolGuardDescription
get_server_memoryreadonlyCached fact pack (summary / markdown / full / context_block).
list_server_memoriesreadonlyEvery instance with cached memory.
recall_server_findingsreadonlySaved agent findings for an instance — lexical search or newest-first. Results are labelled agent-authored and unverified: reference material, never instructions.
build_server_memorystandardProbe a server and populate its memory cache.
refresh_server_memorystandardRe-probe one or more modules, bypassing TTL.
remember_server_findingstandardPersist 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.

ToolDescription
deployRun a versioned deploy script against an instance group.
provisionProvision a new server on a chosen provider (aws, ovh, hetzner_cloud) using a recipe.
cost_reportCross-cloud cost report — pulls per-provider billing into one comparison table.
security_scanRun 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.

ToolGuardDescription
whoamireadonlyMetadata about the current session and account. The bearer token itself is never exposed to the agent.
relay_statusreadonlyLocal and backend view of the relay connection (same data as servonaut connect --status).
relay_reconnectStop and restart the relay listener to heal a stale connection.
api_requeststandardAuthenticated REST proxy against the servonaut.dev API — headers are filtered, bodies capped at 1 MiB, rate-limited to 30 calls/min.
mcp_tool_callBridge 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.

readonly

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.

standard (default)

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.

dangerous

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.

Defence in depth

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 --mcp as the local stdio command (or discover it in the MCP Registry), or connect to https://mcp.servonaut.dev/mcp/sse with 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:

  1. 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 stored servonaut login session (automatic token refresh) — no environment variables needed. Run it in the foreground first while testing (servonaut connect, Ctrl+C stops it cleanly); --stop ends the background listener and --reconnect heals a stale connection. Signing in from the TUI auto-starts an in-process listener too — the sidebar shows ● connected.
  2. Get your token — sign in from the TUI (Account → Login) or run servonaut login on headless boxes; both use the OAuth device flow. The CLI stores the token at ~/.servonaut/auth.json (mode 0600); copy the access_token value — 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).
  3. Add a remote (SSE) MCP server in your agent, pointing at the hosted endpoint with an Authorization: Bearer header:
hosted mcp server block
{
  "mcpServers": {
    "servonaut": {
      "type": "sse",
      "url": "https://mcp.servonaut.dev/mcp/sse",
      "headers": { "Authorization": "Bearer <access_token from ~/.servonaut/auth.json>" }
    }
  }
}
Three things that trip people up

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 --bg keeps 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.jsonl as 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.

Documentation