Storyblok MCP
MCP server for Storyblok: fetch stories, manage tags, and use AI (Cursor, Claude Desktop) to work with your content. You only need to set 2–3 env variables.
What you need
- Node.js 18+ — nodejs.org (LTS)
- Storyblok Space ID — Space settings or from the app URL:
app.storyblok.com/#/me/spaces/<ID>/ - Management API token — Storyblok → Settings → Access tokens → Create (full access or at least Stories + Tags)
Quick start
1. The Universal Way (Best for non-technical users)
Deploy this server to Vercel. Once live, anyone can connect to their own Storyblok space using just the URL and token.
"storyblok": {
"url": "https://your-server.vercel.app/sse",
"headers": {
"Authorization": "Bearer YOUR_TOKEN",
"x-space-id": "YOUR_SPACE_ID"
}
}
Advanced Cloud Options (SSE)
You can further customize the connection using headers or URL parameters:
- Specific Space ID: Use the URL
.../sse/12345or set thex-space-idheader. - Custom API Proxy: Set the
x-api-baseheader to point to your own Storyblok MAPI proxy. - Private Access Key: If the server has an
MCP_API_KEYset, provide it via thex-mcp-keyheader.
Example with all options:
"headers": {
"Authorization": "Bearer YOUR_TOKEN",
"x-space-id": "12345",
"x-api-base": "https://your-proxy.com/v1",
"x-mcp-key": "your-secret-server-key"
}
2. Local Development
cp env.example .env
npm install
npm run build
node start-with-env.js
Edit .env and set at least:
STORYBLOK_SPACE_ID=12345
STORYBLOK_MANAGEMENT_TOKEN=your-management-token-here
3. Running with Docker
You can also run the server using Docker. This is great for consistent deployments.
docker build -t storyblok-mcp .
docker run -p 3000:3000 \
-e STORYBLOK_SPACE_ID=your_id \
-e STORYBLOK_MANAGEMENT_TOKEN=your_token \
storyblok-mcp
The Docker image defaults to SSE mode on port 3000.
Deploying to Kubernetes
-
Push to Registry:
docker tag storyblok-mcp your-registry/storyblok-mcp:latest docker push your-registry/storyblok-mcp:latest -
Apply Manifests: Use the provided k8s-deployment.yaml as a template. It sets up a Deployment, a Service, and an Ingress for custom domain support (HTTPS).
-
External URL: Once deployed, you can point your domain (e.g.,
mcp.yourdomain.com) to your Ingress controller's IP.
4. Connect to Cursor or Claude Desktop
Cursor — edit MCP config (e.g. ~/Library/Application Support/Cursor/User/globalStorage/cursor.mcp/mcp.json or Settings → MCP):
{
"mcpServers": {
"storyblok": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/storyblok-mcp/start-with-env.js"]
}
}
}
Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"storyblok": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/storyblok-mcp/start-with-env.js"]
}
}
}
Replace the path with your actual storyblok-mcp folder path. Restart Cursor or Claude.
start-with-env.js loads .env from the project folder, so you don’t need to put secrets in the MCP config.
Env variables
| Variable | Required | Description |
|---|---|---|
STORYBLOK_SPACE_ID | ✅ | Your Storyblok space ID |
STORYBLOK_MANAGEMENT_TOKEN | ✅ | Management API token |
STORYBLOK_REGION | ❌ | eu (default), us, ca, ap, cn — use if your Space is not in EU |
STORYBLOK_API_BASE | ❌ | Override API base (if proxying) |
Region (EU, US, etc.)
If your Storyblok Space is in the US or another region, set:
STORYBLOK_REGION=us
Options: eu, us, ca, ap, cn. Default: eu.
Custom API URL
Only if you proxy the Storyblok Management API through your own domain:
STORYBLOK_API_BASE=https://your-proxy.com/path
SSE Custom Proxy
In SSE mode, you can also specify the proxy per-connection:
"headers": {
"x-api-base": "https://your-proxy.com/v1"
}
The proxy must forward to the real Storyblok MAPI. Otherwise leave this unset.
Tools
Full-featured TypeScript implementation for the Storyblok Management API.
| Category | Tools |
|---|---|
| Stories | fetch_stories, get_story, create_story, update_story, delete_story, publish_story, unpublish_story, get_story_versions |
| Tags | fetch_tags, create_tag, create_tag_and_add_to_story, add_existing_tag_to_story, update_tag, delete_tag |
| Components | fetch_components, get_component, create_component, update_component, delete_component |
| Assets | fetch_assets, get_asset, update_asset, delete_asset |
| Releases | fetch_releases, get_release, create_release, update_release, delete_release |
| Workflows | fetch_workflows, get_workflow, create_workflow, update_workflow, delete_workflow, fetch_workflow_stages |
| Webhooks | fetch_webhooks, get_webhook, create_webhook, update_webhook, delete_webhook |
| Datasources | fetch_datasources, get_datasource, create_datasource, update_datasource, delete_datasource, fetch_datasource_entries, create_datasource_entry, update_datasource_entry, delete_datasource_entry |
| Space | get_space, update_space |
| Meta | list_tools — list all tools by category |
| Ping | ping — health check (optional check_api=1 to test API) |
Example prompts
- “Fetch my Storyblok stories”
- “List all tags in my space”
- “Suggest a tag for each of my blog posts and add them”
- “Add the tag ‘product-launch’ to story ID …”
Troubleshooting
- “Missing env” —
.envmust be next tostart-with-env.jsand containSTORYBLOK_SPACE_IDandSTORYBLOK_MANAGEMENT_TOKEN. - 401 from Storyblok — Token invalid or expired; create a new Management token with Stories + Tags.
- MCP not listed — Use the absolute path to
start-with-env.jsand restart Cursor/Claude. - “Cannot find module” — Run
npm installandnpm run buildin yourstoryblok-mcpfolder.