MCP 服务器(MCP server)
(v5.47.0)
页面摘要: Strapi 包含一个内置的 Model Context Protocol (MCP)(模型上下文协议)服务器。启用后,它可以让 AI 客户端直接通过 Strapi 的内容管理器(Content Manager)创建、读取、更新、删除、发布和取消发布内容。所有操作都受 Admin 令牌(token)权限控制。
MCP 服务器向 AI 客户端(如 Claude Desktop、Claude Code、Codex、Cursor,或任何兼容 MCP 的工具)暴露一组内容管理工具。例如,连接到 MCP 服务器的 AI 客户端可以创建博客文章、列出最近的条目,或发布页面。哪些工具可用取决于授予用于身份验证的 Admin 令牌(token)的权限。
- 套餐:免费功能
- 角色与权限:管理员(Admin,令牌创建者)
- 启用:服务器配置
- 环境:在开发(Development)和生产(Production)环境中均可用
配置
在首次使用前,Strapi MCP 服务器必须:
- 通过服务器配置文件启用,并使用在管理面板中创建的 Admin 令牌(token)进行身份验证
- 连接到你的 AI 客户端。
基于 Strapi 代码的配置
通过在服务器配置文件中添加 mcp 对象来启用 MCP 服务器:
JavaScript
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
// highlight-start
mcp: {
enabled: true,
},
// highlight-end
});
TypeScript
import type { Core } from '@strapi/strapi';
const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Server => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
// highlight-start
mcp: {
enabled: true,
},
// highlight-end
});
export default config;
设置就绪后,重启 Strapi。MCP 端点在你的 Strapi 服务器上以 /mcp 提供(例如 http://localhost:1337/mcp)。
高级选项
以下可选键可以添加到 mcp 配置对象中:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | 布尔值(Boolean) | false | 启用或禁用 MCP 服务器。 |
connectTimeoutMs | 数字(Number) | 5000 | 内部 MCP 传输连接在被中止请求之前的最大时间(毫秒)。 |
requestTimeoutMs | 数字(Number) | 60000 | 单个 MCP 请求在超时之前完成的最大时间(毫秒)。 |
mcp: {
enabled: true,
connectTimeoutMs: 10000, // 10 秒
requestTimeoutMs: 120000, // 2 分钟
},
基于 Strapi 管理面板的配置
MCP 服务器使用 Admin 令牌(token)对请求进行身份验证。每个 MCP 会话都被限定为用于连接的令牌的权限范围内:
- 创建一个新的 Admin 令牌(token)(见 创建 Admin 令牌(token),在 Admin tokens 功能页面上)。
- 复制令牌(token)的值。在配置 AI 客户端时你会需要它。
令牌的权限决定了向 AI 客户端暴露哪些 MCP 工具。例如,如果令牌仅授予对 Article 内容类型的 read(读取)权限,那么 AI 客户端将只能看到用于文章的列出和读取工具。
AI 客户端配置
一旦你通过服务器配置文件启用了 MCP 服务器,并在管理面板中创建了 Admin 令牌(token),就可以将你的 AI 客户端连接到 Strapi MCP 服务器。
本页的配置示例中使用 http://localhost:1337/。如果你的 Strapi 服务器托管在其他 URL 或端口上,请相应地更新代码。
连接 Claude Desktop
打开 Claude Desktop 的配置文件。位置因系统而异:
| 操作系统 | 文件位置 |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
你也可以从 Claude 的设置中打开 Claude Desktop 的配置文件:转到 Settings > Desktop app > Developer,然后点击 编辑配置(Edit config) 按钮。
将 Strapi MCP 服务器添加到 Claude 的配置文件,如下例所示,将 YOUR_ADMIN_TOKEN 替换为从 Strapi 管理面板配置 复制的 Admin 令牌(token)值:
{
"mcpServers": {
"strapi-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:1337/mcp",
"--header",
"Authorization: Bearer YOUR_ADMIN_TOKEN"
]
}
}
}
重启 Claude Desktop 以使更改生效。
连接 Claude Code
运行以下命令,将 YOUR_ADMIN_TOKEN 替换为从 Strapi 管理面板配置 复制的 Admin 令牌(token)值:
claude mcp add strapi-mcp --transport http http://localhost:1337/mcp -H "Authorization: Bearer YOUR_ADMIN_TOKEN"
连接 Codex
运行以下命令,将 YOUR_ADMIN_TOKEN 替换为保存了从 Strapi 管理面板配置 复制的 Admin 令牌(token)值的环境变量名称:
codex mcp add strapi-mcp --url http://localhost:1337/mcp --bearer-token-env-var YOUR_ADMIN_TOKEN
然后,在启动 codex 之前设置环境变量,或将其添加到你的 shell 中。
运行 /mcp 以确认 strapi-mcp 报告为已连接。
连接 Cursor
将服务器添加到你的 .cursor/mcp.json 文件:
{
"mcpServers": {
"strapi-mcp": {
"type": "streamable-http",
"url": "http://localhost:1337/mcp",
"headers": {
"Authorization": "Bearer YOUR_ADMIN_TOKEN"
}
}
}
}
连接 Windsurf
将服务器添加到你的 ~/.codeium/windsurf/mcp_config.json 文件:
{
"mcpServers": {
"strapi-mcp": {
"serverUrl": "http://localhost:1337/mcp",
"headers": {
"Authorization": "Bearer YOUR_ADMIN_TOKEN"
}
}
}
}
连接其他 MCP 客户端
任何支持 MCP Streamable HTTP 传输协议的客户端都可以连接。通用配置如下:
| 设置 | 值 |
|---|---|
| 传输类型(Transport type) | streamable-http |
| URL | http://localhost:1337/mcp(根据你的 Strapi 实例调整主机和端口) |
| 授权响应头(Authorization header) | Bearer YOUR_ADMIN_TOKEN |
使用
MCP 服务器使用 Streamable HTTP 传输协议。任何兼容 MCP 的客户端都可以通过指向 /mcp 端点、并在 Authorization 响应头中携带 Bearer 令牌(token)来连接。一旦连接,AI 客户端就可以使用自然语言提示与你的 Strapi 内容进行交互。
可用工具
MCP 服务器暴露 3 类工具:从你的模式(schema)生成的内容管理工具、Media Library(媒体库)工具,以及内置的实用工具。
内容管理工具
生成的工具因内容类型是集合类型(collection type)还是单一类型(single type)而异。
集合类型(Collection types) 最多生成 8 个工具:5 个用于 CRUD 操作,3 个用于 草稿与发布(Draft & Publish) 操作:
| 工具 | 操作 | 所需权限 | 说明 |
|---|---|---|---|
list | 读取(Read) | read | 列出条目,支持分页、排序和筛选 |
get | 读取(Read) | read | 按文档 ID 获取单个条目 |
create | 创建(Create) | create | 创建新条目(如果启用了草稿与发布,则作为草稿创建) |
update | 更新(Update) | update | 按文档 ID 更新现有条目 |
delete | 删除(Delete) | delete | 按文档 ID 删除条目 |
publish | 发布(Publish) | publish | 发布草稿条目 |
unpublish | 取消发布(Unpublish) | publish | 取消已发布条目的发布 |
discard_draft | 丢弃草稿(Discard draft) | publish | 丢弃草稿更改并回退到已发布版本 |
单一类型(Single types) 最多生成 6 个工具。因为单一类型始终只代表一个文档,所以没有 list 工具,且创建/更新合并为一个 write 工具:
| 工具 | 操作 | 所需权限 | 说明 |
|---|---|---|---|
get | 读取(Read) | read | 获取单一类型文档 |
write | 创建或更新 | create 和/或 update | 如果不存在则创建文档;否则更新现有草稿 |
delete | 删除(Delete) | delete | 删除单一类型文档 |
publish | 发布(Publish) | publish | 发布文档 |
unpublish | 取消发布(Unpublish) | publish | 取消已发布文档的发布 |
discard_draft | 丢弃草稿(Discard draft) | publish | 丢弃草稿更改并回退到已发布版本 |
发布(publish)、取消发布(unpublish)和丢弃草稿(discard_draft)工具仅在内容类型上启用了 草稿与发布(Draft & Publish) 时才会生成。
Media Library(媒体库)工具 {#media-library-tools}
(v5.54.0)
Strapi 为 Media Library(媒体库) 注册了 10 个工具:3 个用于读取,7 个用于写入。与内容管理工具不同,它们不是从你的模式(schema)生成的,因此始终注册相同的集合。每个工具仅在 Admin 令牌(token)授予以下列出的权限时才会暴露:令牌无法使用的工具不会出现在 tools/list 中,调用它会返回权限错误。
| 工具 | 所需权限 | 说明 |
|---|---|---|
media_list_assets | plugin::upload.read | 列出资源,支持分页和可选筛选 |
media_get_asset | plugin::upload.read | 按数字 id 返回单个资源 |
media_list_folders | plugin::upload.read | 以嵌套结构返回完整的文件夹树 |
media_update_asset | plugin::upload.assets.update | 更新 name、alternativeText 或 caption |
media_move_assets | plugin::upload.assets.update | 批量将资源移动到另一个文件夹 |
media_delete_assets | plugin::upload.assets.update | 批量永久删除资源 |
media_create_folder | plugin::upload.assets.create | 创建文件夹,可选择在某个父文件夹内 |
media_rename_folder | plugin::upload.assets.update | 重命名文件夹 |
media_move_folder | plugin::upload.assets.update | 将文件夹移动到另一个父文件夹 |
media_delete_folder | plugin::upload.assets.update | 删除文件夹及其包含的一切 |
工具响应包含一个固定的字段允许列表:id、name、alternativeText、caption、url、mime、size、width、height、ext、folder 以及时间戳。可能暴露存储提供方凭据或内部路径的字段(provider、provider_metadata、hash、formats、folderPath)永远不会返回,即使内容类型后来被扩展也是如此。
资源和文件夹通过数字 id 而非文档 ID 来标识,两者是独立的序列:同一个数字可以同时命名一个资源和一个文件夹。资源 id 从 media_list_assets 或 media_get_asset 获取,文件夹 id 从 media_list_folders 获取。
读取(Reading)。 media_list_assets 工具接受以下可选参数:
| 参数 | 类型 | 说明 |
|---|---|---|
page | 数字(Number) | 页码,从 1 开始(默认:1)。 |
pageSize | 数字(Number) | 每页资源数量(默认:25,最大:100)。 |
folderId | 数字(Number)或 null | 用于列出特定文件夹中资源的数字文件夹 ID,或 null 仅表示根级资源。省略则列出所有文件夹中的资源,不论文件夹。 |
mime | 字符串(String) | MIME 类型筛选。没有斜杠的值作为前缀匹配("image" 匹配每个 image/* 类型),完整的类型则精确且不区分大小写地匹配("image/png")。 |
name | 字符串(String) | 部分资源名称筛选(不区分大小写的子串匹配)。 |
sort | 字符串(String) | 排序顺序(默认:createdAt:DESC)。仅接受 6 个值:createdAt:ASC、createdAt:DESC、name:ASC、name:DESC、updatedAt:ASC 和 updatedAt:DESC。方向为大写,任何其他值都会被拒绝。 |
media_get_asset 工具需要 1 个参数:id,即数字资源 ID。不接受文档 ID 字符串。media_list_folders 工具不接受任何参数,返回完整的文件夹层级。
写入(Writing)。 media_update_asset 仅写入元数据。文件本身、其 URL、其 MIME 类型和其大小属于 上传提供方,无法通过 MCP 更改。使用 media_move_assets 更改资源所在的文件夹,使用 media_rename_folder 而非 media_move_folder 来更改文件夹名称。
media_move_assets 和 media_move_folder 都接受 null 作为目标,表示 Media Library(媒体库)根目录。文件夹不能移动到自身或其自身的后代中。
media_delete_assets 和 media_delete_folder 会从数据库和存储提供方中移除文件,以及每个生成的缩略图和尺寸变体。没有回收站,也没有撤销,并且删除文件夹会级联到其中的每个子文件夹和文件。这两个工具都无法判断某个资源是否被条目引用,因此成功的删除并不能证明没有任何东西正在使用它。
两者都接受一个 dryRun 参数,它会报告将被移除的内容而不实际移除任何东西。它们在部分失败时的行为不同:media_delete_assets 保留成功的删除并报告其余情况,而 media_delete_folder 如果任何 id 无法解析为文件夹,则会拒绝整个调用。
内置实用工具
除了内容管理工具,Strapi 还注册以下内置工具:
| 工具 | 可用性 | 说明 |
|---|---|---|
log | 仅开发(Development)模式 | 以指定级别(info、warn、error、http、log)将消息记录到 Strapi 服务器控制台。对调试 MCP 交互很有用。 |
内置实用工具仅在开发(Development)模式下可用(当 autoReload 启用时),并且不需要特定的管理员权限。
通过提示进行内容管理
连接后,你可以使用自然语言与你的 Strapi 内容进行交互:
| 提示 | 发生的情况 |
|---|---|
| "创建一篇标题为 'Hello World'、正文为 'First post' 的新文章。" | 创建一个草稿文章条目 |
| "列出最近 5 篇文章。" | 返回分页列表,最新的在前 |
| "显示 ID 为 abc123 的文章。" | 返回完整的条目 |
| "更新文章 abc123,将标题改为 'Hello Strapi'。" | 更新标题,其他字段不变 |
| "发布文章 abc123。" | 将条目的状态更改为已发布 |
| "删除文章 abc123。" | 移除该条目 |
| "创建一篇法语文章,标题为 'Bonjour le monde'。" | 创建一个 locale 设为 fr 的草稿文章 |
国际化(Internationalization,i18n)
当内容类型上启用了 国际化(Internationalization,i18n) 时,MCP 工具接受一个可选的 locale 参数(例如 "en"、"fr")。如果省略,则使用默认语言区域(locale)。
AI 客户端在每个工具的模式(schema)中可以看到哪些语言区域(locale)可用,因此你可以要求它用特定语言创建或更新内容。例如,请求 "创建一篇法语文章,标题为 'Bonjour'" 会向 create 工具传递 locale: "fr"。哪些语言区域(locale)可用取决于 Admin 令牌(token)的权限(见 权限边界)。
在处理本地化内容时,在你的提示中明确提及目标语言,以便 AI 客户端传递正确的 locale 值。例如,优先使用 "创建一篇 法语 文章",而不是 "创建一篇标题为 'Bonjour' 的文章",以避免歧义。
排序
list 工具接受一个支持 4 种写法的 sort 参数:
| 写法 | 示例 |
|---|---|
| 字符串 | "title:asc" |
| 字符串数组 | ["title:asc", "createdAt:desc"] |
| 对象 | { "title": "asc" } |
| 对象数组 | [{ "title": "asc" }, { "createdAt": "desc" }] |
排序字段名被限定为内容类型的标量属性(字符串、数字、布尔值、日期、枚举)。关系(relation)、组件(component)、动态区域(dynamic zone)、媒体(media)和 JSON 字段无法排序。
筛选
list 工具接受使用 Strapi 筛选语法的 filters 参数:
- 字段运算符:
$eq、$ne、$in、$notIn、$lt、$lte、$gt、$gte、$between、$contains、$notContains、$startsWith、$endsWith、$null、$notNull,以及它们不区分大小写的变体($eqi、$nei、$containsi、$notContainsi、$startsWithi、$endsWithi)。 - 逻辑运算符:
$and、$or(接受筛选对象数组)、$not(包裹单个筛选对象)。 - 隐式相等:直接传递值(例如
{ "title": "Hello" })等同于{ "title": { "$eq": "Hello" } }。
与排序字段一样,筛选字段也仅限标量属性。
分页
list 工具还接受 page(从 1 开始,默认:1)和 pageSize(默认:25,最大:100)参数。
关系
关系字段同时支持简写文档 ID 字符串和完整关系对象。
一对一关系(To-one relations)(oneToOne、manyToOne)接受:
- 文档 ID 字符串:
"z7v8zma53x01r6oceimv922b" - 关系对象:
{ "documentId": "z7v8zma53x01r6oceimv922b", "locale": "en", "status": "draft" }(locale和status可选) null以清除关系
一对多关系(To-many relations)(oneToMany、manyToMany)接受包含一个或多个以下键的关系对象:
| 键 | 说明 |
|---|---|
connect | 添加关系。接受文档 ID 字符串数组或 { documentId, locale?, status?, position? } 对象。可选的 position 键支持 { before?, after?, start?, end? } 排序提示(默认:{ end: true })。 |
disconnect | 移除关系。接受文档 ID 字符串数组或 { documentId, locale?, status? } 对象。 |
set | 用提供的数组替换所有现有关系。传递 null 以清除所有关系。与 connect/disconnect 互斥。 |
权限边界
MCP 服务器强制执行与 Strapi 管理面板相同的权限模型。权限在多个层级进行检查:
- 工具可见性:当 AI 客户端连接时,Strapi 会检查 Admin 令牌(token)的权限,仅暴露令牌有权访问的工具。如果令牌没有授予对
Article的delete权限,AI 客户端将根本看不到文章的删除工具。 - 字段筛选:即使在已暴露的工具内部,输入和输出模式(schema)也会被收窄到令牌可以访问的字段。如果令牌授予对
Article的read(读取)权限但排除了body字段,AI 客户端将看不到也不会收到body内容。字段限制按操作独立应用。写入模式(schema)(create、update)仅包含相应操作允许的字段。 - 语言区域(Locale)筛选:当启用 国际化(Internationalization,i18n) 功能并配置了语言区域(locale)级别的权限时,
locale参数会按操作收窄。例如,一个令牌可能允许读取en和fr中的内容,但只允许在en中创建内容。如果默认语言区域(locale)被允许用于某个操作,则该语言区域(locale)被应用为 Zod 模式(schema)的默认值,因此 AI 客户端无需显式指定语言区域(locale)。 - 运行时强制执行:除了模式(schema)级别的收窄外,每个处理程序在运行时都会调用 Strapi 的权限检查器,以验证对所读取、写入或发布的特定文档的访问。基于条件的权限(例如「仅更新你拥有的条目」)在此层级强制执行。
这意味着你可以创建具有细粒度访问权限的令牌:
- 一个只暴露列出和读取工具的「只读」令牌
- 一个限定于特定内容类型(例如文章而非分类)的令牌
- 一个限定于特定字段或语言区域(locale)的令牌
- 一个带有基于条件权限(例如仅更新你拥有的条目)的令牌
为每个 AI 客户端或用例创建专用的 Admin 令牌(token)。使用仍然允许 AI 完成任务的最严格权限。
审计日志
(Enterprise 计划) (v5.52.0)
通过 MCP 服务器执行的条目操作会记录在 审计日志(Audit Logs) 中。每个日志记录携带一个设置为 mcp 的 origin 键,用于区分由 AI 客户端触发的操作与在管理面板中执行的操作。仅读取内容的操作不会被记录。
无状态架构
MCP 服务器使用无状态架构。对 /mcp 端点的每个 POST 请求都会创建一个全新的、临时性的 MCP 服务器实例,其作用域限定在已验证令牌的权限内。请求之间没有会话持久化:每个请求都是独立进行身份验证和授权的。由于没有会话状态,AI 客户端不需要管理会话 ID,并且权限更改(例如撤销令牌或更新其权限)在下一个请求时生效。
/mcp 端点上的 GET 和 DELETE HTTP 方法返回 405 Method Not Allowed JSON-RPC 错误,因为 MCP 服务器只接受 POST 请求。
已知限制
MCP 服务器有以下限制:
- 动态区域(Dynamic zones):动态区域字段在工具模式(schema)中作为无类型数组传递。动态区域内每个组件的内部结构未被描述。
- 嵌套联表加载(population)参数:
list和get工具不支持关系的嵌套联表加载(population)参数。 - 媒体上传:媒体字段接受现有的媒体资源引用,但 MCP 服务器无法上传新文件。请先使用 Strapi 的媒体库或上传 API 添加文件,然后在 MCP 工具调用中引用它们。
- 自定义字段(Custom fields):通过插件注册的自定义字段会映射到其底层的 Strapi 类型。如果在注册 MCP 工具时自定义字段注册表为空,自定义字段会回退到
unknown类型。 - 循环组件引用:直接或间接引用自身的组件会在循环点回退到开放的
record<string, unknown>模式(schema),而不是无限递归结构。
兼容性与模式(schema)变更
(v5.53.0+)
从上面指出的版本开始,内置 MCP 服务器使用 MCP TypeScript SDK v2。这带来了影响客户端和能力(capability)作者的两项变更。
JSON Schema 2020-12
工具 inputSchema 和 outputSchema 文档现在序列化为 JSON Schema 2020-12,而不是早期版本使用的 draft-07 方言。关键的格式差异是:
- 位置元组使用
prefixItems而不是 draft-07 的items数组形式。 - 递归模式(schema)(包括内容类型的
list_*筛选参数)通过$defs而非definitions引用共享定义。
严格遵守 JSON Schema 2020-12 校验所声明模式(schema)的 MCP 客户端,现在会保留 Strapi 声明的每个工具。在此变更之前,那些客户端会拒绝 draft-07 模式(schema),并静默地将工具从可用列表中丢弃,这表现为一个「权限缺失」问题,且服务器端没有记录错误。这就是 strapi/strapi#27395 中描述的故障。完全不校验模式(schema)方言的客户端不受影响。
处理程序上下文与能力结果类型
能力(capability)处理程序仍然接收 { args, extra }。extra 值现在是一个 Strapi 拥有的、全可选的 handler 上下文。你在能力(capability)处理程序中已经使用的字段名保持不变:取消(cancellation)、请求和会话身份、令牌信息、请求元数据,以及发起的 HTTP 请求详情。
工具、提示(prompt)和资源结果是 Strapi 拥有的、从 @strapi/types 导出的类型(McpToolResult、McpPromptResult、McpResourceReadResult、McpResourceListingMetadata、McpContentBlock)。现有的构造仍然有效,包括全部五种内容变体、资源文本和二进制(blob)内容,以及扩展字段。@strapi/types 不再直接依赖 MCP SDK;核心(core)保留 SDK 依赖仅用于传输(transport)。
空的能力(capability)类别现在枚举为空列表,而不是返回未知方法错误。
插件 API
Strapi 插件可以通过 strapi.ai.mcp 服务注册额外的 MCP 工具,以便 AI 客户端可以触发插件特定的操作。点击下面的卡片阅读更多详情:
- 扩展 MCP 服务器 — 通过 strapi.ai.mcp 服务从 Strapi 插件注册自定义 MCP 工具。