MCP Server Reference
Manage your Drupal spaces, import content, deploy between environments, and monitor usage directly from AI tools like Claude Desktop, Cursor, and Claude Code. 25+ tools available.
What is MCP?
The Model Context Protocol (MCP) is an open standard that lets AI assistants connect to external tools and data sources. Decoupled.io provides an MCP server that gives AI tools direct access to your Drupal platform.
Instead of switching between your AI assistant and the dashboard, you can manage everything through natural language:
- "Create a new Drupal site called My Blog"
- "Import a product catalog with 10 sample items"
- "Initialize a test environment and deploy config from dev"
- "Show me usage stats for all my spaces"
Setup
Prerequisites
You need a Personal Access Token (PAT) to authenticate with the MCP server. Get one from your dashboard:
- Go to dashboard.decoupled.io
- Navigate to Settings → API Tokens
- Create a new token and copy it (format:
dc_tok_...)
Configure MCP
Run this command to auto-detect your IDE and configure the MCP server:
npx decoupled-cli@latest mcp configure
It will prompt for your API token and set everything up. You can also target a specific IDE:
npx decoupled-cli@latest mcp configure --ide claude-code
npx decoupled-cli@latest mcp configure --ide cursor
Manual Configuration (JSON)
Claude Code
Add a .mcp.json file to your project root:
{
"mcpServers": {
"decoupled-io": {
"type": "http",
"url": "https://mcp.decoupled.io",
"headers": {
"Authorization": "Bearer dc_tok_YOUR_TOKEN"
}
}
}
}
Claude Desktop
Add to your Claude Desktop configuration file:
{
"mcpServers": {
"decoupled-io": {
"url": "https://mcp.decoupled.io/sse",
"headers": {
"Authorization": "Bearer dc_tok_YOUR_TOKEN"
}
}
}
}
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Cursor
Add to your Cursor MCP settings (Settings → MCP):
{
"mcpServers": {
"decoupled-io": {
"url": "https://mcp.decoupled.io/sse",
"headers": {
"Authorization": "Bearer dc_tok_YOUR_TOKEN"
}
}
}
}
Space Management Tools
list_spaces
List all Drupal spaces in your organization with status, URLs, and hosting tier.
| Parameter | Type | Description |
|---|---|---|
archived |
boolean (default: false) | Include archived spaces |
Try it: "Show me all my Drupal spaces"
get_space
Get detailed information about a specific space including status, URLs, admin credentials, and resource usage.
| Parameter | Type | Description |
|---|---|---|
id |
number or string (required) | Space ID or machine name |
Try it: "What's the status of space 42?"
create_space
Create a new Drupal space. Provisioning takes ~30 seconds from the inventory pool, or 90-100 seconds for a fresh install if the pool is empty.
| Parameter | Type | Description |
|---|---|---|
name |
string (required) | Name for the new space |
type |
starter | growth (default: starter) | Hosting tier — starter (hibernates after idle) or growth (always-on) |
Try it: "Create a new Drupal site called My Portfolio"
delete_space
Permanently delete a Drupal space. This action cannot be undone.
| Parameter | Type | Description |
|---|---|---|
id |
number (required) | Space ID to delete |
Environment Tiers
Decoupled.io supports a Dev → Test → Live environment pipeline, similar to Pantheon or Acquia. Each space starts as a Dev environment. You can then initialize Test and Live tiers from it.
initialize_tier
Initialize a Test or Live environment for a space. Creates a clone of the source space as the next tier in the pipeline.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Source space ID to clone into the new tier |
tier |
test | live (required) | Target tier to initialize |
Tier hierarchy:
- Test can only be created from a Dev space
- Live can only be created from a Test space
Try it: "Initialize a test environment from space 42"
deploy
Deploy database/files or configuration between environment tiers. Both spaces must belong to the same environment group.
| Parameter | Type | Description |
|---|---|---|
sourceSpaceId |
number (required) | Source space ID to deploy from |
targetSpaceId |
number (required) | Target space ID to deploy to |
deployType |
db-files | config (required) | Type of deployment |
Deploy types:
- db-files — Copies database and uploaded files from source to target (destructive — overwrites target data)
- config — Exports Drupal configuration from source and imports into target (views, content types, image styles, etc.)
Try it: "Deploy config from my dev space to test"
Content Tools
import_content
Import content models and data into a Drupal space. Always include both model and content arrays — Drupal spaces start empty with no content types.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Target space ID |
content |
object (required) | Must contain both model (creates types/fields) and content (populates data) arrays |
preview |
boolean (default: false) | Preview changes without applying |
Supported field types: string, text, select(opt1|opt2|opt3), bool, int, number, date, datetime, image, term(vocab)[], paragraph(type)[], ref(node:bundle). Use ! for required, [] for multi-value.
{
"model": [{
"bundle": "blog_post",
"label": "Blog Post",
"body": true,
"fields": [
{ "id": "category", "label": "Category", "type": "select(tutorial|news|review)" },
{ "id": "layout", "label": "Layout", "type": "select(default|wide|sidebar)" },
{ "id": "featured", "label": "Featured", "type": "bool" },
{ "id": "hero_image", "label": "Hero Image", "type": "image" }
]
}],
"content": [{
"id": "post1",
"type": "node.blog_post",
"path": "/blog/first-post",
"values": {
"title": "Getting Started with Headless Drupal",
"body": "<p>Your first headless CMS project...</p>",
"category": "tutorial",
"layout": "wide",
"featured": true
}
}]
}
Try it: "Import a blog content model with 5 sample posts into space 42"
get_import_example
Get the complete content import JSON example showing all supported field types and the correct structure.
Parameters: None
Try it: "Show me the content import format"
import_config
Import Drupal configuration YAML into a space. Supports views, image styles, roles, menus, content type settings, display modes, and more.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Target space ID |
configs |
array (required) | Array of objects with name (config name) and yaml (YAML string) |
preview |
boolean (default: false) | Preview changes without applying |
{
"configs": [
{
"name": "image.style.wide",
"yaml": "langcode: en\nstatus: true\nname: wide..."
},
{
"name": "user.role.editor",
"yaml": "langcode: en\nstatus: true\nid: editor..."
}
]
}
Try it: "Create a Wide image style on space 42 that scales images to 1200px width"
Allowed config types: Views, image styles, menus, content type settings, field configs, display modes, taxonomy vocabularies, blocks, roles, text formats, editor configs, pathauto patterns, and more. Dangerous configs like core.extension and system.site are blocked.
Organization & Usage Tools
get_organization
Get current organization details including name, subscription plan, and limits.
Parameters: None
get_usage
Get organization-wide usage statistics including storage, bandwidth, and API requests across all spaces.
Parameters: None
get_space_usage
Get detailed usage statistics for a specific space.
| Parameter | Type | Description |
|---|---|---|
id |
number (required) | Space ID |
Utility Tools
get_login_link
Generate a one-time login link that logs you directly into the Drupal admin panel. Expires in 24 hours.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
Try it: "Give me a login link for space 42"
get_oauth_credentials
Get OAuth credentials for a space, ready to paste into your Next.js .env.local file. Returns client_id, client_secret, and revalidate_secret.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
Try it: "Get the OAuth credentials for space 42 so I can set up my Next.js frontend"
configure_preview
Configure decoupled preview and on-demand revalidation for a space. Sets the frontend preview URL, enables preview for all content types, configures the GraphQL Compose Preview draft provider, and sets up revalidation with the same URL. Does not enable anonymous redirects.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
previewUrl |
string (required) | Frontend URL (e.g., "https://my-site.vercel.app") |
Try it: "Configure preview for space 42 with URL https://my-site.vercel.app"
Content Discovery Tools
list_content_types
List all content types (node bundles) available on a Drupal space. Returns machine names, labels, and descriptions.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID to query |
Try it: "What content types are available on space 42?"
describe_content_type
Get the field definitions for a specific content type. Returns field names, types, labels, required status, and cardinality.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID to query |
contentType |
string (required) | Content type machine name (e.g., "article") |
Try it: "Show me the fields for the article content type on space 42"
list_taxonomies
List all taxonomy vocabularies on a Drupal space. Returns vocabulary machine names, labels, and descriptions.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID to query |
list_terms
List taxonomy terms from a specific vocabulary on a Drupal space.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID to query |
vocabulary |
string (required) | Vocabulary machine name (e.g., "tags") |
Content CRUD Tools
list_content
List content (nodes) of a specific type from a Drupal space. Returns titles, UUIDs, and field values.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID to query |
contentType |
string (required) | Content type machine name |
limit |
number (default: 10, max: 50) | Number of items to return |
sort |
string (default: "-created") | Sort field |
Try it: "Show me the 5 most recent articles on space 42"
get_content
Get a single content item (node) by its UUID. Returns all fields and relationships.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
contentType |
string (required) | Content type machine name |
uuid |
string (required) | The UUID of the content item |
create_content
Create a new content item (node) on a Drupal space via JSON:API. Use describe_content_type first to see available fields.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
contentType |
string (required) | Content type machine name |
attributes |
object (required) | Field values (must include "title") |
Try it: "Create an article titled 'Hello World' on space 42"
update_content
Update an existing content item. Only provide the fields you want to change.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
contentType |
string (required) | Content type machine name |
uuid |
string (required) | UUID of the content item |
attributes |
object (required) | Fields to update |
delete_content
Delete a content item from a Drupal space. This action cannot be undone.
| Parameter | Type | Description |
|---|---|---|
spaceId |
number (required) | Space ID |
contentType |
string (required) | Content type machine name |
uuid |
string (required) | UUID of the content item |
Scaffolding Tools
download_starter
Get the Next.js starter template for headless Drupal. Returns the git clone URL and setup instructions for a barebones Next.js 16 starter with GraphQL proxy, Apollo Client, ISR revalidation, and Tailwind CSS.
Parameters: None
Try it: "Help me set up a Next.js frontend for my Drupal space"
Example Workflows
Build a blog from scratch
Ask your AI assistant:
"Create a new Drupal space called 'Tech Blog', then import a blog content model with categories and 5 sample posts about web development. Give me the login link when done."
The AI will call create_space, wait for provisioning, call import_content with generated content, then get_login_link.
Set up a Next.js frontend
Ask your AI assistant:
"Get the OAuth credentials for space 42, download the starter template, configure preview with my Vercel URL, and help me set it up."
The AI will call get_oauth_credentials, download_starter, and configure_preview to get everything connected.
Set up environment tiers
Ask your AI assistant:
"Initialize a test environment from space 42, then deploy the latest config from dev to test."
The AI will call initialize_tier to create the test tier, then deploy with deployType: config to sync configuration.
Troubleshooting
Token not working
Ensure your token starts with dc_tok_ and hasn't been revoked. Generate a new one at Settings → API Tokens.
Space still provisioning
New spaces typically provision in ~30 seconds (from inventory pool) or 90-100 seconds for a fresh install. Use get_space to check the status. The AI assistant will typically wait and poll automatically.
MCP server not connecting
Verify the server URL is https://mcp.decoupled.io (HTTP transport) or https://mcp.decoupled.io/sse (SSE transport). Check that your Authorization header includes Bearer before the token.
Test the server directly
curl -s https://mcp.decoupled.io \
-H "Content-Type: application/json" \
-H "Authorization: Bearer dc_tok_YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}' \
| jq -r '.result.tools[].name'