内容
# gpt-subagents-subscription
MCP 服务器,提供基于 **ChatGPT 订阅** 的 GPT "子代理" 工具,使用 OpenAI 的 **"通过 ChatGPT 登录"** OAuth 而非按使用次数计费的 API 密钥。与 [`gpt-subagents-api`](https://github.com/Wally-Ahmed/gpt-subagents-api)(使用 API 密钥)是 sibling 项目,并配备相同的 **编排模式** 系统。
> **注意:** 通过 OpenAI 的 **"通过 ChatGPT 登录"** OAuth 进行身份验证 — OpenAI 通过 Codex CLI 引入的机制,用于将您的 ChatGPT 订阅带到第三方工具 — 并使用生成的令牌调用 ChatGPT 后端。 与 OpenAI 无关或未获得 OpenAI 认可。 这些后端端点没有版本控制,可能会更改;如果调用开始失败,稳定的替代方案是 API 密钥 sibling [`gpt-subagents-api`](https://github.com/Wally-Ahmed/gpt-subagents-api)。
---
## 工具
| 工具 | 功能 |
|------|--------------|
| `ask_gpt` | 通过 ChatGPT 订阅询问 GPT 模型。 **您选择 `模型` 并编写 `指令`(系统提示)每次调用 — 两者都是必需的,无默认值。** 接受任何有效的模型 ID;已知建议:`gpt-5.6-sol`(前沿)、`gpt-5.6-terra`(平衡)、`gpt-5.6-luna`(快速/廉价)— 使用明确的 ID(bare `gpt-5.6` 别名被订阅后端拒绝);较旧的 `gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` 仍然有效。 可选 `reasoning_effort`(无/低/中/高/x高/最大;完整的刻度是 gpt-5.6 功能)。 |
| `ask_gpt_batch` | 在一次工具调用中并发运行最多 8 个 **独立** 的询问(每个询问与 `ask_gpt` 具有相同的字段)。 结果返回一起,按询问标记;一个询问失败不会中止其他询问。 |
| `check_usage` | 剩余 ChatGPT/Codex 订阅配额 |
| `list_patterns` / `get_pattern` | 用于驱动模型的编排模式(见下文) |
所有工具都注释为 `readOnlyHint: true` — 它们从不改变状态,只消耗配额 — 因此 MCP 客户端(如 Claude Code)可以在一条消息中并行调度多个 `ask_gpt` 调用,而不是序列化它们。 后端接受一个帐户上的并发请求;`ask_gpt_batch` 保证服务器端并发,无论客户端的调度如何。
---
## 编排模式
模式是可重用的剧本([`patterns/`](./patterns) 中的 Markdown),描述了 *如何* 驱动专家工具 — 分割工作、捆绑上下文、调用专家、 **验证其输出与基本事实**,并聚合。 它们通过 `list_patterns`(目录)和 `get_pattern("<name>")`(全文)公开,在调用时从磁盘读取(无需重建即可添加一个),并且服务器的 `instructions` 提示代理在非平凡专家工作之前查阅它们。
| 名称 | 功能 |
|------|--------------|
| [`two-layer-cross-model-expert`](./patterns/two-layer-cross-model-expert.md) | 将 GPT 专家封装在验证 Claude 子代理中,以便编排者仅看到并行、上下文便宜、基本事实检查的结论。 |
| [`worker-orchestrator`](./patterns/worker-orchestrator.md) | 通过廉价的 Sonnet 包装器子代理将具体工作分散到 GPT 工作器(使用快速模型进行 `ask_gpt`)— 通过执行验证,而不是验证门控。 |
两种模式都附带一个渲染的图表,位于 [`patterns/html/`](./patterns/html)。 请参阅 [`patterns/README.md`](./patterns/README.md) 以添加您自己的模式。
---
## 命令行界面
与 shell 命令具有相同的功能(`dist/cli.js`,二进制名称 `gpt-subagents-subscription`)— 没有 MCP 框架,原始答案在 stdout 上,因此通过 shell 工具驱动它的代理在协议样板上花费零令牌:
```bash
# 询问(子命令是可选的);模型是必需的(无默认值)
gpt-subagents-subscription ask -m gpt-5.6-luna "为什么天空是蓝色的?"
# 管道 stdin 成为提示 — 或当给出提示时的上下文
git diff | gpt-subagents-subscription ask -m gpt-5.6-sol -e high -p "审查此差异"
# 订阅配额、模式和每台机器的 OAuth 登录
gpt-subagents-subscription usage
gpt-subagents-subscription patterns
gpt-subagents-subscription pattern worker-orchestrator
gpt-subagents-subscription login # (--logout 清除令牌)
```
`-i/--instructions` 覆盖系统提示(CLI 默认:简洁专家;MCP 工具保持指令必填)。 对于 2+ 个独立询问,并行运行多个调用(shell `&` / `xargs -P`)— `ask_gpt_batch` 的 CLI 等价项。 使用 `npm link` 安装二进制文件,或通过 `node dist/cli.js` / `npm run cli --` 调用。
---
## 设置
需要 Node 18+ 和有效的 ChatGPT 订阅。
```bash
npm install
npm run build
npm run login # 打印一个登录 URL 以打开;使用 ChatGPT 登录(一次性)
```
`npm run login` 在 `http://localhost:1455/auth/callback` 上运行 OAuth 流,并将令牌存储在 `~/.gpt-subagents-subscription/auth.json`(模式 `0600`,**绝不** 提交)。 运行 `npm run login -- --logout` 以清除它们。
### 注册到 Claude Code
```bash
claude mcp add gpt-subagents-subscription -- node /absolute/path/to/gpt-subagents-subscription/dist/server.js
```
### 长时间调用
**硬上限:** 订阅后端在 **~15 分钟**(在 HTTP/1.1 和 HTTP/2 上测量,约为 902s,事件积极流动;`background` 模式被拒绝 — "必须设置为 false")。 如果推理 + 输出超过窗口,则询问会因工作丢失而失败,服务器会将其报告为失败。 **将每个询问范围限定为合适;将较大的作业分成独立的询问**(`ask_gpt_batch` 并发运行它们 — 模式显示了如何操作)。
在此上限以下,服务器保持其他所有超时时间。 MCP 客户端会杀死一个工具调用,其 HTTP 响应长时间保持 **字节沉默**:Claude Code(v2.1.183 观察) 在 ~5 分钟时中止,经验上看,无论 `MCP_TOOL_TIMEOUT` 还是服务器特定的 `timeout` 字段如何,字节沉默调用都不会阻止它。 因此,服务器自己保持字节流动:
- **SSE 响应模式 + 30 秒心跳。** 在 HTTP 模式下,服务器以 SSE 流回答工具调用,并在后端调用进行时每 30 秒发出通知(当客户端发送 `progressToken` 时为进度通知,否则为日志通知)。 响应永远不会是字节沉默的,因此客户端第一字节/空闲定时器不会触发。
- **服务器端时钟截止日期** — 默认 **3h15m** 每后端请求(防止后端挂起的备用)。 通过 `GSS_RESPONSES_DEADLINE_MS` 以毫秒为单位覆盖,无需重建。
- **客户端时钟** — Claude Code 的 `MCP_TOOL_TIMEOUT`(毫秒;默认 ≈28h)限制总调用时间。 如果您设置它,请将其保持在服务器截止日期之上。
- **取消传播。** 如果客户端中止调用,服务器会中止正在进行的后端请求,而不是让它燃烧订阅配额直到完成。
后端连接也针对沉默进行了加强:禁用了 undici 头部/正文空闲超时,并启用了 TCP keepalive 探测,以便 NAT/防火墙空闲跟踪不会在长时间推理阶段期间丢弃安静流。
### 在 macOS 上保持 HTTP 服务器始终在线
手动启动的 HTTP 服务器在重启时死亡,并在重建后继续提供过时的代码。 使用 launchd 代替 — [`deploy/com.wally.gpt-subagents-subscription.plist`](./deploy/com.wally.gpt-subagents-subscription.plist) 在登录时启动它,在崩溃时重启它,并固定 `GPT_MCP_HTTP_PORT=8791`:
```bash
# 一次性安装(根据 plist 调整路径,如果存储库位于其他位置)
cp deploy/com.wally.gpt-subagents-subscription.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.wally.gpt-subagents-subscription.plist
# 每次重建后 — 重启托管进程以加载新的 dist/
npm run build && npm run restart:http
```
通过在 MCP 注册中添加 `"timeout": 12600000` 来固定客户端时钟(以及对于较新的 Claude Code 版本,参见上面的 `env` 设置 `MCP_TOOL_TIMEOUT` / `CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT`)。
---
## 工作原理
1. `npm run login` → 与 `auth.openai.com` 的 PKCE OAuth → 本地存储令牌。
2. MCP 服务器读取并自动刷新这些令牌。
3. 工具调用使用 Responses API 模式,将 `Authorization: Bearer` + `ChatGPT-Account-Id` 发送到 `chatgpt.com/backend-api/codex/responses`。
---
## 安全
- 令牌存储在存储库外部(`~/.gpt-subagents-subscription/`)并在所有地方被 gitignore。
- 没有提交凭证;`.env.example` 仅包含可选的模型覆盖。
- 本项目 **从不读取您现有的 `~/.codex/auth.json`** — 它会生成自己的令牌。
- 本地代理/编辑器状态(`.mempalace/`、`.claude/`、`CLAUDE.local.md`、IDE 文件夹)被 gitignore。
---
## 致谢 / 前期作品
"通过 ChatGPT 登录" 订阅流程已由社区记录,例如 EvanZhouDev/openai-oauth 和各种文章。
## 许可证
MIT