@appstrate/connect-helper
v0.2.2
Published
One-shot OAuth helper for Appstrate model-provider subscriptions. Run via `npx @appstrate/connect-helper <token>`.
Maintainers
Readme
@appstrate/connect-helper
One-shot OAuth helper for connecting personal OAuth model-provider subscriptions to an Appstrate organization.
Why this exists
Subscription-based OAuth providers (ChatGPT Codex, Claude Code, …) ship official CLIs whose client_ids only allowlist http://localhost:PORT/... redirect URIs. The Appstrate dashboard cannot host the OAuth callback itself — the providers' authorization servers reject any redirect that isn't loopback. This helper bridges that gap: it runs on the user's machine, binds the loopback port the provider expects, completes the OAuth dance, and ships the resulting credentials back to the Appstrate platform.
The dashboard is the entry point — the user clicks "Connect <provider>", the platform mints a short-lived pairing token, and the user copy-pastes a one-line npx command.
Why this is a separate (private) repo
Some of the providers this helper supports — notably Anthropic's Claude Code OAuth flow — are subject to Consumer Terms of Service that restrict use with third-party tools. Keeping the helper out of the OSS appstrate/appstrate tree preserves the OSS project's clean ToS posture, while still giving operators who have reviewed those terms a one-line install:
npx @appstrate/connect-helper@latest <pairing-token>The npm package itself is published publicly (so npx works without auth); the source lives here, in a private repo, to make the organizational posture explicit.
Supported providers
Providers are registered data-driven in src/loopback-oauth.ts#MODEL_PROVIDERS. Adding one is a single entry — { login, displayName, defaultLabel } — and requires no other change in the helper. Today: ChatGPT (Codex / Plus / Pro / Business) and Claude (Pro / Max / Team).
The platform side ships each provider as an opt-in module (see the main repo's MODULES env var). The helper supports the union of all OAuth providers any platform module may register.
Usage
The dashboard generates the exact command — you should not invoke this helper directly outside of that flow.
# Surfaced by the dashboard, copied verbatim by the user:
npx @appstrate/connect-helper@latest <pairing-token>The helper:
- Decodes the pairing token (base64url JSON header + random secret).
- Resolves the
providerIdagainst its registry. - Opens your browser to the provider's authorize page.
- Receives the OAuth callback on the loopback port the provider expects.
- POSTs the resulting credentials to the platform URL embedded in the token.
- Exits.
The platform's pairing token expires 5 minutes after issue and is single-use. If the helper hangs, exits non-zero, or the pairing has expired, regenerate the command from the dashboard.
Installation
You don't need to install anything — npx downloads the package on demand. If you prefer a global install:
npm install -g @appstrate/connect-helper
appstrate-connect <pairing-token>Exit codes
| Code | Meaning | | ---- | -------------------------------------------------------------------------- | | 0 | Success — credentials saved on the platform | | 1 | Generic / network / unexpected error | | 2 | Bad pairing token (malformed, expired, already consumed, unknown provider) | | 3 | OAuth flow cancelled by the user |
Security
- The helper is stateless — no config files, no keychain, no persisted state. Tokens live in process memory for the duration of the helper's run, then disappear.
- The pairing token's secret portion is hashed (SHA-256) before storage server-side; the platform never persists the plaintext.
- The token includes the platform URL; the helper rejects HTTP URLs for non-loopback hosts so a tampered token can't downgrade you into a clear-text POST.
- The
npxinvocation downloads the helper from the npm registry. We recommend pinning a version (@appstrate/[email protected]) in production setups; the dashboard does this by default.
Development
bun install
bun run check # tsc + eslint + prettier + test
bun test # unit tests only
bun run build # bundle into dist/cli.js for the npm channelThe pairing-token codec lives in @appstrate/core/pairing-token — both the platform (encode/hash) and this helper (decode) consume the same package to avoid drift.
Release process
# Bump version in package.json, commit, tag, push:
git tag v0.3.0
git push origin v0.3.0
# GitHub Actions runs the `publish.yml` workflow.License
Apache-2.0.
