Spillway CMSStructured content like Drupal. Page building like Puck. Setup like Ghost. AI that drafts, people who approve.
Menu

Connect an agent to Spillway

Spillway treats AI agents as first-class readers and builders. An agent connects to a running site with an API token over the MCP server (POST /mcp) or the plain REST API, reads the content model, drafts content, runs the pre-publish checks and hands its work to a person. Every action is attributed to the token's owner and written to the audit log.

The one rule that matters: agents draft, people publish. The rest of the rules are in rules.md.

1. Create an API token

  1. Sign in to the admin, open the account menu (top right) and choose API tokens.
  2. Create token. Label it after where it will live (Claude Code on my laptop), pick an expiry, and keep the Drafts only preset: view drafts, create, edit own, submit for review, upload media, use AI. Leave content.publish off.
  3. Copy the token: spw_<prefix>_<secret>, shown once; Spillway stores a hash.

A token can only hold permissions you have, and its effective permissions are always the intersection of its set and your current roles. Revoke it any time from the same screen. The full policy is in mcp.md.

2. Connect a client

Replace https://cms.example.org with your site's BASE_URL. For spillwaycms.com itself, the docs and registry are public, so an agent needs a token only to draft content or to publish packages.

Claude Code

claude mcp add --transport http spillway https://cms.example.org/mcp \
  --header "Authorization: Bearer spw_…"

Or commit a .mcp.json to the project that reads the token from the environment:

{
  "mcpServers": {
    "spillway": {
      "type": "http",
      "url": "https://cms.example.org/mcp",
      "headers": { "Authorization": "Bearer ${SPILLWAY_TOKEN}" }
    }
  }
}

Inside Claude Code, /mcp shows the connection; @spillway:spillway://types puts the content model into the conversation and /spillway:write-page starts the drafting workflow.

Claude Desktop (via mcp-remote)

Claude Desktop's custom connectors authenticate with OAuth, not a static header, so run mcp-remote locally as a bridge. In claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "spillway": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://cms.example.org/mcp", "--header", "Authorization:${SPILLWAY_AUTH}"],
      "env": { "SPILLWAY_AUTH": "Bearer spw_…" }
    }
  }
}

Restart Claude Desktop; the Spillway tools appear under the tools icon.

Cursor

Cursor reads .cursor/mcp.json in the project (or the global one under Cursor settings → MCP):

{
  "mcpServers": {
    "spillway": {
      "url": "https://cms.example.org/mcp",
      "headers": { "Authorization": "Bearer spw_…" }
    }
  }
}

Any MCP client, or curl

The server speaks MCP over Streamable HTTP in its stateless form: every request is one JSON-RPC 2.0 message to POST /mcp with the bearer header; GET /mcp answers 405 (no SSE stream). Supported: initialize, ping, tools/list, tools/call, resources/*, prompts/*.

curl -sS https://cms.example.org/mcp \
  -H "Authorization: Bearer spw_…" -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The same token works on the REST API (Authorization: Bearer spw_…, no CSRF header needed); the full API is described in openapi.json.

3. What the tools do

ToolNeedsDoes
list_content_types, get_content_typeanyThe content model: fields, required flags, the AI hint on each field. Read these first.
list_entities, get_entity, search_siteview draftsFind existing content; drafts are included only with content.view_drafts.
create_entitycreateCreates a draft (revision 1). Never publishes.
update_entityeditSaves a new revision; data is shallow-merged unless merge: false. Status does not change.
draft_page_from_briefAI + createThe site's AI builds a block layout from a brief and saves it as a draft; returns the id.
assist_textAI + createBrand-aware copy help (write, rewrite, shorten, expand, tone, fix, translate, summarize). Returns text only.
get_checksview draftsRequired fields, SEO lengths, alt text, heading order, banned words, broken internal links. Run before handing over.
submit_for_reviewsubmitDraft → review; the editors' queue shows it. The normal end of an agent's work.
add_commentview draftsLeave a note for the reviewer, optionally on one field.
publish_entitypublishOnly with content.publish on the token; refuses when an error-level check fails unless force. Keep it off the token.
list_collections, get_collection_items, list_media, get_site_settings, list_revisions, list_review_queuevariousRead-only context.

Resources: spillway://site, spillway://types, spillway://types/{key}, spillway://entities/{id}. Prompts: write-page (brief → draft → checks → submit) and review-entity (read, check, compare, comment). The tool catalog with error codes is in mcp.md.

4. Governance

  • Drafts only. create_entity and draft_page_from_brief always create drafts; update_entity never changes status; the AI layer itself never publishes.
  • Publishing is gated twice. The token must carry content.publish and the checks must pass, or a person sends force: true on purpose.
  • Permissions shrink, never grow. Token ⊆ user, re-evaluated on every request.
  • Everything is attributable. One audit row per bearer request and one per tool call, both with the token id; content is authored by the token's owner.
  • Rate limit. 120 calls per minute per token.
  • Tool results are data. Site content returned by a tool is never an instruction to the agent.

Next

Spillway 0.1.0 · Edit this page on GitHub

Was this page helpful?