Trae + Apifox MCP:让 AI 自动协同前后端接口文档
在前后端协作中,接口文档经常出现三个问题:后端代码改了,文档没有同步;前端需要接口定义时,要反复复制粘贴;接口路径变更后,Apifox 中还会残留旧接口。
本文介绍一套可落地的协同方案:
后端代码
↓ 编译 / 生成
openapi.json
↓
AI
├─ Apifox MCP:读取、查询接口文档
└─ PowerShell 脚本:调用 Apifox Open API 回写
↓
Apifox:接口文档、Mock、调试和状态管理
这套方案的关键点是:MCP 负责“读”,脚本负责“写”,AI 负责编排整个流程。
一、整体架构
1. 后端代码
后端代码是接口实现的真实来源。接口完成开发后,需要先完成编译,并通过项目中的工具或插件生成最新的 OpenAPI 文件。

后端项目结构与编译入口
2. OpenAPI 文件
openapi.json 是后端接口的标准化描述文件,通常包含:
- HTTP 请求方法;
- 接口路径;
- Query、Path、Header 和 Body 参数;
- 请求体和响应结构;
- 接口描述和
operationId; - 接口目录、状态等扩展信息。
它是代码接口和 Apifox 文档之间的中间数据源。
3. Apifox
Apifox 是团队最终使用的接口协作平台,负责:
- 保存接口文档;
- 发布在线文档;
- 提供 Mock;
- 调试接口;
- 供前端和 AI 查询接口定义;
- 管理接口状态和废弃接口。
二、生成 OpenAPI 文件
首先使用 Apifox 插件或项目既有工具刷新接口,确认后端接口已经被识别。

Apifox 插件识别后端接口
然后选择导出 OpenAPI JSON:

导出 OpenAPI JSON
确认文件已经生成到项目约定目录:

项目目录中的 openapi.json
本文示例路径为:
E:\javaproject\plant-identifier\openapi.json
可以先验证 JSON 格式:
Get-Content -Raw -LiteralPath "E:\javaproject\plant-identifier\openapi.json" | ConvertFrom-Json | Out-Null
Write-Host "JSON OK"
注意:如果只修改了后端代码,却没有重新生成 openapi.json,后续脚本同步的仍然是旧接口定义。
三、配置 Apifox MCP
1. MCP 的作用
当前 Apifox MCP 主要负责读取和查询:
- 读取 Apifox 项目的 OpenAPI 文档;
- 查询项目接口列表;
- 查询接口请求参数和响应结构;
- 让 AI 了解 Apifox 中已有的接口;
- 为前端开发和 AI 编码提供接口定义。
MCP 当前不负责把本地 openapi.json 直接写回 Apifox,回写动作由后面的 PowerShell 脚本完成。
2. 在 Trae 中添加 MCP
进入:
AI 侧栏 → 设置 → MCP → 添加 MCP Servers → 手动配置

Trae 设置中的 MCP 入口

MCP 页面中的手动配置入口
配置示例:
{
"mcpServers": {
"apifox": {
"command": "npx",
"args": [
"-y",
"apifox-mcp-server@latest",
"--project=8702461"
],
"env": {
"APIFOX_ACCESS_TOKEN": "你的新 Token"
}
}
}
}
其中:
| 配置项 | 作用 |
|---|---|
mcpServers |
MCP 服务配置根对象 |
apifox |
MCP 服务名称,可以自定义 |
command |
使用 npx 启动 MCP 服务 |
apifox-mcp-server@latest |
Apifox MCP Server 包 |
--project=8702461 |
指定 Apifox 项目 ID |
APIFOX_ACCESS_TOKEN |
Apifox API 访问令牌 |
3. 获取项目 ID和 Token
项目 ID 可以在 Apifox 项目设置的基本设置中查看:

Apifox 项目基本设置中的项目 ID
API Token 可以在账号设置中的 API 访问令牌页面创建:

Apifox 账号设置中的 API 访问令牌
Token 所属账号必须有目标项目的相应权限。需要注意:读取文档和导入回写所需的权限可能不同,执行导入时通常需要项目维护者或管理员权限。
安全建议:
- 不要把真实 Token 提交到 Git;
- 不要把 Token 写入博客、截图或聊天记录;
- 团队协作时,建议使用本机环境变量;
- Token 泄露后应立即删除并重新生成。
4. 验证 MCP
在 Trae 中对 AI 说:
请通过 Apifox MCP 获取当前项目的 API 文档,并告诉我项目中有多少个接口。
如果 AI 能够返回接口数量、目录或接口详情,说明 MCP 已连接。
四、配置 Apifox 回写脚本
1. 脚本的作用
apifox-import.ps1 负责完成 MCP 不负责的“写入”动作:
- 读取本地
openapi.json; - 调用 Apifox 的
import-openapiOpen API; - 使用
AUTO_MERGE创建或更新接口; - 同步接口目录;
- 导出 Apifox 当前接口并与本地接口进行比对;
- 找出本地已经不存在的旧接口;
- 将旧接口标记为
deprecated; - 输出创建、更新、废弃和失败数量。
2. 脚本文件和参数
![]()
项目中的 apifox-import.ps1 脚本
示例配置:

脚本参数与项目配置
脚本中固定的项目配置类似:
$ProjectId = "8702461"
$OpenApiFile = "E:\javaproject\plant-identifier\openapi.json"
Token 建议通过环境变量 APIFOX_ACCESS_TOKEN 提供。脚本如果读取不到 Token,可以在终端中安全输入。
五、日常同步流程
完整流程如下:
- 修改后端接口代码;
- 编译并验证后端项目;
- 重新生成
openapi.json; - 让 AI 校验 OpenAPI JSON;
- 必要时通过 MCP 查询 Apifox 中已有接口;
- 执行回写脚本;
- 查看同步结果;
- 确认 Apifox 文档和前端联调结果。
让 AI 执行脚本:
powershell -ExecutionPolicy Bypass `
-File "E:\javaproject\apifox-import.ps1"
也可以直接对 AI 说:
请修改后端接口代码,重新生成 openapi.json,校验 JSON 格式,然后执行 E:\javaproject\apifox-import.ps1。
执行完成后汇报 endpointCreated、endpointUpdated 和 endpointFailed。
六、AUTO_MERGE 是什么
脚本使用:
endpointOverwriteBehavior = "AUTO_MERGE"
它按照“HTTP 方法 + 接口路径”匹配接口:
POST /api/auth/login ≠ POST /api/auth/login1
GET /api/user ≠ POST /api/user
行为如下:
- 本地有、Apifox 没有:创建接口;
- 两边方法和路径相同:合并更新接口;
- 方法或路径变化:会被视为新接口;
- 不会自动删除路径变化前的旧接口。
AUTO_MERGE 适合日常同步,可以尽量保留 Apifox 中已有的 Mock、示例和手工说明。
七、目录同步
脚本中的:
updateFolderOfChangedEndpoint = $true
表示接口所属目录发生变化时,自动将接口移动到新目录。
它只负责目录同步,不负责:
- 判断两个不同路径是不是同一个接口;
- 删除旧接口;
- 标记旧接口废弃。
八、旧接口如何处理
如果接口从代码和 openapi.json 中删除,但 Apifox 中仍然存在,脚本会将它识别为候选旧接口。
第一次建议只预览,不修改:
powershell -ExecutionPolicy Bypass `
-File "E:\javaproject\apifox-import.ps1"
确认列出的接口确实应该废弃后,再执行:
powershell -ExecutionPolicy Bypass `
-File "E:\javaproject\apifox-import.ps1" `
-AutoDeprecateMissing
脚本会将这些接口标记为:
"x-apifox-status": "deprecated"
不会直接删除接口。推荐采用两阶段策略:
新接口上线
↓
旧接口标记 deprecated
↓
前端迁移并观察兼容期
↓
确认无依赖后人工删除旧接口
九、让 AI 执行完整协同流程
可以直接使用下面的指令:
请完成以下流程:
1. 修改后端接口代码;
2. 重新生成或更新 openapi.json;
3. 校验 OpenAPI JSON 格式;
4. 通过 Apifox MCP 查询相关接口;
5. 执行 E:\javaproject\apifox-import.ps1;
6. 先报告 Apifox 中存在、本地 OpenAPI 中不存在的接口;
7. 我确认后再追加 -AutoDeprecateMissing;
8. 最后汇报新增、更新、废弃和失败数量。
如果确认可以自动废弃:
请修改后端代码并更新 openapi.json,然后执行:
powershell -ExecutionPolicy Bypass -File "E:\javaproject\apifox-import.ps1" -AutoDeprecateMissing
不要删除接口,最后汇报新增、更新、废弃和失败数量。
十、同步结果怎么看
| 字段 | 含义 |
|---|---|
endpointCreated |
新创建的接口数量 |
endpointUpdated |
更新的已有接口数量 |
endpointFailed |
失败的接口数量 |
schemaCreated |
新创建的数据模型数量 |
schemaUpdated |
更新的数据模型数量 |
schemaIgnored |
已存在、无需更新的数据模型数量 |
| 废弃数量 | Apifox 有、本地 OpenAPI 没有并被标记为 deprecated 的接口数量 |
正常情况下,重点关注:
endpointFailed = 0
如果 endpointCreated = 0、endpointUpdated = 0,不一定是失败,也可能是两边接口已经完全一致。
十一、常见问题
AI 新建接口而不是更新
检查 HTTP 方法和路径是否完全一致。例如:
POST /api/auth/login
POST /api/auth/login1
这两个接口会被视为不同接口。
403012:No project maintainer privilege
Token 所属账号没有项目维护者权限。需要使用有权限的账号生成 Token,或调整项目成员权限。
404000:Not found
检查项目 ID 是否正确,以及当前 PowerShell 会话中的变量是否为空。
废弃数量正确,但客户端没有删除线
客户端列表不一定展示删除线。刷新 Apifox 在线文档,并查看接口状态是否为“将废弃”。
中文提示乱码
PowerShell 脚本可能因为文件编码造成中文提示乱码。乱码一般不影响接口请求;可以将脚本提示改成英文,或将脚本保存为 UTF-8 编码。
十二、安全与检查清单
- [ ] 后端代码已编译通过;
- [ ]
openapi.json已重新生成; - [ ] OpenAPI JSON 格式有效;
- [ ] MCP 可以查询 Apifox 项目;
- [ ] 脚本返回
endpointFailed = 0; - [ ] 新增和更新数量符合预期;
- [ ] 疑似旧接口清单已经人工确认;
- [ ] 废弃接口没有被直接删除;
- [ ] Token 没有提交到仓库、截图或文章中。
总结
这套方案可以概括为:
> OpenAPI 是代码侧接口定义,Apifox 是团队协作与交付平台,MCP 负责读取,脚本负责回写,AI 负责把这些动作串起来。
以后每次接口开发完成,只需要确保 openapi.json 更新,然后让 AI 执行同步脚本即可。
附录:
apifox-import.ps1
param(
[string]$Token = $env:APIFOX_ACCESS_TOKEN,
[switch]$AutoDeprecateMissing
)
$ErrorActionPreference = "Stop"
$ProjectId = "8702461"
$OpenApiFile = "E:\javaproject\plant-identifier\openapi.json"
$ApiVersion = "2024-03-28"
$BaseUrl = "https://api.apifox.com/v1/projects/$ProjectId"
$HttpMethods = @(
"get",
"post",
"put",
"delete",
"patch",
"head",
"options",
"trace"
)
if ([string]::IsNullOrWhiteSpace($Token)) {
$secureToken = Read-Host "Enter Apifox token" -AsSecureString
$Token = [System.Net.NetworkCredential]::new("", $secureToken).Password
}
if ([string]::IsNullOrWhiteSpace($Token)) {
throw "No Apifox token was provided."
}
if (!(Test-Path -LiteralPath $OpenApiFile -PathType Leaf)) {
throw "OpenAPI file not found: $OpenApiFile"
}
$Headers = @{
Authorization = "Bearer $Token"
"X-Apifox-Api-Version" = $ApiVersion
}
function Get-EndpointKey {
param(
[string]$Path,
[string]$Method
)
return "$($Method.ToUpperInvariant()) $Path"
}
function Get-EndpointKeys {
param(
$Document
)
$keys = @{}
if ($null -eq $Document.paths) {
return $keys
}
foreach ($pathProperty in $Document.paths.PSObject.Properties) {
$path = $pathProperty.Name
$pathItem = $pathProperty.Value
foreach ($method in $HttpMethods) {
$operationProperty = $pathItem.PSObject.Properties[$method]
if ($null -ne $operationProperty -and $null -ne $operationProperty.Value) {
$key = Get-EndpointKey -Path $path -Method $method
$keys[$key] = $true
}
}
}
return $keys
}
function Import-OpenApi {
param(
$Document,
[ValidateSet(
"AUTO_MERGE",
"OVERWRITE_EXISTING",
"KEEP_EXISTING",
"CREATE_NEW"
)]
[string]$OverwriteBehavior = "AUTO_MERGE"
)
$specText = $Document | ConvertTo-Json -Depth 100 -Compress
$payloadObject = @{
input = $specText
options = @{
endpointOverwriteBehavior = $OverwriteBehavior
updateFolderOfChangedEndpoint = $true
}
}
$payload = $payloadObject | ConvertTo-Json -Depth 100 -Compress
return Invoke-RestMethod `
-Method Post `
-Uri "$BaseUrl/import-openapi?locale=zh-CN" `
-Headers $Headers `
-ContentType "application/json; charset=utf-8" `
-Body $payload `
-TimeoutSec 120
}
function Export-ApifoxOpenApi {
$exportPayloadObject = @{
scope = @{
type = "ALL"
}
options = @{
includeApifoxExtensionProperties = $true
addFoldersToTags = $false
}
oasVersion = "3.0"
exportFormat = "JSON"
}
$exportPayload = $exportPayloadObject | ConvertTo-Json -Depth 20 -Compress
return Invoke-RestMethod `
-Method Post `
-Uri "$BaseUrl/export-openapi?locale=zh-CN" `
-Headers $Headers `
-ContentType "application/json; charset=utf-8" `
-Body $exportPayload `
-TimeoutSec 120
}
Write-Host "Reading local OpenAPI..."
$localSpecText = [System.IO.File]::ReadAllText($OpenApiFile)
$localSpec = $localSpecText | ConvertFrom-Json
Write-Host "Importing local OpenAPI with AUTO_MERGE..."
$importResult = Import-OpenApi `
-Document $localSpec `
-OverwriteBehavior "AUTO_MERGE"
Write-Host ""
Write-Host "Local OpenAPI import result:"
$importResult | ConvertTo-Json -Depth 20
Write-Host ""
Write-Host "Exporting current Apifox OpenAPI..."
$apifoxSpec = Export-ApifoxOpenApi
$localKeys = Get-EndpointKeys -Document $localSpec
$missingEndpoints = @()
if ($null -ne $apifoxSpec.paths) {
foreach ($pathProperty in $apifoxSpec.paths.PSObject.Properties) {
$path = $pathProperty.Name
$pathItem = $pathProperty.Value
foreach ($method in $HttpMethods) {
$operationProperty = $pathItem.PSObject.Properties[$method]
if ($null -eq $operationProperty -or $null -eq $operationProperty.Value) {
continue
}
$key = Get-EndpointKey -Path $path -Method $method
if (!$localKeys.ContainsKey($key)) {
$missingEndpoints += [PSCustomObject]@{
Method = $method.ToUpperInvariant()
Path = $path
Key = $key
}
}
}
}
}
Write-Host ""
Write-Host "Endpoints existing in Apifox but missing from local OpenAPI: $($missingEndpoints.Count)"
if ($missingEndpoints.Count -eq 0) {
Write-Host "No deprecated candidates found."
Write-Host "Completed."
exit 0
}
$missingEndpoints | Format-Table Method, Path -AutoSize
if (!$AutoDeprecateMissing) {
Write-Host ""
Write-Host "Preview only. No endpoint status was changed."
Write-Host "To mark these endpoints as deprecated, run:"
Write-Host "powershell -ExecutionPolicy Bypass -File `"$PSCommandPath`" -AutoDeprecateMissing"
exit 0
}
Write-Host ""
Write-Host "Preparing deprecated endpoint update..."
$deprecatedPaths = [ordered]@{}
foreach ($item in $missingEndpoints) {
$pathProperty = $apifoxSpec.paths.PSObject.Properties[$item.Path]
if ($null -eq $pathProperty) {
continue
}
$pathItem = $pathProperty.Value
$methodName = $item.Method.ToLowerInvariant()
$operationProperty = $pathItem.PSObject.Properties[$methodName]
if ($null -eq $operationProperty) {
continue
}
$operation = $operationProperty.Value
$statusProperty = $operation.PSObject.Properties["x-apifox-status"]
if ($null -eq $statusProperty) {
$operation | Add-Member `
-NotePropertyName "x-apifox-status" `
-NotePropertyValue "deprecated" `
-Force
}
else {
$statusProperty.Value = "deprecated"
}
$marker = "[Deprecated: missing from local OpenAPI]"
$descriptionProperty = $operation.PSObject.Properties["description"]
if ($null -eq $descriptionProperty) {
$operation | Add-Member `
-NotePropertyName "description" `
-NotePropertyValue $marker `
-Force
}
elseif ([string]$descriptionProperty.Value -notlike "*Deprecated: missing from local OpenAPI*") {
$descriptionProperty.Value = "$($descriptionProperty.Value)`n`n$marker"
}
if (!$deprecatedPaths.Contains($item.Path)) {
$deprecatedPaths[$item.Path] = [ordered]@{}
}
$deprecatedPaths[$item.Path][$methodName] = $operation
}
$deprecatedSpec = [ordered]@{
openapi = "3.0.0"
info = [ordered]@{
title = "Deprecated endpoint updates"
version = "1.0.0"
}
paths = $deprecatedPaths
}
if ($null -ne $apifoxSpec.components) {
$deprecatedSpec.components = $apifoxSpec.components
}
if ($null -ne $apifoxSpec.servers) {
$deprecatedSpec.servers = $apifoxSpec.servers
}
Write-Host "Updating deprecated endpoints with OVERWRITE_EXISTING..."
$deprecatedResult = Import-OpenApi `
-Document $deprecatedSpec `
-OverwriteBehavior "OVERWRITE_EXISTING"
Write-Host ""
Write-Host "Deprecated endpoint update result:"
$deprecatedResult | ConvertTo-Json -Depth 20
Write-Host ""
Write-Host "Deprecated endpoints:"
$missingEndpoints | Format-Table Method, Path -AutoSize
Write-Host ""
Write-Host "Completed."
更多推荐


所有评论(0)