普通视图

发现新文章,点击刷新页面。
今天 — 2026年2月9日首页

一句话生成整套 API:我用 Claude Code 自定义 Skill + MCP 搞了个接口代码生成器

作者 jerrywus
2026年2月9日 10:24

一句话生成整套 API:我用 Claude Code 自定义 Skill + MCP 搞了个接口代码生成器

从 Swagger 文档到 TypeScript 类型、API 函数、Mock 数据,一句指令全自动。

前言

做前端的应该都经历过这种事:

后端丢来一个 Swagger 链接,然后你得:

  1. 打开文档,一个个看接口定义
  2. 手写 TypeScript 类型(请求参数、响应结构)
  3. 写 API 调用函数
  4. 造 Mock 数据给本地开发用
  5. 注册 Mock 路由

一个模块少说 2-3 个接口,这些重复劳动能耗掉半天。

后来我想,这活儿能不能自动化?于是折腾了一套方案,现在只要一句话:

实现接口:https://gateway.xxx.cn/doc.html#/组织架构服务/供应商管理/page_1

Claude Code 会自己打开 Swagger 文档、提取接口信息、让你勾选要实现哪些接口,然后并行生成所有代码。

这篇文章记录一下整个搭建过程和实际跑起来的效果。

整体架构

先看全貌,方案分三块:

┌─────────────────────────────────────────────────┐
│                  api-add Skill                   │
│              (工作流编排 / 入口)                    │
├─────────────────────────────────────────────────┤
│                                                  │
│  ┌──────────────────┐                            │
│  │ chrome-devtools   │  ← 读取 Swagger 文档       │
│  │      MCP          │  ← 提取接口信息             │
│  └──────────────────┘                            │
│           │                                      │
│           ▼                                      │
│  ┌──────────────────────────────────┐            │
│  │        Agent Team (并行)          │            │
│  │  ┌────────────┐ ┌─────────────┐  │            │
│  │  │ api-define │ │ mock-create │  │            │
│  │  │  (Haiku)   │ │  (Haiku)    │  │            │
│  │  │            │ │             │  │            │
│  │  │ TS 类型    │ │ Mock 数据    │  │            │
│  │  │ API 函数   │ │ Mock 路由    │  │            │
│  │  └────────────┘ └─────────────┘  │            │
│  └──────────────────────────────────┘            │
│                                                  │
└─────────────────────────────────────────────────┘
  • Skill:自定义技能,定义工作流怎么跑
  • MCP (Model Context Protocol):让 AI 能操控浏览器,直接读文档
  • Agent Team:两个 Agent 同时干活,一个写类型和 API,一个写 Mock

下面一个个说。

一、Chrome DevTools MCP -- 让 AI "看见"浏览器

MCP 是什么?

MCP(Model Context Protocol)是 Anthropic 出的一个开放协议,让 AI 能跟外部工具交互。简单说就是 AI 的插件系统,接上不同的 MCP Server,AI 就多了一种能力。

为什么要用 Chrome DevTools MCP?

Swagger/Knife4j 文档是动态渲染的 SPA 页面。你用 fetchcurl 去请求,拿到的只是一个空壳 HTML,接口信息全靠 JS 渲染出来,根本抓不到。

Chrome DevTools MCP 能让 AI 操控一个真实的浏览器:

  • 打开页面,等 JS 渲染完
  • 读取页面的可访问性树(Accessibility Tree)
  • 点击元素、做页面交互

说白了就是让 AI 能像人一样看网页。

怎么配置

在 Claude Code 里添加 chrome-devtools MCP server:

chrome devtools mcp github 地址

  • 打开 github 项目页面,找到 Claude Code 的配置指令。进入项目根目录,终端执行:
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
  • 然后在项目 .claude 目录下创建 mcp.json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "-y",
        "chrome-devtools-mcp@latest"
      ]
    }
  }
}

配好之后 Claude Code 就能操作浏览器了,主要用到这几个工具:

工具 干什么的
navigate_page 打开指定 URL
take_snapshot 获取页面快照(可访问性树)
click 点击页面元素
fill 填写表单
take_screenshot 截图

我们这个场景主要用前三个:导航、快照、点击。

二、api-add Skill -- 工作流编排

Skill 是什么?

Claude Code 的 Skill 就是一个 Markdown 文件,告诉 AI 碰到什么情况该怎么做。里面写清楚:

  • 什么时候触发
  • 按什么步骤执行
  • 有什么限制

文件放在 .claude/skills/<skill-name>/SKILL.md,Claude Code 启动时会自动加载。

api-add Skill 怎么设计的

我想要的效果是:给一个 Swagger URL,自动把接口文档变成可用的代码。

.claude/skills/api-add/SKILL.md
---
name: api-add
description: 从 Swagger 文档或 md 文档快速创建 API function、
  TypeScript 类型定义和 Mock 实现。
  触发关键词:实现接口、创建接口、添加API、接口定义。
---

# API from Swagger Doc

## skill 触发场景

### 场景1
用户提供接口 url,并说实现接口定义

### 场景2
用户指定一个 md 文档,则直接从文档中读取接口定义

## 工作流程

### 第一步:获取接口信息

使用 chrome-devtools-mcp 读取 Swagger 文档:

1. 使用 navigate_page 打开 Swagger URL
2. 使用 take_snapshot 读取页面内容
3. 展开左侧菜单,获取当前分类下的所有接口列表
4. 使用 AskUserQuestion,列出所有接口供用户选择
5. 用户确认后,逐一点击并提取完整信息

### 第二步:创建 Agent Team 并行生成代码

创建 2 个 teammate 分别负责:
- api-define:TypeScript 类型 + API 函数
- mock-create:Mock 数据 + Mock 路由

### 第三步:清除 teams 并结束

这里说几个我做的选择:

1. 为什么用 MCP 而不是直接请求 API?

Swagger 文档是前端渲染的 SPA,HTTP 请求拿不到内容。必须在真实浏览器里跑一遍 JS 才能看到接口信息。

2. 为什么要让用户选接口?

一个模块可能有十几个接口,但这次迭代可能只用到其中两三个(或者部分接口已经实现过了)。让用户自己勾选,省得生成一堆用不上(或者重复)的代码。

3. 为什么用 Agent Team?

写 TypeScript 类型/API 函数和写 Mock 数据/路由,这两件事互不依赖。让两个 Agent 同时跑,时间省一半。而且 Agent 用的是 Haiku 模型,比主模型便宜很多。

✏️ 我测试了一下,单独写⬆是6分钟多一点;使用agent teams 是4分钟多一点(因为是小功能, 时间节省不太明显, 但贵在省时间。 你可以尝试大功能,比如实现一个复杂的模块,时间节省会更明显)

三、Agent 定义 -- 分工干活

除了 Skill,还得定义两个 Agent,它们才是真正写代码的。

api-define Agent

.claude/agents/api-define.md
---
name: api-define
description: 实现指定模块的 api function & typescript 类型的创建
model: haiku
color: green
---

实现指定模块的 api function & typescript 类型的创建,
严格按以下要求实现:

1. 严格参照 .claude/rules/ 中的编码规范
2. 完整实现:TypeScript 类型、API 函数

mock-create Agent

.claude/agents/mock-define.md
---
name: mock-create
description: 实现指定 api 接口的 mock 实现
model: haiku
color: orange
---

实现指定 api 接口的 mock 实现,严格按以下要求实现:

1. 严格参照 .claude/rules/ 中的编码规范
2. 完整实现:Mock 服务器(mocks 目录),
   实现 Express 接口(routes、controllers、data)

几个值得说的点:

  • model: haiku -- 用轻量模型就够了,写这种模式化的代码不需要大模型,跑得快还省钱
  • "严格参照编码规范" -- 靠 .claude/rules/ 里的规则文件约束代码风格,后面会讲
  • color -- 终端里用不同颜色区分两个 Agent 的输出,看着方便

四、实战演示

来看实际跑一遍是什么样。我要给"供应商管理"模块实现接口。

Step 1:触发 Skill

只需要输入一句话:

实现接口:https://gateway.xxx.cn/doc.html#/组织架构服务/供应商管理/page_1

Claude Code 会自动识别到 api-add Skill,加载后通过 MCP 打开 Swagger 文档:

image.png

Step 2:读取文档,选择接口

AI 通过浏览器快照读到页面内容,找到左侧菜单里"供应商管理"下的所有接口,弹出选择框让我勾:

image.png

它做了这几件事:

  • 识别了左侧菜单的接口列表(POST 分页列表、GET 配置商户)
  • 点进每个接口 Tab,提取了完整的请求参数和响应结构
  • URL 指向的"分页列表"被标成了推荐选项

我两个都选了。

Step 3:Agent Team 并行干活

确认后,Claude Code 起了一个 Agent Team,两个 Agent 同时开工:

image.png

截图里能看到:

  • api-definer(绿色)在写 TypeScript 类型定义和 API 函数
  • mock-creator(橙色)在写 Mock 数据和路由
  • 两个同时跑,互不影响
  • 底部状态栏显示着两个 Agent 的运行状态

Step 4:完成,收工

两个 Agent 干完活,自动关闭并清理资源:

image.png

最终生成了这些文件:

# API & 类型定义
src/types/supply-company.ts          ← TypeScript 类型
src/api/supply-company/index.ts      ← API 函数

# Mock 实现
mocks/routes/data/supply-company-page.json    ← Mock 数据
mocks/routes/supply-company.controller.cjs    ← Mock 控制器
mocks/routes/org.cjs                          ← 路由挂载(已更新)

五、看看生成的代码

代码质量怎么样?直接贴。

TypeScript 类型定义

部分展示:

// src/types/supply-company.ts

/** 供应商分页查询参数 */
export interface ISupplyCompanyPageParam extends IPageParam {
  /** 供应商名称 */
  name?: string;
}

/** 供应商分页列表项 */
export interface ISupplyCompanyPageVO {
  /** 供应商组织id */
  orgId: number;
  /** 公司编码 */
  code: string;
  /** 供应商名称 */
  orgName: string;
  /** 负责人id */
  staffId: number;
  /** 负责人姓名 */
  userName: string;
  /** 状态 */
  status: string;
  /** 所属商户 */
  merchantName: string;
  /** 创建人 */
  creator: string;
  /** 创建时间 */
  createTime: string;
}

I 前缀、JSDoc 注释、继承 IPageParam,跟项目里手写的一模一样。

API 函数

部分展示:

// src/api/supply-company/index.ts

export async function querySupplyCompanyPage(
  params: ISupplyCompanyPageParam
) {
  let total = 0;
  let data = [] as ISupplyCompanyPageVO[];
  params = toConditional(params);

  try {
    const { code, context, message } = await Http.post<{
      total: number;
      data: ISupplyCompanyPageVO[];
    }>(`${baseUrl}/page`, { ...params });

    if (code !== EResponseCode.Succeed) {
      throw new Error(message || '服务器异常,请稍后再试~');
    }
    total = context?.total || 0;
    data = context?.data || [];
  } catch (error) {
    throw new Error(getHttpErrorMessage(error));
  }

  return { total, data };
}

项目里标准的 API 写法:async/await + try/catch + toConditional + 错误处理,一个不差。

Mock 数据

部分展示:

// mocks/routes/data/supply-company-page.json
[
  {
    "orgId": 1001,
    "code": "SC-2025-001",
    "orgName": "上海奢品供应链有限公司",
    "staffId": 2001,
    "userName": "张经理",
    "status": "ENABLED",
    "merchantName": "LuxMall旗舰店",
    "creator": "系统管理员",
    "createTime": "2025-01-15 10:30:00"
  }
  // ... 更多数据
]

Mock 数据的字段值是有意义的中文内容,不是那种 "string" 占位符。

Mock 控制器

部分展示:

// mocks/controllers/supply-company.controller.cjs

const express = require('express');
const router = express.Router();
const supplyCompanyList = require('./data/supply-company-list.json');

/**
 * 供应商分页列表
 * POST /page
 */
router.post('/page', (req, res) => {
  let all = JSON.parse(JSON.stringify(supplyCompanyList));
  const { page = 1, size = 50, name } = req.body || {};

  // 按供应商名称模糊搜索
  if (name) {
    all = all.filter((item) =>
      String(item.orgName).includes(String(name))
    );
  }

  const total = all.length;
  const start = (Number(page) - 1) * Number(size);
  const end = start + Number(size);
  const data = all.slice(start, end);

  res.json({
    code: 0,
    message: null,
    context: { total, data },
    traceId: '',
    spanId: '',
  });
});

module.exports = router;

分页、模糊搜索、标准响应格式,都按项目的 Mock 规范来的。

六、代码质量靠什么保证?Rules

你可能会想:AI 怎么知道我们项目的编码规范?

.claude/rules/ 目录。这是 Claude Code 的规则系统,你可以理解为给 AI 写了一份项目编码手册:

.claude/rules/
├── api.md           ← API 实现标准(函数命名、错误处理模式)
├── ts-define.md     ← TypeScript 规范(I前缀、E前缀、JSDoc)
├── mock.md          ← Mock 服务器架构(路由、控制器、数据文件)
├── components.md    ← 组件库参考
├── vue-single-file.md ← Vue SFC 标准
└── ...

每个 Agent 工作时都会读这些规则文件。所以生成出来的代码风格跟项目里手写的一致,不会出现那种一看就是 AI 写的通用代码。

七、想复刻?文件结构在这

如果你想在自己项目里搞一套,需要这些文件:

.claude/
├── agents/
│   ├── api-define.md          ← API 定义 Agent
│   └── mock-define.md         ← Mock 创建 Agent
├── skills/
│   └── api-add/
│       └── SKILL.md           ← 工作流编排 Skill
├── rules/
│   ├── api.md                 ← API 编码规范
│   ├── ts-define.md           ← TypeScript 规范
│   └── mock.md                ← Mock 规范
└── ...

# MCP 配置(项目级或全局)
.mcp.json                      ← Chrome DevTools MCP 配置

八、效果对比

维度 手动开发 api-add Skill
耗时 6.5m 4.3m
类型定义 手动从文档抄 自动提取,不会漏字段
API 函数 复制模板手动改 自动生成,符合规范
Mock 数据 手动编假数据 自动生成,内容像真的
代码规范 看个人习惯 Rules 强制约束
人为错误 字段名拼错、类型写错 从文档直接提取,基本不会错

总结

回头看,这套方案做了四件事:

  1. 用 MCP 让 AI 能读浏览器里的 Swagger 文档
  2. 用 Skill 把多步骤任务编排成一句话就能触发的流程
  3. 用 Agent Team 让两个轻量 Agent 并行干活,省时间也省钱
  4. 用 Rules 约束代码风格,保证生成的代码跟手写的一样

说到底就是把"从文档到代码"这个重复劳动自动化了。

这套方案也不只能用在 Swagger 上。改一下 Skill 的工作流,Apifox、Postman、自定义 Markdown 文档、GraphQL Schema,只要浏览器能打开的接口文档都能接。

如果你也在用 Claude Code,可以试试 Skill + MCP 这个组合。


觉得有用的话点个赞,也欢迎在评论区聊聊你的 Claude Code 玩法。

❌
❌