MCP server for Krova Cloud — let Claude, Cursor, and any MCP client provision and manage Cubes (Firecracker microVMs).
Krova MCP exhibits strong naming conventions and comprehensive parameter schemas across all 27 tools. Tool names uniformly follow verb_noun patterns (list_cubes, create_cube, delete_cube, etc.) with clear action semantics. All tools have descriptions between 34 - 256 characters, meeting the baseline (avg 194 chars). Input schemas are present and well-structured with type declarations, min/max constraints, and enum support. However, output schemas are not documented in the provided code, a significant gap for tools like create_cube, list_domains, and get_cube_ssh where response structure is critical for downstream chaining. Error handling descriptions are minimal; tools provide operational context (e.g., 'async', 'destructive', 'disk preserved') but lack explicit recovery guidance ('If snapshot fails, try power_off first'). The toolAnnotations feature is enabled, providing destructive/readonly hints, but composition could be stronger, several tools are domain-specific rather than universally reusable. Parameter naming is consistent (spaceId, cubeId, domainId patterns) but lacks type suffixes on ambiguous fields (e.g., port appears in both cubePort and publicPort contexts without clarifying direction).
Create (provision) a new Cube in a Space. Provisioning is asynchronous — the returned Cube begins in a pending state. Destructive/billable: creating a Cube starts hourly billing.
Attach a custom domain to a Cube. The domain must be delegated to Krova's nameservers or have its records configured manually (see the returned records). Asynchronous: DNS propagation is instant once records are published.
Create a TCP port mapping: a public port (on the Cube's public IP) routed to an in-Cube port.
Register an outbound webhook endpoint that Krova Cloud will POST Cube events to (e.g., when a Cube starts, stops, fails to start, or is deleted).
Delete a Cube — permanently; its disk is destroyed. Destructive: once sent, it cannot be undone. The Cube must not have terminationProtection enabled (see protect_cube and unprotect_cube).
Output schemas not documented in source. Tools like create_cube, restore_snapshot, list_cubes return complex objects (Cube, Snapshot, Domain structures with nested fields), but response schema is not visible in the provided code. LLMs cannot plan downstream tool calls without knowing what fields are returned.
Error handling lacks recovery guidance. Descriptions mention async operations and destructive actions, but do not explain what error states are possible or what the agent should do next. E.g., create_cube is async, what if polling times out? Should the agent call get_cube? Call describe_events?
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 70 | 2026-07-28+ | v2 |
Detach a custom domain from a Cube. The domain's traffic stops being routed to this Cube (asynchronous: may take a moment to propagate).
Delete a snapshot (asynchronous). Destructive: once sent, it cannot be undone.
Delete a TCP port mapping — the public port is no longer routed to the in-Cube port.
Unregister an outbound webhook endpoint — it will no longer receive Cube events.
Get details for a single Cube by id.
Everything needed to SSH into a Cube: host, port, the login USER, and any pinned host keys. Call this rather than guessing a username — it is `ubuntu` or `debian` on Cubes created from images that ship a default user, and `root` on older Cubes, so it cannot be derived from the image id. The returned user has passwordless sudo; `sudo su` reaches root.
List all Cubes (Firecracker microVMs) in a Krova Cloud Space.
List all custom domains attached to a Cube.
List available OS images.
Show per-resource hourly pricing for Cubes (VCPUs, RAM, disk) and snapshots.
List regions with available capacity (may be empty if demand is very high).
List all snapshots in a Cube.
List all TCP port mappings for a Cube (ports exposed to the public internet and routed to in-Cube ports).
List all outbound webhook endpoints configured in a Space.
Power off a running Cube (asynchronous). Compute + host RAM are released while disk is preserved; the Cube becomes stopped.
Enable termination protection on a Cube — delete_cube is rejected until you call unprotect_cube. Idempotent: protecting an already-protected Cube is a no-op.
Restart a Cube (cold restart — the Cube boots from disk, picking up a refreshed kernel). Data is preserved. Asynchronous: the returned Cube begins in a restarting state.
Restore a snapshot to a Cube (asynchronous). The Cube must be stopped. The Cube's disk is replaced with a copy of the snapshot.
Create a snapshot of a Cube's disk (asynchronous). The Cube must be stopped.
Disable termination protection on a Cube — delete_cube is now allowed. Idempotent: unprotecting an already-unprotected Cube is a no-op.
Update a custom domain's configuration.
Start a stopped Cube (asynchronous).
Sparse descriptions on discovery tools. list_regions, list_images, list_pricing have descriptions under 20 chars: 'List regions...', 'List available OS images.', 'Show per-resource hourly pricing...'. These do not explain WHEN to call them or what the LLM should do with the returned data.
Optional spaceId parameter design. spaceId is optional 'if KROVA_SPACE_ID is set as the server default', but this pattern relies on server initialization state, not per-request self-containment. The current MCP spec (2026-07-28) emphasizes stateless request handling; server defaults create implicit dependencies.
No batch operations or pagination documented. list_cubes, list_snapshots, list_domains, list_tcp_mappings, list_webhooks accept no limit/offset/cursor parameters. If a Space has hundreds of resources, the agent cannot paginate results, risking context window exhaustion.