Integrations

MCP Server

The official Otwa Cloud Model Context Protocol server lets your AI assistant deploy, manage, and destroy cloud servers on your behalf — straight from a chat prompt. 30 tools, scope-aware authorization, three-layer safety on anything destructive.

Scoped keys
Idempotent
No install (hosted)
stdio fallback

Quick start

The easiest path is the hosted endpoint — no install, no Node runtime, just a Bearer key on every request. The setup wizard in your dashboard generates per-client snippets, but here's the two-step version:

  1. 1

    Create an API key with MCP scopes

    Go to Dashboard → API Access → Connect AI and click Generate MCP key. This creates a key with the recommended scopes (account:read,servers:read,servers:write,billing:read).

    servers:destroy is off by default — the AI should never be one prompt away from terminating your VM. Enable it explicitly in the key creation form only if you need it.

  2. 2

    Add the MCP server to your AI client

    For Claude Code:

    claude mcp add --transport http otwa "https://mcp.otwa.cloud/mcp" \
      --header "Authorization: Bearer YOUR_API_KEY"

    For Cursor — add to ~/.cursor/mcp.json:

    {
      "mcpServers": {
        "otwa": {
          "url": "https://mcp.otwa.cloud/mcp",
          "headers": { "Authorization": "Bearer YOUR_API_KEY" }
        }
      }
    }

    Snippets for Claude Desktop, Windsurf, VS Code, Zed, Continue, and OpenCode are generated in the dashboard.

Tool reference

30 tools across seven surfaces. The required scope on each tool is enforced server-side — a key without the scope gets a 403, the AI sees the error and tells you which scope is missing.

Account & catalogue

otwa_accountaccount:read

Current account, balance, tier.

otwa_list_productsaccount:read

Available plans with monthly prices and product IDs.

otwa_list_regionsaccount:read

Regions where new servers can be deployed.

otwa_list_os_templatesaccount:read

OS images for new servers and reinstalls.

Servers

otwa_list_serversservers:read

Every server on this account with status, region, primary IP.

otwa_get_serverservers:read

Full detail incl. specs, networking, OS.

otwa_get_server_credentialsservers:read

SSH credentials. The AI is instructed not to paste these into the chat.

otwa_get_server_statsservers:read

Live CPU / RAM / disk / network metrics from vSphere.

otwa_create_serverservers:write

Provision a new VM. Auto-generates Idempotency-Key so retries never double-bill.

otwa_rename_serverservers:write

Change the dashboard label. Cosmetic only.

otwa_power_serverservers:write

start | stop | reboot. confirm:true required for stop/reboot.

otwa_reset_server_passwordservers:write

Rotate root password via vSphere guest ops.

otwa_reinstall_serverservers:destroy

Wipe disk and rebuild from a new OS template. Requires confirm + iAcknowledgeDataLoss.

otwa_destroy_serverservers:destroy

Permanently terminate. Requires confirm + iAcknowledgeDataLoss + expectedLabel typo-guard.

otwa_list_snapshotsservers:read

List a server's point-in-time disk snapshots.

otwa_create_snapshotservers:write

Capture a disk snapshot as a restore point. Max 2 per server.

otwa_revert_snapshotservers:destroy

Roll the disk back to a snapshot. Requires confirm + iAcknowledgeDataLoss + expectedLabel typo-guard.

otwa_delete_snapshotservers:write

Remove a snapshot. Non-destructive to live data.

otwa_get_dashboard_ssoservers:read

5-minute SSO link to the dashboard — handoff to web UI when you need noVNC console.

Networking

otwa_list_server_ipsservers:read

Every IP attached to a server with PTR.

otwa_set_ptrservers:write

Set reverse DNS (PowerDNS-backed, propagates in seconds).

otwa_delete_ptrservers:write

Clear reverse DNS.

Billing

otwa_list_invoicesbilling:read

Paged invoice history.

otwa_get_invoicebilling:read

Single invoice with line items.

otwa_list_transactionsbilling:read

Top-ups, charges, refunds.

otwa_get_wallet_balancebilling:read

Crypto wallet addresses + balances. Read-only — does not create new addresses.

Webhooks

otwa_list_webhookswebhooks:read

Registered webhook subscriptions.

otwa_create_webhookwebhooks:write

Register a new webhook — secret returned once.

otwa_delete_webhookwebhooks:write

Permanently remove a webhook subscription.

Reseller

otwa_get_reseller_stateaccount:read

Reseller program state: tier, discount, rolling 30-day GMV, next-tier progression. Helps the AI answer 'how close am I to the next tier?'

Safety model

We assume the AI is well-intentioned but fallible, and we assume your key might be over-scoped or leak. Three independent layers of defence:

  1. 1
    Tool-side confirm flags. Destructive tools require confirm: true and iAcknowledgeDataLoss: true — the AI cannot fire-and-forget; the call surfaces in the model's reasoning.
  2. 2
    Typo-guard on destroy. otwa_destroy_server requires expectedLabel matching the server's current label. If labels differ — because the AI looked at the wrong server, or you renamed it mid-conversation — the call is rejected before reaching the API.
  3. 3
    Server-side scope enforcement. The servers:destroy scope is split from servers:write. A key without servers:destroy cannot terminate or reinstall — full stop, at the API. Tool guards can be bypassed by a misaligned model; this one can't.

otwa_create_server and otwa_reinstall_server also auto-attach a fresh Idempotency-Key on every retry, so transient network blips never produce two servers or charge twice.

OAuth 2.0 device-code flow

For AI clients that natively speak the MCP authorization spec — no key copy-paste, browser-approved access, revocable from the dashboard. Both Bearer API keys and OAuth tokens are accepted on the same endpoints — the choice is per-client.

Resource metadataGET https://mcp.otwa.cloud/.well-known/oauth-protected-resource
AS metadataGET https://api.otwa.cloud/.well-known/oauth-authorization-server
Access tokenopaque otwa_at_… 90-day TTL
Refresh tokenopaque otwa_rt_… 90-day TTL, single-use
Grant typesdevice_code · refresh_token
  1. 1
    Discovery. Spec-compliant client fetches the protected-resource metadata above, then the AS metadata. Both are public, no auth.
  2. 2
    Register. POST /api/oauth/register with {client_name, software_id, scope}. RFC 7591 Dynamic Client Registration — no auth, public clients only (no client secret).
  3. 3
    Device authorization. POST /api/oauth/device/code returns a user_code like XXXX-YYYY + verification_uri. Open the URI in a browser, sign in, approve the requested scopes.
  4. 4
    Token exchange. Poll POST /api/oauth/token at the returned interval. Returns authorization_pending until approved, then {access_token, expires_in, scope}. Use the access token inAuthorization: Bearer otwa_at_….
  5. 5
    Refresh proactively. When the access token nears expiry, exchange the refresh token at the same endpoint: grant_type=refresh_token. Returns a fresh access + refresh pair. The old refresh token is single-use — replaying it fails with invalid_grant.
  6. 6
    Revoke any time. User-facing list at Dashboard → API access → OAuth grants — one click revoke per token. RFC 7009 endpoint at POST /api/oauth/revoke accepts both access and refresh tokens.

Today most AI clients still expect a pasted Bearer key. Use OAuth if your client supports it; the dashboard's Connect AI wizard still ships per-client key-paste snippets, which work alongside OAuth on the same endpoint.

Local stdio (alternative)

If you'd rather not depend on mcp.otwa.cloud — offline work, auditable local execution, or air-gapped policy — install the npm package and let your AI client spawn it as a stdio child process:

npx -y @otwa/mcp-server

Same tool set, same safety guards. The only difference is the network path: stdio talks directly to api.otwa.cloud without going through us. Source is open and MIT-licensed on GitHub .

Ready to wire it up?

The dashboard generates per-client snippets pre-filled for you. Two clicks: generate key, copy snippet.

Open the setup wizard