Documentation
How Bobby CMS works
Static product and integration documentation for the pilot. Endpoints and interfaces described as planned are not operational.
Headless model
Bobby CMS stores structured content and its publication state. It does not render pages, own templates or serve customer domains. Your website or application reads content and performs all rendering, routing, caching and hosting.
This boundary is a governance rule, not a current limitation: customer page hosting is a permanent non-goal.
Collections
A collection groups related pages and defines the shape they share — for example a documentation set, a set of product entries or an article series. Custom collection types are available to every workspace during the pilot and are not plan-gated.
Pages
A page is a structured record inside a collection: a stable identifier, a slug used by the consumer, and ordered content blocks with typed fields. A page has no visual layout of its own.
Versions
Every change produces a version. Versions move through: draft → in review → approved → published → superseded, with archiving available. Published versions are immutable so consumers can rely on what they fetched.
What publishing means
Publishing makes a content version available through the API and MCP. It never creates a public web page and never exposes a customer URL on Bobby CMS. Publishing requires the content.publish scope and writes an audit record.
Delivery API
A workspace-scoped, read-only Delivery API returns collections and released, delivery-enabled versions as JSON. It is authenticated with a workspace API credential carrying an explicit scope set. Credentials are shown once and stored only as a one-way verifier. The canonical base is https://bobbycms.com/api/v1/. Reads are:
- GET /api/v1/delivery/collections
- GET /api/v1/delivery/collections/{collection}
- GET /api/v1/delivery/collections/{collection}/entries
- GET /api/v1/delivery/collections/{collection}/entries/{entry}
Scopes are delivery.read and delivery.collections.read. There are no API writes, no anonymous access and no public delivery. An internal release is not delivery: each exact version also requires its own delivery-exposure decision.
MCP (authenticated, read only)
The canonical MCP endpoint is https://bobbycms.com/mcp, served over Streamable HTTP with a server-verified bearer credential. It is never anonymous and never writes. Four read-only tools are available: cms.list_collections, cms.get_collection, cms.list_entries and cms.get_entry.
MCP and the Delivery API share one content service and one permission service, so an agent can never exceed the scopes of the credential behind it and can never see content the same credential could not already retrieve over REST. MCP access requires its own scopes ( mcp.connect, mcp.delivery.collections.read, mcp.delivery.entries.read ); REST scopes alone grant no MCP access.
Permission scopes
| Scope | Grants |
|---|---|
| content.read | Read collections, pages and versions in the workspace. |
| content.write | Create and edit draft versions. |
| content.publish | Move an approved version to published. |
| collection.manage | Create, rename and configure collections and types. |
| member.read | Read workspace membership and roles. |
| member.manage | Invite members and change roles below the granting role. |
| apikey.manage | Create and revoke API and MCP credentials. |
| preview.generate | Generate temporary metadata preview documents. |
| billing.read | Read plan, credits and invoices. |
| billing.manage | Change plan and purchase credits. |
| audit.read | Read the workspace audit trail. |
Roles map to scopes server-side. The browser never decides authority: all privileged operations are validated by one canonical server-side authorization authority, and the Workspace Owner role cannot be granted through an ordinary invite or role change.
Iframely metadata previews (planned)
When an editor references an external URL, Bobby CMS can resolve metadata for it — title, description, provider and thumbnail reference — through Iframely. Bobby CMS never proxies, mirrors or hosts third-party page content.
Proposed, admin-configurable defaults:
- Preview-token lifetime: 15 minutes
- Manual refresh: once per 60 seconds per page version
- Generation limit: 30 per hour per workspace
- HTTPS only, with immediate revocation available
- Reserved verification route:
/iframely-preview/{opaque-signed-token}(name only, not implemented)
Outbound resolution is SSRF-protected: public DNS only, private, loopback, link-local and cloud-metadata ranges blocked, redirects capped, and response size, time and content type constrained.
Pilot limitations
Nothing on this site is operational yet