--- summary: "Grok provider data sources: ACP JSON-RPC, grok.com billing fallback, OAuth credentials, and local session signals." read_when: - Debugging Grok billing/usage parsing - Updating `grok agent stdio` JSON-RPC integration - Adjusting `~/.grok/auth.json` credential reading --- # Grok provider Grok uses xAI's official Grok Build CLI (`grok`, released 2026-05-14). Usage data is fetched via the ACP JSON-RPC `x.ai/billing` extension method over `grok agent stdio` when available, then via grok.com's billing gRPC-web endpoint using the signed-in browser session when the CLI surface does not expose billing. ## Data sources + fallback order 1) **`~/.grok/auth.json` (primary; always works for SuperGrok subscribers)** - Reads `email`, `team_id`, `first_name`/`last_name`, plan-hint (`auth_mode`) for the identity row in the menu. 2) **`grok agent stdio` ACP JSON-RPC** (best-effort, currently disabled in grok 0.1.210) - We spawn `grok agent stdio` and call `initialize` + `x.ai/billing` (no params). - **Known limitation:** in grok 0.1.210 the `x.ai/billing` extension method is only wired in the interactive TUI; the agent-stdio surface returns `-32601 Method not found`. The provider degrades silently to identity-only when this happens. When xAI exposes billing on the agent protocol, no code change is required. - One non-obvious quirk: grok's ACP parser does not unescape `\/` in method names. `Foundation.JSONSerialization.data` defaults to escaping forward slashes, so payloads must be re-encoded with `\/` → `/` before being written to stdin or grok will silently drop them (12s client-side timeout instead of the expected error response). 3) **grok.com billing gRPC-web fallback** (best-effort) - POSTs an empty gRPC-web protobuf request to `https://grok.com/grok_api_v2.GrokBuildBilling/GetGrokCreditsConfig`. - Uses grok.com browser session cookies. When a non-expired `~/.grok/auth.json` token is available, CodexBar first sends it with each browser session, then retries that session with cookies only. - CodexBar imports Chrome only by default to avoid unrelated browser Keychain prompts. - CLI/test runtime does not import browser cookies unless `CODEXBAR_ALLOW_BROWSER_COOKIE_IMPORT=1` is set. - `~/.grok/auth.json` is still used for identity and as a last best-effort bearer-only probe after browser sessions fail. Expired tokens are not sent. - Parses the returned protobuf enough to recover used percent and reset timestamp, accepting both gRPC-web frames and the raw protobuf form returned by some successful requests. A current billing period with an omitted proto3 `credit_usage_percent` is treated as zero usage. This keeps billing visible when `grok agent stdio` returns `Method not found`. 4) **Local session signals** (informational fallback) - Walks `~/.grok/sessions///signals.json` files (last 30 days). - Aggregates `totalTokensBeforeCompaction`, `contextTokensUsed`, `modelsUsed`, and the most recent session timestamp. ## OAuth credentials - File: `~/.grok/auth.json` (path overridable via `GROK_HOME`). - Top-level keys are OIDC scope URLs. CodexBar prefers entries under `https://auth.x.ai::` (SuperGrok), falling back to `https://accounts.x.ai/sign-in` (legacy session). - Required fields per entry: `key` (bearer token), `refresh_token`, `expires_at`, `auth_mode`, `email`, `team_id`, `user_id`, `first_name`/`last_name`. - Tokens are issued by `grok login` and expire after ~7 days; refresh is handled by the CLI itself (CodexBar does not refresh; it just reads the cached credential). ## JSON-RPC contract - Transport: stdin/stdout, newline-delimited JSON-RPC 2.0 (no Content-Length framing). - `initialize` params: ```json { "protocolVersion": "1", "clientCapabilities": { "fs": { "readTextFile": false, "writeTextFile": false }, "terminal": false } } ``` - `x.ai/billing` result shape (all monetary values are `{ val: }`): ```json { "billingCycle": { "billingPeriodStart": "2026-05-01T00:00:00Z", "billingPeriodEnd": "2026-06-01T00:00:00Z" }, "monthlyLimit": { "val": 99900 }, "onDemandCap": { "val": 0 }, "on_demand_enabled": false, "disabledByConfig": false, "usage": { "includedUsed": { "val": 12345 }, "onDemandUsed": { "val": 0 }, "totalUsed": { "val": 12345 } } } ``` - Auth errors surface as JSON-RPC errors with the message `"Authentication required to fetch billing data. Run 'grok login' to authenticate."`. - Timeouts: 8s for `initialize`, 12s for `x.ai/billing`. CodexBar terminates the child `grok` process on timeout to avoid leaking subprocesses. ## Mapping to `UsageSnapshot` - **Primary window** = credit usage (against the subscription/included limit): - CLI RPC: `usedPercent` = `usage.totalUsed.val / monthlyLimit.val * 100`; `resetsAt` = `billingCycle.billingPeriodEnd`. - grok.com fallback: `usedPercent` and `resetsAt` parsed from the gRPC-web billing protobuf. - The UI label for the live usage bar is dynamic: "Weekly" or "Monthly" when `resetsAt` matches a common cycle, falling back to the registered "Credits" label otherwise. Settings and history views continue to use "Credits" as the stable metric name. - **Identity**: - `accountEmail` from credential `email`. - `accountOrganization` from credential `team_id`. - `loginMethod` = "SuperGrok" for OIDC, otherwise the raw `auth_mode`. ## Local fallback (`~/.grok/sessions/`) Each session directory contains `signals.json` with fields like: ```json { "turnCount": 1, "contextTokensUsed": 2968, "contextWindowTokens": 512000, "totalTokensBeforeCompaction": 0, "modelsUsed": ["grok-build"], "primaryModelId": "grok-build", "sessionDurationSeconds": 47 } ``` CodexBar aggregates these into a `GrokLocalSessionSummary` (session count, total tokens, last session time, primary model) and exposes it for diagnostics even when the RPC path is unavailable. ## Status xAI has not exposed a Statuspage-style status feed yet. The "View Status" link points to `https://status.x.ai`. ## Key files - `Sources/CodexBarCore/Providers/Grok/GrokProviderDescriptor.swift` - `Sources/CodexBarCore/Providers/Grok/GrokAuth.swift` - `Sources/CodexBarCore/Providers/Grok/GrokRPCClient.swift` - `Sources/CodexBarCore/Providers/Grok/GrokWebBillingFetcher.swift` - `Sources/CodexBarCore/Providers/Grok/GrokStatusProbe.swift` - `Sources/CodexBarCore/Providers/Grok/GrokLocalSessionScanner.swift` - `Sources/CodexBar/Providers/Grok/GrokProviderImplementation.swift`