@sixtynine-digital/cms-mcp
v0.1.0
Published
MCP server that exposes a Sixtynine CMS tenant's schema + content to Claude (and other MCP clients) for type-safe Next.js integration
Readme
@sixtynine-digital/cms-mcp
A Model Context Protocol server that exposes a single Sixtynine CMS tenant's schema + content to MCP-aware editors (Claude Code, Cursor, etc.).
The point: when an AI assistant is helping build a customer's frontend against this CMS, it needs to know which collections exist, what fields they have, and what's stored in them — in one go, without the developer pasting the schema into every prompt. This server gives the assistant exactly those answers.
What it exposes
| Tool | What it does |
|------|--------------|
| list-collections | Every collection in the tenant, with a one-line summary of each field. Call this first. |
| describe-collection | Full schema for one collection: every field's type, required/translatable flags, and option blob. |
| query-items | Paginated items from a collection. Supports filter, sort, populate, locale. |
| get-item | A single item by UUID or slug, with optional relation hydration. |
| list-field-types | Static reference of every field type the CMS supports — useful when proposing a new schema. |
All five tools are read-only. Authentication is via a delivery (not management) API key, scoped to one tenant + one environment.
Install
The server is published as an npm package. The recommended way to use it
is from a customer Next.js project's .mcp.json:
{
"mcpServers": {
"sixtynine-cms": {
"command": "npx",
"args": ["-y", "@sixtynine-digital/cms-mcp"],
"env": {
"SIXTYNINE_CMS_API_KEY": "sk_test_…",
"SIXTYNINE_CMS_BASE_URL": "https://cms.sixtynine.dev/api/v1"
}
}
}
}SIXTYNINE_CMS_BASE_URL is optional — defaults to the production API.
For local development point it at http://localhost:3001/api/v1.
Generating the API key
In the CMS admin: Tenant → API → "+ Generate Key", pick type
Delivery and the environment you want to read from. The raw key is
shown once — copy it into your .env.local or directly into the MCP
config.
Local dev (monorepo)
From the monorepo root:
pnpm --filter @sixtynine-digital/cms-mcp build
SIXTYNINE_CMS_API_KEY=sk_test_… \
SIXTYNINE_CMS_BASE_URL=http://localhost:3001/api/v1 \
node packages/cms-mcp/dist/index.jsThe server speaks MCP over stdio — wire your editor at the binary path
above, or run through npx once published.
Design notes
- The MCP wraps
@sixtynine/cmsrather than calling the API directly, so it inherits the SDK's typing, error handling, and preview semantics. The one exception isCmsClient.getSchema(), a thin pass-through toGET /content/_schemathat lives on the client now precisely so this server can use it. - Static reference of field types lives in
src/field-types.ts— keep it in sync with the PrismaFieldTypeenum and the field validators inapps/api/src/modules/fields/. - Per-tenant scope is implicit: the API key carries the tenant + the
environment, so the tools don't take a
tenantIdparameter. If a customer needs to read multiple tenants from one assistant, register multiple server entries with different env-var sets. - The server is intentionally read-only. Creating / updating items is out of scope — that's an authoring concern that belongs in the admin UI, not in editor-side tooling.
