Zenex CMSDocs

MCP integration

Use Zenex from an AI client with stdio or Streamable HTTP. Both transports use the same scoped API keys and editorial operations.

1. Create a scoped API key
Start with content:read and content:write to let your agent prepare drafts. Publication and deletion are separate permissions.
2. Connect a local client with stdio
For clients that launch MCP servers as local processes. Install Node.js 24 and run npm ci in your local Zenex checkout first; no database or CMS environment file is needed for the bridge.
Generic mcpServers configuration
{
"mcpServers": {
"zenex": {
"command": "node",
"args": [
"/absolute/path/to/zenex-cms/scripts/mcp-stdio.mjs"
],
"env": {
"ZENEX_CMS_URL": "https://your-cms.example",
"ZENEX_API_KEY": "znx_REPLACE_WITH_YOUR_KEY"
}
}
}
}

Replace the absolute script path and key locally. This format is accepted by clients using mcpServers JSON; other clients need the same command, args and environment in their own format. Use your client’s secret store when available. Restart or reconnect the integration after saving.

The bridge connects to your hosted CMS using HTTPS and authenticates every request. It does not run a local database or expose a listening port. Use the direct node command above; package-manager banners must not be written to MCP stdout.

Or connect directly over Streamable HTTP
For clients that support a remote MCP endpoint and a custom Authorization header.
URL: https://your-cms.example/api/mcp
Transport: Streamable HTTP
Authorization: Bearer znx_REPLACE_WITH_YOUR_KEY

This is API-key authentication, not OAuth. Clients that require OAuth-only remote servers need the stdio bridge if they support local servers. Legacy SSE-only clients are not supported. Stateless JSON responses do not provide background notifications.

3. Test the editorial workflow
  1. Ask the agent to call get_blog and list_categories.
  2. Create a category, then use its ID in create_posts with status draft.
  3. Review the draft in the dashboard. Publish only after approval and with content:publish + content:write.

Tools cover posts, categories, tags, authors, image upload and blog metadata. Translations use separate posts linked by translationGroupId. New blogs, ownership, members, API keys and paid automatic translation remain dashboard-only.

REST endpoints, fields and permissions →
Rich content: every editor block
Agents use the same Editor.js JSON as the dashboard through create_posts and update_posts, over either transport.

Ask the agent to call get_editor_guide for examples of paragraphs, headings, nested lists, quotes, code, tables, images, link cards, safe HTML and separators.

For a table with a bold, shaded header row, send this block inside content.blocks. Use withHeadings: false for a table without a header.

Table block
{
"type": "table",
"data": {
"withHeadings": true,
"stretched": false,
"content": [
[
"Feature",
"Status"
],
[
"Tables",
"Supported"
],
[
"Notes",
""
]
]
}
}

Editing: supplying content replaces all blocks. Read the post first and preserve everything outside the requested edit. Raw HTML is sanitized; scripts and arbitrary iframes do not execute. Public blogs need the shared zenex-cms.css stylesheet or equivalent styles.

Troubleshooting

401: missing, expired or revoked key. 403: missing scope, wrong blog or disallowed browser origin. 429: wait 60 seconds. 500: ask the operator to check database connectivity and apply the API-key migration.

Keep secrets out of prompts, repositories, browser bundles and public environment variables. Use one key per client and revoke it if compromised. Do not automatically retry a failed write: first check whether it was saved.