# Subscription Bridges Subscription bridges let the gateway route requests to user-owned AI subscription tools through a local HTTP interface. The bridge pattern is: ```text gateway -> local bridge -> installed CLI or local adapter -> subscription-backed response ``` The gateway does not need direct access to the subscription account material. The CLI or adapter keeps its own authentication state. ## Why Bridges Exist Many subscription tools are designed for interactive use, not direct API access. A bridge gives the gateway a small, testable HTTP surface around those tools: - `GET /health` - `POST /api/generate` - `POST /v1/chat/completions` This makes subscription tools easier to test, monitor, and route alongside other providers. ## Discovery Discovery checks: - CLI binary availability - version probe result - authentication status when a safe probe exists - default bridge health - configured bridge URL Run discovery: ```bash curl -X POST http://localhost:3100/api/subscriptions/scan \ -H "Authorization: Bearer " ``` List subscriptions: ```bash curl http://localhost:3100/api/subscriptions \ -H "Authorization: Bearer " ``` Search: ```bash curl "http://localhost:3100/api/subscriptions?search=claude" \ -H "Authorization: Bearer " ``` ## Join Join records that the operator wants to use a subscription. ```bash curl -X POST http://localhost:3100/api/subscriptions/join \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{ "subscription_id": "chatgpt", "auto_spawn": true }' ``` Joining does not expose OAuth state or account credentials. The subscription summary returned by the list endpoint contains the generated access card, including the direct gateway API URL for that subscription. ## Spawn Spawn one bridge: ```bash curl -X POST http://localhost:3100/api/subscriptions/bridges \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{ "subscription_id": "chatgpt" }' ``` Spawn all eligible bridges: ```bash curl -X POST http://localhost:3100/api/subscriptions/bridges \ -H "Authorization: Bearer " ``` ## Test ```bash curl -X POST http://localhost:3100/api/subscriptions/test \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{ "subscription_id": "chatgpt", "message": "Reply with a bridge smoke test." }' ``` The test response should include: - subscription ID - model - bridge URL - HTTP status - latency - response snippet ## Call A Joined Subscription Every joined subscription can be called through its own OpenAI-compatible gateway URL: ```bash curl -X POST http://localhost:3100/api/subscriptions/chatgpt/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{ "model": "gpt-4-turbo", "messages": [ { "role": "user", "content": "Reply through the ChatGPT subscription bridge." } ] }' ``` The unified endpoint can also target a specific subscription: ```bash curl -X POST http://localhost:3100/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -H "X-LLM-Gateway-Subscription: chatgpt" \ -d '{ "model": "gpt-4-turbo", "messages": [ { "role": "user", "content": "Reply through the ChatGPT subscription bridge." } ] }' ``` For ambiguous model IDs, prefer the direct subscription URL or the `X-LLM-Gateway-Subscription` header. This keeps routing explicit when several subscription tools expose similar model names. Chat messages are compressed before bridge dispatch when compression can reduce the request. Responses include gateway compression metadata where available. ## Access Card Each subscription summary includes an access card with: - gateway base URL - chat completions URL - per-subscription chat completions URL - model list - default model - required headers - `X-LLM-Gateway-Subscription` header value - bridge URL - bridge env var - curl example Use the gateway endpoint from the access card in client applications, not the subscription credentials. ## Adding A Bridge Implementation Add or update: - `packages/gateway/src/modules/subscription-discovery.ts` - `packages/gateway/src/modules/bridge-spawner.ts` - `packages/gateway/src/routes/subscriptions.ts` - `packages/gateway/src/pipeline/external-providers.ts` Minimum checklist: 1. Add a catalog entry. 2. Add a version probe. 3. Add an auth probe if the CLI supports one safely. 4. Pick a localhost bridge port. 5. Add one or more model IDs. 6. Implement the CLI invocation. 7. Return OpenAI-compatible chat output where possible. 8. Add health behavior. 9. Add tests or a documented smoke test. ## Security Rules - Bind local bridges to localhost. - Do not print OAuth artifacts. - Do not return subscription account data in API responses. - Avoid logging full prompts by default. - Treat bridge errors as operational state, not as successful routing. - Prefer explicit join before auto-spawn in shared environments. ## Troubleshooting ### Installed But Not Authenticated Log in through the CLI directly, then run scan again. ### Bridge Port Already In Use Check whether a previous bridge process is still running or configure a different bridge URL. ### Unified Chat Returns Provider Missing Check whether the selected model ID belongs to a discovered, joined, and running subscription. ### CLI Works But Bridge Fails Run the gateway with a verbose log level and test the bridge endpoint directly.