一个本地 stdio MCP Server:使用项目 token 或账号 Cookie 只读查询 YApi 项目、分类和接口文档,并通过“先预览、后应用”按分类生成确定性的 TypeScript/JavaScript 请求函数与类型。
运行时不会修改 YApi;它只会在明确执行 api_apply_generation 后写入本地受管文件。每个业务项目在自身根目录保存 YApi 配置和凭据,因此只需在 Codex 全局注册一次 MCP 服务。
- Node.js 20 或更高版本
- 可访问目标 YApi 实例
- YApi 项目 token,或账号登录态中的
_yapi_token与_yapi_uidCookie
cd E:\GitHub\api-mcp
pnpm install
pnpm build在 ~/.codex/config.toml 中只添加一次下面的全局配置。不要设置 cwd、--config、环境变量 token 或 env_vars:
[mcp_servers.api-mcp]
command = "node"
args = ['E:\GitHub\api-mcp\dist\cli.js', '--workspace-mode']
startup_timeout_sec = 20
tool_timeout_sec = 120
default_tools_approval_mode = "writes"然后在每个业务项目根目录创建 api-mcp.config.mjs 或 api-mcp.config.json。从示例复制:
copy E:\GitHub\api-mcp\api-mcp.config.example.mjs api-mcp.config.mjs每次源码变更后都执行 pnpm build,重启 Codex,并用 /mcp 确认服务已连接。
使用前检查:
- 只在
~/.codex/config.toml配置一条带--workspace-mode、不含cwd的 stdio 服务。 - 每个业务项目根目录只放一个
api-mcp.config.mjs或.json。 - 认证可使用
projects[].token,或服务器级 Cookie;不支持tokenEnv或env_vars。 - 实际生成目录固定为
<output.dir>/<project.id>。 - 把真实的
api-mcp.config.*加入业务仓库的.gitignore。 - 先执行 preview,再执行 apply;计划有效期为十分钟。
服务只在 stdout 写 MCP 协议消息,诊断信息写 stderr,并对 token、Authorization、Cookie 等敏感值脱敏。
如果只想将服务绑定到一个固定项目,可直接在终端运行:
node E:\GitHub\api-mcp\dist\cli.js --config /absolute/path/api-mcp.config.json在 --workspace-mode 下,服务仅在工具调用给出的业务项目根目录查找以下文件之一:api-mcp.config.js、.mjs、.cjs 或 .json。不能缺失,也不能同时存在多个。.mjs 和 ESM .js 使用 export default;.cjs 使用 module.exports;JSON 不执行代码。
--workspace-mode 要求 workspaceRoot 保持默认 "."(或解析后与调用的项目根目录相同),避免配置将生成目标带出当前项目。固定 --config 模式仍可按配置文件解析该字段。所有 output.dir 都相对有效 workspace,不能是绝对路径、包含 ..,或通过符号链接越界。不同项目不能共用输出目录。项目 ID 必须是安全路径段,生成目录自动追加项目 ID。
type ProjectTokenAuth = {
projects: Array<{
id: string
token: string
categories?: { include?: 'all' | number[]; exclude?: number[] }
}>
auth?: never
discovery?: never
}
type AccountCookieAuth = {
projects?: never
auth: {
type: 'cookie'
cookie: string // 必须包含 _yapi_token 与 _yapi_uid
}
discovery?: {
include?: 'all' | number[] // YApi 数字项目 ID,默认 "all"
exclude?: number[] // 默认 []
}
}
interface YapiMcpConfig {
workspaceRoot?: string // 默认 "."
cacheTtlMs?: number // 默认 60_000
requestTimeoutMs?: number // 默认 10_000
servers: Array<({
id: string
url: string
output: {
dir: string
language?: 'ts' | 'js' // 默认 "ts"
aiManifest?: string | false // 默认 "api-manifest.json"
requestAdapter: { module: string; export?: 'default' | string }
dataKey?: string | string[]
queryArrayFormat?: 'brackets' | 'indices' | 'repeat' | 'comma' | 'json'
barrel?: string | false // TS 默认 "index.ts",JS 默认 "index.js"
}
} & (ProjectTokenAuth | AccountCookieAuth))>
}推荐在业务项目根目录新建 api-mcp.config.mjs。下面是 TypeScript 输出的完整配置;将 token 替换为对应 YApi 项目的项目 token,并将 adapter 模块路径改为业务项目实际路径:
export default {
workspaceRoot: '.',
servers: [
{
id: 'company-yapi',
url: 'https://yapi.example.com',
output: {
dir: 'src/generated',
language: 'ts',
aiManifest: 'api-manifest.json',
requestAdapter: {
module: '@/utils/request',
export: 'default',
},
dataKey: ['data'],
queryArrayFormat: 'brackets',
barrel: 'index.ts',
},
projects: [
{
id: 'web-api',
token: '你的 YApi 项目 token',
categories: { include: 'all', exclude: [] },
},
],
},
],
}同一个 YApi 服务下的多个项目共用 output 与 adapter;每个项目只配置自己的 id、token、分类筛选。不同 server 可各自配置一套 output。id 在整个配置文件内必须唯一。
如果不想逐个维护项目 token,可改为服务器级 Cookie:
export default {
workspaceRoot: '.',
servers: [
{
id: 'company-yapi',
url: 'https://yapi.example.com',
auth: {
type: 'cookie',
cookie: '_yapi_token=替换为登录Cookie; _yapi_uid=替换为用户ID',
},
discovery: {
include: 'all',
exclude: [100, 200],
},
output: {
dir: 'src/generated',
language: 'ts',
aiManifest: 'api-manifest.json',
requestAdapter: { module: '@/utils/request', export: 'default' },
queryArrayFormat: 'brackets',
barrel: 'index.ts',
},
},
],
}Cookie 模式会读取账号可见分组及其项目,并按 discovery 过滤。发现出的 MCP 项目标识就是 YApi 数字项目 ID,例如 291;输出目录为 src/generated/project-291。Cookie 与 projects 互斥,不能在同一个 server 中同时配置。
JavaScript 项目只需切换输出语言和 barrel 扩展名:
output: {
dir: 'src/generated',
language: 'js',
aiManifest: 'api-manifest.json',
requestAdapter: { module: '@/utils/request', export: 'default' },
queryArrayFormat: 'brackets',
barrel: 'index.js',
}可以省略 language、aiManifest、queryArrayFormat 和 barrel,默认值分别为 'ts'、'api-manifest.json'、'brackets'、TS 的 'index.ts' 或 JS 的 'index.js'。barrel: false 会禁用入口文件,aiManifest: false 会禁用清单。barrel 必须使用与语言相同的扩展名,manifest 必须是相对 .json 路径。
例如,output.dir: 'src/generated' 且项目 id: 'web-api' 时,生成位置为 src/generated/web-api。一个 server 的 output 由其全部 projects 共用,而每个 project 只保留自己的 token 和分类筛选。
token 和 Cookie 都只适合受信任的本地业务仓库;Cookie 代表整个账号权限,风险高于单项目 token。不要将真实配置提交到版本控制。应在 .gitignore 中忽略四种 api-mcp.config.* 文件名。运行时会对完整 Cookie、token、Authorization 和敏感响应字段脱敏。
dataKey 同时影响生成的响应类型和运行时 descriptor。例如 dataKey: ["data", "items"] 会让响应类型指向 schema 的 data.items,并由 request adapter 在实际响应中解包相同路径。路径无法从 schema 解析时,响应类型回退到 unknown,preview 返回警告。
api_list_projects({ workspaceRoot, checkConnection? }):列出一个业务项目根目录中的安全项目元数据;可选择检查连接。api_list_categories({ workspaceRoot, project, refresh? }):列出配置过滤后的分类。api_search_interfaces({ workspaceRoot, project, query?, categoryIds?, methods?, statuses?, limit?, cursor?, refresh? }):搜索标题、路径、标签、方法和状态;limit为 1–100。api_resolve_url({ workspaceRoot, url, refresh? }):直接解析已配置项目中的 YApi 分类或接口链接,返回内容及可传给 preview 的 scope。api_get_interface({ workspaceRoot, project, interfaceId, refresh? }):获取归一化接口详情。api_preview_generation({ workspaceRoot, project, scope, includeDiff? }):计算目标文件、hash、冲突、警告、过期时间及可选 diff,不写文件。api_apply_generation({ planId }):重新校验配置、YApi 源数据和目标 hash 后应用计划。
workspaceRoot 必须是 Codex 当前任务工作区的绝对路径;apply 根据 preview 创建的计划定位工作区,因此不能也不需要传递 workspaceRoot。
可以直接对 AI 说:
帮我看看
https://yapi.example.com/project/291/interface/api/cat_4047的接口内容。
AI 会调用 api_resolve_url。分类 URL(.../api/cat_<分类ID>)会返回分类信息、接口摘要及 { "kind": "categories", "ids": [分类ID] };单接口 URL(.../api/<接口ID>)会返回完整请求/响应 schema 及对应的 interfaces scope。随后 AI 应先解释接口内容;只有在你明确确认后,才调用 api_preview_generation,并在你确认 preview 后调用 api_apply_generation。
URL 的服务地址和 YApi 数字项目 ID 必须匹配某个已配置 token,或属于 Cookie 账号可见且未被 discovery 排除的项目。项目不匹配、权限不足、被筛选排除或 URL 格式无效时会返回稳定错误。
scope 必须是以下三种形式之一:
{ "kind": "interfaces", "ids": [101, 102] }
{ "kind": "categories", "ids": [10, 11] }
{ "kind": "project" }选择单个接口仍会重新读取并生成它所属分类的完整 category-<id>.ts,不会意外覆盖同分类的其他接口。
默认 TypeScript 模式每个项目会生成:
request-types.ts:受管的 descriptor、adapter 和YapiFileData<T>类型。category-<id>.ts:该分类的完整接口类型和请求函数。index.ts(可配置或禁用):只导出本次生成范围包含的受管文件。api-manifest.json:供 AI 和业务代码检索的稳定操作清单,可改名或设为false禁用。
设置 output.language: 'js' 时生成 ESM:request-types.d.ts、category-<id>.js、配套的 category-<id>.d.ts、index.js 与 index.d.ts。JS 不依赖 TypeScript 运行时;类型信息只存在于 .d.ts。barrel 的扩展名必须与语言一致。
业务开发时优先读取生成目录的 api-manifest.json:它列出每个接口的函数名、导入入口、请求/响应类型、参数部分和 YApi 链接。应导入其中的函数复用,而不是重新手写 HTTP 请求。
文件不包含时间戳;分类、接口与声明顺序稳定。函数名固定以 api 开头,并由路径组成:GET /api/users/{id} 生成 apiUsersById;HTTP method 不参与命名,路径仍冲突时追加 interface ID。
每个生成函数均为箭头函数,接收 descriptor 形式的 requestData 及可选 ...args。基础 descriptor 会保留全部固定字段,随后以 Object.assign(descriptor, requestData) 合并调用数据,再将额外参数原样传给 adapter:
export const apiUsersById = (requestData, ...args) =>
requestAdapter(Object.assign(descriptor, requestData), ...args)TypeScript 会生成对应的 ApiUsersByIdRequestData 类型:它保留 YapiRequestDescriptor 的字段,并将 pathParams、query、headers、body 收窄到接口文档定义的类型。
preview 生成随机 planId,默认 10 分钟有效。apply 不接受未经 preview 的写入,并会拒绝:
- 没有 managed marker 或 marker 不属于同项目/来源的目标文件;
- preview 后变化的 YApi 数据、配置或目标文件;
- workspace 外路径及越界符号链接。
不再出现在当前生成范围的旧分类文件只会列入 staleFiles,不会自动删除;barrel 也不再导出它们。TS/JS 切换产生的旧受管文件同样只报告为 stale,绝不自动删除。
常见稳定错误码包括 CONFIG_INVALID、CONFIG_NOT_FOUND、CONFIG_AMBIGUOUS、WORKSPACE_INVALID、YAPI_HTTP_ERROR、YAPI_API_ERROR、YAPI_TIMEOUT、PLAN_EXPIRED、PLAN_STALE、PATH_OUTSIDE_WORKSPACE、UNMANAGED_FILE_CONFLICT 和 WRITE_PARTIAL。
业务侧 adapter 接收以下 descriptor,并返回解包后的响应:
interface YapiRequestDescriptor<TBody = unknown> {
method: string
path: string
pathParams?: Record<string, unknown>
query?: Record<string, unknown>
headers?: Record<string, unknown>
body?: TBody
requestBodyType: string
responseBodyType: string
dataKey?: string[]
queryArrayFormat: string
metadata: {
projectId: number
categoryId: number
interfaceId: number
title: string
yapiUrl: string
}
extraInfo: {
name: string // 接口名称
creator: string // 创建人
updatedAt: string // 中国标准时间,格式 YYYY-MM-DD HH:mm:ss
remark: string // 接口备注
}
}
type YapiRequestAdapter = <TResponse>(
descriptor: YapiRequestDescriptor,
...args: unknown[]
) => Promise<TResponse>examples/request-adapter.ts 提供了基于 fetch 的参考实现,包括 path 参数、五种 query 数组格式、JSON、表单、上传以及 dataKey 解包。生成器只导入配置指定的 adapter,不执行任何配置回调或外部命令。
pnpm install
pnpm lint
pnpm typecheck
pnpm run typecheck:examples
pnpm test
pnpm build
pnpm run pack:dry-run测试覆盖双认证配置、敏感值脱敏、账号项目发现、YApi 错误/超时/分页/缓存、schema 推断、生成代码编译、preview/apply 冲突与 stale 文件策略,以及真实子进程 stdio 上的全部 MCP 工具。
使用 MCP Inspector 做交互式冒烟测试:
npx @modelcontextprotocol/inspector node ./dist/cli.js --workspace-mode- yapi-to-typescript handbook:多项目配置、类型生成和统一请求适配器设计。
- YApi OpenAPI:只读项目与接口文档端点。
- MCP TypeScript SDK server guide:stdio Server 与 tools 接口。
MIT