内容
<div align="center">
# API 笔记本
**本地优先、Git友好的API客户端** — 像Postman一样,但每个工作区都是一个可以提交、差异比较和共享的普通JSON和Markdown文件目录。
[](https://github.com/mbadaz/api-notebook/actions/workflows/ci.yml)
[](https://github.com/mbadaz/api-notebook/releases)
[](https://nodejs.org)
[](LICENSE)

</div>
## 目录
- [功能](#功能)
- [快速入门](#快速入门)
- [磁盘上的工作区布局](#磁盘上的工作区布局)
- [通过Git协作](#通过Git协作)
- [从Postman导入](#从Postman导入)
- [脚本(预请求和测试)](#脚本(预请求和测试))
- [Cookie](#Cookie)
- [MCP服务器(用于AI代理)](#MCP服务器(用于AI代理))
- [键盘快捷键](#键盘快捷键)
- [技术栈](#技术栈)
- [贡献](#贡献)
- [版本发布](#版本发布)
- [许可证](#许可证)
## 功能
### 请求和协议
- **HTTP和GraphQL请求**,带有参数、头部、正文模式(JSON、文本、URL编码表单、 multipart/form-data 带文件字段、二进制文件)和GraphQL查询/变量编辑器。文件正文通过路径引用,并在发送时读取;根据扩展名猜测Content-Type。
- **流协议** — WebSocket、Socket.IO和MCP(Streamable HTTP)请求类型。通过本地服务器建立连接(因此 `{{variables}}`、头部、身份验证和Cookie jar适用),带有实时消息日志和可重用的已保存消息/发出。MCP请求浏览服务器的工具,并通过每个工具的JSON模式生成的表单调用它们。
- **二进制安全响应**,带有下载按钮;非文本响应(图像、PDF、存档)保持完整。
- **身份验证助手**:Bearer令牌、基本身份验证、API密钥(头部或查询)。
- **无CORS问题** — 请求由本地Node服务器执行,返回状态、头部、正文、计时和大小。
### 自动化
- **脚本**:Postman兼容的预请求和后响应(测试)脚本,带有 `pm.*` API — 从响应设置环境变量,调整传出的请求,并编写 `pm.test`/`pm.expect` 断言。在请求、文件夹和集合级别工作 — 集合和文件夹脚本在它们下面的每个请求周围运行。
- **Cookie**:自动的每个工作区的Cookie jar捕获响应中的 `Set-Cookie` 并将匹配的Cookie附加到后续请求(尊重域名/路径/过期/安全);一个管理器允许您查看和清除它们,脚本可以通过 `pm.cookies` 读取它们。
### 环境和秘密
- **环境**(工作区级别),带有 `{{variable}}` 插值在URL、参数、头部、身份验证字段和正文中。活动环境存储在工作区之外,因此它永远不会污染您的仓库。
- **秘密变量**:标记一个变量 🔒,其值写入 `.local.json` 文件中 — 共享文件只声明名称,因此队友确切地看到他们需要本地填充哪些秘密。
### 本地优先和Git友好
- **工作区** 是您在磁盘上任意选择的文件夹(通过原生系统文件夹选择器或输入路径) — 通过将工作区设为Git仓库并推送到GitHub进行协作。在Linux上,选择器使用 `zenity` 或 `kdialog` 如果已安装。
- **Markdown文档** 在每个请求(存储为伴随的 `.md` 文件,因此它在GitHub上渲染)和每个集合上。
- **请求管理**:侧边栏项目上的悬停菜单,带有重命名、复制、粘贴(跨集合)、复制、删除;未保存的更改突出显示保存按钮,并在导航离开时提示。
### 导入和导出
- **Postman导入**:导入Postman集合或环境导出(集合v2.1.0) — 文件夹变为集合,请求保留其URL、参数、头部、身份验证和正文,描述变为Markdown文档,环境变量导入(Postman秘密进入 `.local.json`)。
- **cURL导入/导出**:将cURL命令粘贴到集合中以创建请求,或复制任何请求作为可运行的cURL命令,并解析变量。
### 用于AI代理
- **MCP服务器**:AI代理可以通过MCP查询、构建、运行和管理工作区 — 集合、请求、环境、执行和Postman导入 — 通过工作区上的Streamable-HTTP端点。
## 快速入门
```sh
npm install
npm run dev
```
打开 http://localhost:5173。 API服务器运行在 http://localhost:3001。
对于类似生产环境的单服务器(提供构建的UI和API):
```sh
npm run build
npm start # http://localhost:3001
```
## 磁盘上的工作区布局
```
my-workspace/
├── workspace.json # { id, name }
├── environments/
│ ├── dev.json # 共享变量 + 机密变量名
│ └── dev.local.json # 机密值 — gitignored,每个机器
└── collections/
└── users-api/
├── collection.json # { name, description }
└── requests/
├── get-user.json # method, url, params, headers, auth, body…
└── get-user.md # 请求的Markdown文档
```
> [!NOTE]
> 应用本地状态存储在 `~/.apinotebook/`(已注册的工作区列表和每个工作区的活动环境) — 机器特定的内容从不写入工作区文件夹。
## 通过Git协作
```sh
cd my-workspace
git init && git add . && git commit -m "Initial workspace"
gh repo create my-workspace --private --source . --push
```
队友克隆仓库,然后在API Notebook中选择 **打开现有文件夹…** 并指向克隆。拉取更改,提交和推送分享您的更改。 将凭证保存在标记为 🔒 机密的变量中:它们的值存储在 `.local.json` 文件中(每个工作区的 `.gitignore` 自动包含规则),因此仓库共享变量名,而每个队友提供自己的值。 克隆的工作区显示未填充的机密,带有“丢失”警告,并且它们的 `{{tokens}}` 突出显示红色,直到设置本地值。
## 从Postman导入
从Postman导出集合或环境(集合格式 **v2.1.0**),然后在API Notebook中单击侧边栏 **集合** 头部的 **⤓** 按钮。 选择 **导入文件…** 以选择单个 `.json` 导出,或 **导入文件夹…** 以递归导入文件夹中找到的每个集合/环境导出。 文件类型自动检测,所有内容导入到 **当前工作区**,因此请先打开或创建要导入到的工作区。
映射内容:
- **文件夹 → 文件夹。** Postman文件夹导入为可嵌套的文件夹,保存在集合中,保留原始层次结构。 位于集合根部的请求保留在命名为Postman集合的集合根部。
- **请求** 保留其方法、URL(查询字符串拆分为参数编辑器)、头部和身份验证(Bearer、Basic、API密钥)。 正文映射到原始JSON/文本、 `x-www-form-urlencoded` 、 multipart/form-data(包括文件字段,通过路径)、二进制文件和GraphQL。
- **描述 → Markdown文档** 在请求上。
- **脚本**:请求预请求/测试脚本导入到请求的 **预请求** / **测试** 标签页。 集合和文件夹级脚本也导入并在执行链中运行(集合 → 文件夹(s)→ 请求),因此它们仍然在每个请求周围运行(参见 [脚本](#脚本(预请求和测试)))。 脚本可能使用此应用未实现的Postman API;它们原样导入,并在运行时显示任何错误。
- **环境**:每个 `values` 条目成为变量。 Postman标记为 `secret` 的变量导入为 🔒 机密 — 名称进入共享环境文件,值进入 `.local.json`。
## 脚本(预请求和测试)
使用Postman兼容的JavaScript自动化请求。 每个请求都有一个 **预请求** 标签页(在发送前运行)和一个 **测试** 标签页(在响应到达后运行)。 最常见的用法是从响应中设置环境变量:
```js
// 测试(响应后)
const data = pm.response.json();
pm.environment.set("bearer_token", data.token); // 后续请求使用 {{bearer_token}}
pm.test("登录成功", () => pm.expect(pm.response.code).to.equal(200));
```
### 集合和文件夹脚本
脚本不仅存在于请求上 — **集合和文件夹具有相同的预请求和测试标签页**(单击侧边栏中的集合或文件夹以打开其编辑器)。 在那里设置的脚本围绕 **它下面的每个请求** 运行,这是共享设置(如刷新身份验证令牌或断言没有响应是5xx)的合适位置。
当运行请求时,脚本沿其路径链接,从外到内:
```
collection pre-request → folder pre-request(s, outer → inner) → request pre-request
→ request is sent →
collection tests → folder tests(s, outer → inner) → request tests
```
所有级别共享一个运行状态,因此在集合预请求脚本中设置的变量通过 `pm.variables.set` 在下面的文件夹和请求脚本中可见。 从Postman导入的集合和文件夹级别脚本插槽到此相同的链中。
### `pm` API
Postman API的子集:
- `pm.environment.get/set/unset/has/toObject` — **持久化** 到活动环境。 如果变量是 🔒 机密,则值进入 `.local.json`;否则进入共享文件。 (设置 *非机密* 变量会将其值写入可提交的文件 — 标记机密为 🔒。)
- `pm.variables.get/set` — 当前运行的会话范围(仅保存)。
- `pm.request`(预请求)— 读取/修改 `method`、`url`、`headers`(`add`/`upsert`/`remove`/`get`)和 `body.raw` 在请求发送前。
- `pm.response`(测试)— `code`、`status`、`responseTime`、`headers.get()`、`.text()`、`.json()`。
- `pm.cookies` — `get(name)`、`has(name)`、`toObject()` 用于请求的域名,从工作区Cookie jar读取。
- `pm.test(name, fn)` 和类似chai的 `pm.expect`(`.to.equal/eql`、`.to.be.a/ok`、`.to.include`、`.to.have.property/status`、`.not`)。
- `console.log/info/warn/error` — 捕获并在响应 **测试** 标签页中显示,连同测试结果和运行中更改的变量。
> [!WARNING]
> 脚本在本地服务器上运行在受限的 `node:vm` 沙盒(无 `require`、`process`、`fetch` 或定时器)中,超时2秒。 这使得您自己的脚本在您自己的机器上受到保护;它 **不是** 一个强化的边界,因此在运行从其他地方导入的集合中的脚本之前,请先查看脚本。
## Cookie
每个工作区都有一个自动的Cookie jar,就像浏览器一样。 当响应发送 `Set-Cookie` 时,Cookie被存储;后续请求会自动附加匹配的Cookie(尊重域名、路径、过期和 `Secure` 标志)。 登录请求可以设置会话Cookie,后续请求直接使用 — 无需手动复制。
单击顶部栏中的 **🍪 Cookies** 以查看按域名分组的Cookie jar并删除单个Cookie或全部清除;响应显示设置的Cookie数量。 脚本可以通过 `pm.cookies.get(name)` / `has(name)` / `toObject()` 读取Cookie。
Cookie仅存储在您的机器上(在 `~/.apinotebook/` 中),永远不会存储在工作区文件夹中,因此永远不会提交到仓库中。
## MCP服务器(用于AI代理)
服务器通过Streamable HTTP在 `http://localhost:3001/mcp` 上公开 [模型上下文协议](https://modelcontextprotocol.io) 端点,因此AI代理(Claude Code、Claude Desktop等)可以驱动您的工作区。 它在与应用程序相同的服务器上运行,因此只需启动它(`npm run dev` 或 `npm start`)并将其添加到您喜欢的代理中。 例如:
```sh
claude mcp add --transport http api-notebook http://localhost:3001/mcp
```
### 示例用法
您可以要求代理执行的一些操作:
- **在您正在开发的应用程序中实现文档化的API。** *"实现 `POST /v1/refunds` 端点,详见 `payments-api` 工作区中的Refunds集合,然后在我的开发服务器上运行该请求,直到它通过。"* 代理读取请求的URL、参数、身份验证、正文和Markdown文档作为规范,在您的代码库中编写端点,并通过执行保存的请求进行验证 — 变量、脚本和Cookie jar应用,迭代直到测试通过。
- **记录完成的API。** 构建API后,指向代理指向源或OpenAPI规范,并要求它 *"在我的API Notebook工作区中创建一个集合,每个端点对应一个请求,并带有Markdown文档和示例正文。"* 由于工作区是普通文件夹,您可以像Git diff一样查看结果并将其提交到代码旁边。
- **烟雾测试和调试。** *"运行smoke-tests集合中的每个请求到staging环境,并总结任何失败"*- 代理返回每个运行的状态、计时和 `pm.test` 结果。
> [!TIP]
> 简而言之,MCP服务器让API Notebook在两个方向上工作:作为代理实现的 **规范** 和作为 **目标** ,其中代理从其源代码记录API。
### 工具
工具是 **多工作区** - 每个都需要一个 `workspaceId`(首先调用 `list_workspaces` 以发现它们;从应用程序UI创建新工作区,因为这需要文件夹选择器)。 工具集涵盖完整的:
- **查询**:`list_workspaces`、`get_workspace_tree`、`get_collection`、`get_request`、`get_environment`、`list_cookies`。
- **构建和编辑**:`create_collection`、`update_collection`、`create_request`、`update_request`(仅传递的字段更改;使用 `{{variable}}` 进行插值)、`create_environment`、`update_environment`、`set_active_environment`、`set_variable`。
- **运行**:`execute_request` - 通过代理发送保存的请求,带有变量插值、预请求/测试脚本和Cookie jar,并返回响应以及脚本结果和测试结果。
- **导入**:`import_postman`(集合或环境,通过文件路径)。
- **破坏性**(标记给代理):`delete_request`、`delete_collection`、`clear_cookies`。 这些操作受到保护 - 调用其中一个操作而不确认 `confirm: true` 会返回确切的删除内容并且不执行;代理必须显示它并在确认后再次调用 `confirm: true`。
> [!NOTE]
> 端点是未身份验证的,与本地REST API匹配 - 它仅用于 `localhost` 使用。 (cURL字符串导入不是MCP工具;代理直接通过 `create_request` / `update_request` 创建请求。)
## 键盘快捷键
| 快捷键 | 操作 |
|---|---|
| `Cmd/Ctrl` + `Enter` | 发送当前请求 |
| `Cmd/Ctrl` + `S` | 保存当前请求 |
| URL栏中的 `Enter` | 发送 |
## 技术栈
- `server/` — Node + Express + TypeScript。 基于文件的存储,请求执行代理,变量插值,30秒超时。
- `client/` — React + Vite + TypeScript。 没有状态库;通过小型类型化API客户端与服务器通信(`client/src/api.ts`)。
## 贡献
欢迎贡献! 参见 [CONTRIBUTING.md](CONTRIBUTING.md) 设置项目、 [分支模型](CONTRIBUTING.md#branching-model)、PR工作流和我们的约定。 `main` 是受保护的,CI必须在请求合并前通过。 参与者同意我们的 [行为准则](CODE_OF_CONDUCT.md)。
## 版本发布
API Notebook作为源码发布 - 每个版本都是Git标签和 [GitHub Release](https://github.com/mbadaz/api-notebook/releases)。 整个应用程序共享一个 [SemVer](https://semver.org) 版本(根、`client`和`server`同步)。 参见 [CHANGELOG.md](CHANGELOG.md) 了解更改内容和 [RELEASING.md](RELEASING.md) 发布流程。
运行特定版本:
```sh
git fetch --tags
git checkout vX.Y.Z
npm install && npm run build
npm start # http://localhost:3001
```
## 许可证
[MIT](LICENSE) © Tapiwa Muzira