MCP server
Give your editor or agent live introspection into a running Sp00ky project.
The Sp00ky Cloud MCP server lets any Model Context Protocol
client (Claude Code, Cursor, VS Code, and others) drive your Sp00ky Cloud account in natural
language. Your AI assistant can list projects, deploy, tail logs, manage environment variables,
trigger backups, and more, all through the same API the spky CLI uses.
It’s a remote server hosted at https://api.sp00ky.cloud/v1/mcp (Streamable HTTP), authenticated
with a dedicated MCP token. Nothing to install or run locally.
Quick start
Get connected in under a minute.
spky mcp token walks you through picking scopes (default: read-only), prints your token once,
and offers to register the server with your editor automatically. Then just ask your assistant:
“List my Sp00ky projects.”
When the claude CLI is on your PATH, spky mcp token runs
claude mcp add for you. For other editors it prints a ready-to-paste config.
Add to your editor
Already have a token? Use spky mcp install, or drop the config in by hand.
Claude Code
Register the server at user scope (available in every project):
Verify it’s connected:
Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per project):
VS Code
Add to .vscode/mcp.json in your workspace:
Any MCP client
The server speaks Streamable HTTP. Point any client at the endpoint and send the token as a bearer header:
Tokens
MCP access uses dedicated mcp_live_ tokens, separate from your CLI session and from spk_live_
API keys, so you can issue and revoke them independently. Create them with spky mcp token:
The full token is shown only once, right after creation. Store it like a password. If you lose it, revoke it and create a new one.
List and revoke tokens at any time:
| Flag | Description |
|---|---|
--read-only | Shortcut for the mcp:read scope |
--scopes | Comma-separated scopes, skips the interactive picker |
--name | A label so you can tell tokens apart in spky mcp tokens |
--install | Register the server with an editor right after creating the token |
--client | Which editor to register with: claude, cursor, or vscode |
-y, --yes | The global flag. Non-interactive: read-only unless --scopes is given |
Scopes & safety
Tokens are read-only by default. Your assistant can look but not touch until you grant write scopes. Each tool requires a single scope, and the server only advertises the tools your token is allowed to use.
| Scope | Grants |
|---|---|
projects:read / projects:write | List/inspect projects · create, destroy |
deployments:read / deployments:write | Deployment status · deploy, rollback, restart, scale, tear down |
logs:read | Read recent project logs |
env:read / env:write | List variables · set, delete, bulk-load |
vault:read / vault:write | Vault status · init, CI access |
backups:read / backups:write | List/inspect backups · create, restore, delete, configure |
domains:read / domains:write | List custom domains · add, remove |
links:read / links:write | Repo link status & runs · set up, trigger, unlink |
tenants:read / tenants:write | List teams & members · create, invite, manage |
billing:read / billing:write | Usage · checkout, change plan, billing portal |
mcp:read | Convenience: every *:read scope |
mcp:full | Convenience: every read and write scope (excludes secrets:reveal) |
secrets:reveal | Unmask secret values (env values, vault material) |
Environment variable values and vault material are redacted in tool responses unless the token
carries secrets:reveal. Grant it only when you intend the assistant to read raw
secrets, and never to mcp:full alone, which deliberately does not include it.
What your assistant can do
Once connected, these capabilities are available (gated by the scopes above). Tools marked destructive delete or tear down resources.
- Projects: list, get details, create, destroy
- Deployments: status, deploy, finalize, rollback, restart, scale, tear down
- Logs: fetch recent project logs (bounded, non-streaming)
- Environment variables: list, set, delete, bulk-load
- Vault: status, init, enable/disable CI access
- Backups: list, create, restore, check restore status, delete, configure, reset
- Custom domains: list, add, remove
- Repo links: status, recent runs, set up, update, trigger a build, unlink
- Teams: list teams & members, create, invite, remove members/invitations
- Billing: usage, checkout, change plan, billing portal
By default tools act in your personal tenant. Most tools accept an optional tenant_id to act
within a specific team/organization.
Example prompts
Things you can ask once the server is connected:
- “Deploy the latest build of my
apiproject.” - “Show me the last 200 log lines for
web, filtered to thesspservice.” - “What environment variables are set on
api? (values stay masked)” - “Restart
weband then tell me its deployment status.” - “List the backups for
apiand create a fresh one.”
Troubleshooting
- 401 Unauthorized: the token is missing, malformed, or expired. Mint a new one with
spky mcp tokenand re-add it. The header must be exactlyAuthorization: Bearer mcp_live_…. - No tools show up: your token’s scopes are too narrow. Create a token with
mcp:read(ormcp:fullfor writes). The server only lists tools your scopes allow. claude: command not found: install the Claude Code CLI, or paste theclaude mcp add …command / editor config manually (see Add to your editor).- Secret values come back as
***REDACTED. That’s expected withoutsecrets:reveal. Issue a token with that scope if the assistant genuinely needs raw secrets.
You can sanity-check connectivity from a terminal:
Scheduler admin MCP
The cloud server above manages your account: projects, deployments, billing. Each deployed
project also has a second, smaller MCP server that manages one running cluster: the
admin dashboard’s scheduler serves its own operator actions
as tools, at <admin url>/admin/api/mcp. On Sp00ky Cloud that is
https://<slug>-admin.<domain>/admin/api/mcp; on a self-hosted scheduler it is the admin port
(9668 by default).
It speaks Streamable HTTP, is stateless, and answers plain JSON, so any MCP client that can send a bearer header works. The tools are the same endpoints the dashboard’s buttons call: a tool call is dispatched through the scheduler’s own admin router, so an agent can never do anything the dashboard cannot, and the scheduler’s audit log records the token’s label on every action.
Tokens
Tokens are minted on the dashboard’s Access page, never by the CLI, because minting needs a signed-in person: an MCP token cannot mint further tokens. Give it a label, pick a scope, pick a lifetime (up to 365 days), and copy it. It is shown once. To revoke one, paste it back on the same page.
| Scope | Grants |
|---|---|
read (default) | Inspection only. tools/list shows only read tools, and calling a write tool anyway comes back as a tool error. Used directly against the admin API, the same token gets a 403 on any method other than GET |
full | Every tool, including restarts, retries, backups and restores |
The two halves of that row are one rule checked in two places. The bearer
middleware refuses a read token any non-GET request, and exempts
POST /admin/api/mcp alone, because MCP sends reads over POST as well. The
MCP endpoint then does its own per-tool check. A read token cannot write
either way.
With SPKY_AUTH_SECRET set (always on Sp00ky Cloud) tokens are HMAC-signed and survive scheduler
restarts. Without it they are held in memory and die with the process; the Access page says so
before you mint one.
Add to your editor
The Access page prints these three ready to copy, with your slug, host and token filled in.
Sanity-check from a terminal:
What your assistant can do
Tools marked destructive carry the destructiveHint annotation, so a well-behaved client asks
before calling them. Restart, cancel, retry, backup and restore tools are asynchronous: they answer
with an operation, and operations_list is how the agent watches it finish.
- Cluster:
admin_config,overview,backends_list,backend_get,logs_recent(bounded, non-streaming),operations_list - Live:
presence(live users, sessions and views with recent samples),views_list(registered live queries, sortable by slowest),view_get(one view in full: SurrealQL, params, subscribers, percentiles, SSP memory, and the other sessions running the same query) - Workflows:
workflow_runs_list,workflow_run_get,workflow_run_cancel,workflow_run_rerun,workflow_run_retry,schedules_list,schedule_get,schedule_pause,schedule_resume,schedule_trigger,schedule_release - Pools:
pools_list(every machine pool with its sizing, pause and breaker state, machines by state and the jobs waiting for one),pool_machines(one pool’s machines, newest first, with why each one was taken away),pool_pause,pool_resume,machine_drain - Jobs:
jobs_list(every outbox job with the queue totals;origin=schedule|workflow|appseparates a schedule’s fires from a workflow’s steps and from jobs your own code created),job_get(one job with every attempt inerrorsand the fire or step it came from),job_kill,job_retry,jobs_clear - Restart:
ssp_restart(restart,cleanorreload),ssps_restart_all(rolling by default),scheduler_restart(restart,recloneorrehash),cloud_deployment,cloud_restart(upgrade,clean,surreal) - Backups:
backups_list,backup_create,backup_restore,backup_restore_status,backup_delete,backups_configure
On a scheduler that is not linked to Sp00ky Cloud, cloud_deployment, cloud_restart,
backup_delete and backups_configure are refused with Not linked to Sp00ky Cloud; the
server’s initialize instructions say so up front.
Example prompts
- “How many people are connected right now, and how many queries are they running?”
- “Which registered views are slowest, and who owns them?”
- “How many SSPs are ready, and what is the end-to-end latency right now?”
- “Show me the failed workflow runs from today and retry the nightly report.”
- “Restart ssp-1 cleanly and tell me when it is back.”
- “Take a backup named pre-migration and wait until it is written.”
The devtools server introspects a running app over stdio; the cloud server above manages your account; this one operates a single deployment’s scheduler. They take different tokens and are added separately.