gpt-subagents-subscription
# gpt-subagents-subscription
An MCP server that exposes GPT "subagent" tools backed by your **ChatGPT subscription** — using
OpenAI's **"Sign in with ChatGPT"** OAuth instead of a pay-per-use API key. Sibling to
[`gpt-subagents-api`](https://github.com/Wally-Ahmed/gpt-subagents-api) (which uses an API key), and
it ships the same **orchestration patterns** system.
> **Note:** Authenticates via OpenAI's **"Sign in with ChatGPT"** OAuth — the mechanism OpenAI
> introduced (through Codex CLI) for bringing your ChatGPT subscription to a third-party tool — and
> calls the ChatGPT backend with the resulting token. Not affiliated with or endorsed by OpenAI. These
> backend endpoints aren't versioned and can change; if a call starts failing, the stable alternative
> is the API-key sibling [`gpt-subagents-api`](https://github.com/Wally-Ahmed/gpt-subagents-api).
---
## Tools
| Tool | What it does |
|------|--------------|
| `ask_gpt` | Ask a GPT model via your ChatGPT subscription. **You pick `model` and write `instructions` (the system prompt) every call — both required, no defaults.** Any valid model id is accepted; known suggestions: `gpt-5.6-sol` (frontier), `gpt-5.6-terra` (balanced), `gpt-5.6-luna` (fast/cheap) — use the explicit ids (the bare `gpt-5.6` alias is rejected by the subscription backend); older `gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` still work. Optional `reasoning_effort` (none/low/medium/high/xhigh/max; the full scale is a gpt-5.6 feature). |
| `ask_gpt_batch` | Run up to 8 **independent** asks concurrently in one tool call (each ask has the same fields as `ask_gpt`). Results return together, labeled per ask; one failed ask doesn't abort the others. |
| `check_usage` | Remaining ChatGPT/Codex subscription quota |
| `list_patterns` / `get_pattern` | Orchestration patterns for driving the model well (see below) |
All tools are annotated `readOnlyHint: true` — they never mutate state, only consume quota — so MCP
clients that key on it (Claude Code does) can dispatch several `ask_gpt` calls from one message **in
parallel** instead of serializing them. The backend accepts concurrent requests on one account;
`ask_gpt_batch` guarantees that concurrency server-side regardless of the client's scheduling.
---
## Orchestration patterns
Patterns are reusable playbooks (Markdown in [`patterns/`](./patterns)) that describe *how* to drive
the expert tools — splitting work, bundling context, calling the expert, **verifying its output
against ground truth**, and aggregating. They're exposed via `list_patterns` (catalog) and
`get_pattern("<name>")` (full text), read from disk **at call time** (no rebuild to add one), and the
server's `instructions` nudge the agent to consult them before non-trivial expert work.
| name | what it does |
|------|--------------|
| [`two-layer-cross-model-expert`](./patterns/two-layer-cross-model-expert.md) | Wrap the GPT expert in verifying Claude subagents so the orchestrator only ever sees parallel, context-cheap, ground-truth-checked conclusions. |
| [`worker-orchestrator`](./patterns/worker-orchestrator.md) | Fan concrete work out to the GPT worker (`ask_gpt` with a fast model) through cheap Sonnet wrapper subagents — validated by execution, not a verification gate. |
Both patterns ship a rendered diagram under [`patterns/html/`](./patterns/html). See [`patterns/README.md`](./patterns/README.md) to add your own.
---
## CLI
The same capability as a shell command (`dist/cli.js`, bin name `gpt-subagents-subscription`) —
no MCP framing, raw answer on stdout, so an agent driving it through a shell tool spends zero
tokens on protocol boilerplate:
```bash
# ask (the subcommand is optional); model is REQUIRED (no default)
gpt-subagents-subscription ask -m gpt-5.6-luna "why is the sky blue?"
# piped stdin becomes the prompt — or the context when a prompt is given
git diff | gpt-subagents-subscription ask -m gpt-5.6-sol -e high -p "review this diff"
# subscription quota, patterns, and per-machine OAuth login
gpt-subagents-subscription usage
gpt-subagents-subscription patterns
gpt-subagents-subscription pattern worker-orchestrator
gpt-subagents-subscription login # (--logout to clear tokens)
```
`-i/--instructions` overrides the system prompt (CLI default: terse expert; the MCP tool keeps
instructions required). For 2+ independent asks, run multiple invocations concurrently
(shell `&` / `xargs -P`) — the CLI equivalent of `ask_gpt_batch`. Install the bin with
`npm link` or invoke via `node dist/cli.js` / `npm run cli --`.
---
## Setup
Requires Node 18+ and an active ChatGPT subscription.
```bash
npm install
npm run build
npm run login # prints a sign-in URL to open; sign in with ChatGPT (one-time)
```
`npm run login` runs an OAuth flow on `http://localhost:1455/auth/callback` and stores tokens at
`~/.gpt-subagents-subscription/auth.json` (mode `0600`, **never** committed). Run
`npm run login -- --logout` to clear them.
### Register with Claude Code
```bash
claude mcp add gpt-subagents-subscription -- node /absolute/path/to/gpt-subagents-subscription/dist/server.js
```
### Long-running calls
**Hard ceiling first:** the subscription backend terminates a single response stream at **~15
minutes** (measured at ~902s on both HTTP/1.1 and HTTP/2, with events actively flowing; `background`
mode is rejected — "Store must be set to false"). An ask whose reasoning+output exceeds the window
dies with its work lost, and the server reports it as such. **Scope each ask to fit; split larger
jobs into independent asks** (`ask_gpt_batch` runs them concurrently — the patterns show how).
Below that ceiling, this server keeps every other timeout out of the way. MCP clients kill a tool
call whose HTTP response stays **byte-silent** for too long — Claude Code (observed on v2.1.183)
aborts at ~5 minutes, and empirically neither `MCP_TOOL_TIMEOUT` nor the per-server `timeout` field
prevents it for a byte-silent call. This server therefore keeps bytes flowing itself:
- **SSE response mode + 30s heartbeats.** In HTTP mode the server answers tool calls as an SSE
stream and emits a notification every 30s while the backend call is in flight (a progress
notification when the client sent a `progressToken`, else a logging notification). The response
is never byte-silent, so client first-byte/inactivity timers don't fire.
- **Server-side wall-clock deadline** — default **3h15m** per backend request (a backstop against a
hung backend). Override in ms via `GSS_RESPONSES_DEADLINE_MS`, no rebuild needed.
- **Client wall-clock** — Claude Code's `MCP_TOOL_TIMEOUT` (ms; default ≈28h) bounds total call
time. If you set it, keep it above the server deadline.
- **Cancellation propagates.** If the client aborts a call, the server aborts the in-flight backend
request instead of letting it burn subscription quota to completion.
The backend connection is hardened for silence too: undici header/body inactivity timeouts are
disabled and TCP keepalive probes are enabled, so NAT/firewall idle tracking won't drop a quiet
stream during a long reasoning phase.
### Keeping the HTTP server always-on (macOS)
A hand-launched HTTP server dies on reboot and keeps serving stale code after rebuilds. Manage it
with launchd instead — [`deploy/com.wally.gpt-subagents-subscription.plist`](./deploy/com.wally.gpt-subagents-subscription.plist)
starts it at login, restarts it on crash, and pins `GPT_MCP_HTTP_PORT=8791`:
```bash
# one-time install (adjust paths in the plist if the repo lives elsewhere)
cp deploy/com.wally.gpt-subagents-subscription.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.wally.gpt-subagents-subscription.plist
# after every rebuild — restart the managed process so it loads the new dist/
npm run build && npm run restart:http
```
Pin the client-side wall-clock too by adding `"timeout": 12600000` to the server's entry in the MCP
registration (and see the `env` settings above for `MCP_TOOL_TIMEOUT` /
`CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT` on newer Claude Code versions).
---
## How it works
1. `npm run login` → PKCE OAuth against `auth.openai.com` → tokens stored locally.
2. The MCP server reads and auto-refreshes those tokens.
3. Tool calls POST to `chatgpt.com/backend-api/codex/responses` with `Authorization: Bearer` +
`ChatGPT-Account-Id`, using the Responses API schema.
---
## Security
- Tokens live outside the repo (`~/.gpt-subagents-subscription/`) and are gitignored everywhere.
- No credentials are committed; `.env.example` holds only optional model overrides.
- This project **never reads your existing `~/.codex/auth.json`** — it mints its own tokens.
- Local agent/editor state (`.mempalace/`, `.claude/`, `CLAUDE.local.md`, IDE folders) is gitignored.
---
## Credits / prior art
The "Sign in with ChatGPT" subscription flow has been documented by the community, e.g.
[EvanZhouDev/openai-oauth](https://github.com/EvanZhouDev/openai-oauth) and various write-ups.
## License
MIT
TDQS
Scored across 4 tools
Each tool has a distinct purpose: ask_gpt for queries, check_usage for quota, get_pattern and list_patterns for orchestration patterns. No overlap in functionality.
All tools follow a consistent verb_noun snake_case pattern (ask_gpt, check_usage, get_pattern, list_patterns), making them predictable and easy to understand.
With 4 tools, the set is concise and focused on core subscription-GPT and pattern orchestration needs. Could possibly benefit from a tool to list available models, but the count is appropriate for its scope.
The set covers querying GPT, checking usage, and managing orchestration patterns. A minor gap is the absence of a tool to list models or subscription details beyond quota, but core workflows are well-supported.