MCP server
Page summary:
Strapi includes a built-in Model Context Protocol (MCP) server. Enable it in your server configuration, authenticate with an admin API token, and connect any MCP-compatible tool to read and write content directly from your IDE.
The MCP server is a stateless HTTP endpoint embedded in Strapi core that implements the Model Context Protocol JSON-RPC 2.0 specification. It allows AI coding agents such as Cursor, GitHub Copilot, or Claude Code to interact with a running Strapi instance directly from the IDE, without a third-party bridge.
Each request to POST /mcp authenticates the caller via an admin API token, evaluates RBAC permissions, and processes the JSON-RPC payload in a fresh server context. No server-side sessions are maintained between requests.
mcp.enabled: true in the server configuration fileConfiguration
The MCP server has no admin panel configuration. Enable and configure it in the server configuration file.
Code-based configuration
Add an mcp key to your ./config/server file with at minimum enabled: true:
- JavaScript
- TypeScript
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
mcp: {
enabled: true,
},
});
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
mcp: {
enabled: true,
},
});
The following options are available under the mcp key:
| Parameter | Description | Type | Default |
|---|---|---|---|
mcp.enabled | Enables the MCP endpoint at POST /mcp. | boolean | false |
mcp.connectTimeoutMs | Maximum time in milliseconds allowed for a connection to establish. | integer | 5000 |
mcp.requestTimeoutMs | Maximum time in milliseconds allowed for a single request to complete. | integer | 60000 |
Changing ./config/server requires rebuilding the admin panel. Run yarn build or npm run build after saving the file.
Usage
Once enabled, the MCP server listens at POST /mcp on your Strapi host. Authenticate requests with an admin API token and connect any MCP-compatible tool to start reading and writing content.
Connecting an MCP client
To connect an MCP-compatible tool such as Cursor, Claude Code, or the MCP Inspector:
- Start your Strapi instance with
yarn developornpm run develop. - Open the admin panel and navigate to Settings > Admin API Tokens.
- Create a new token with the permissions matching what you want the AI agent to access. Copy the
accessKeyvalue shown at creation. - Configure your MCP client to point to
http://localhost:1337/mcpand pass the token as aBearerheader.
- Cursor
- VS Code
Add to your .cursor/mcp.json file:
{
"mcpServers": {
"strapi": {
"url": "http://localhost:1337/mcp",
"headers": {
"Authorization": "Bearer your_access_key"
}
}
}
}
Add to your .vscode/mcp.json file:
{
"servers": {
"strapi": {
"type": "http",
"url": "http://localhost:1337/mcp",
"headers": {
"Authorization": "Bearer your_access_key"
}
}
}
}
Replace your_access_key with the token value generated in step 3.
Authentication
Every request to the MCP server must include a Bearer token in the Authorization header. The token must be an admin API token of kind admin.
The MCP server validates the token on each request. Validation checks that:
- The token exists and is of kind
admin. - The token is not expired.
- The token belongs to an active user account.
On successful authentication, the token's lastUsedAt timestamp is updated. If validation fails, the server returns a 401 response with an AUTHENTICATION_REQUIRED error.
The MCP server does not use Strapi's built-in route-level authentication. The MCP layer handles authentication entirely.
Keep your admin API token secret. Anyone who has access to the token can read and write content within the permission scope of the token owner's roles.
Available content-type tools
When the MCP server receives a tools/list request, it returns 1 set of tools per displayed content type. The tools available depend on the content-type kind and the caller's RBAC permissions.
Collection types expose the following tools, where {slug} is the content-type's API ID:
| Tool | Description |
|---|---|
find_{slug} | Retrieve a list of entries |
find_one_{slug} | Retrieve a single entry by document ID |
create_{slug} | Create a new entry |
update_{slug} | Update an existing entry |
delete_{slug} | Delete an entry |
publish_{slug} | Publish an entry |
unpublish_{slug} | Unpublish an entry |
Single types expose:
| Tool | Description |
|---|---|
find_{slug} | Retrieve the document |
write_{slug} | Create or update the document (upsert) |
delete_{slug} | Delete the document |
publish_{slug} | Publish the document |
unpublish_{slug} | Unpublish the document |
RBAC rules are applied per request:
- A tool only appears in
tools/listwhen the token has the required permission for that action on the content type. - Field-restricted roles see a narrowed input schema. Disallowed fields are absent from the schema and stripped from Document Service calls.
- For localized content types, the
localeparameter is restricted to only the locales the token owner may access for the given action.
Registering custom tools from a plugin
Plugins can register additional tools, prompts, and resources on the MCP server during the Strapi register() lifecycle using strapi.ai.mcp:
module.exports = ({ strapi }) => {
strapi.ai.mcp.registerTool('my-custom-tool', {
description: 'Description shown to the AI agent',
inputSchema: z.object({
// Zod schema for the tool input
}),
handler: async (input, context) => {
// Tool implementation
},
access: { auth: { action: 'plugin::my-plugin.some-action' } },
});
};
You can also use strapi.ai.mcp.registerPrompt() and strapi.ai.mcp.registerResource() for prompts and resources respectively.
Registration must happen during register(). Capability registration is locked once the MCP server starts. Tools registered after startup are ignored.
A built-in log tool is registered automatically and is only visible in development mode (when autoReload is true). It is not available in production.