Skip to main content
@google/gemini-cli (v0.40.1+).

Install

Auth

Crewship’s apiKeyEnvVarsForAdapter("GEMINI_CLI") accepts either; both are mirrored to the container env so any version of gemini-cli finds its key.

Google account login

A Google AI Pro / Ultra subscription is a file, not a variable: Gemini CLI reads its “Login with Google” session only from ~/.gemini/oauth_creds.json (the google-auth-library credentials object — access_token, refresh_token, scope, token_type, id_token, expiry_date in milliseconds). Sign in with gemini on your own machine, then store the whole file as a credential:
The slot name on assign is the binding’s identity, not something Gemini reads. A bare token is refused at submit time: the file needs access_token, refresh_token and expiry_date, and only the file the CLI wrote has all three. At every run start Crewship renders the login into the agent’s ~/.gemini/oauth_creds.json (/crew/agents/<slug>/.gemini/oauth_creds.json, mode 0600) with the real access and id tokens and refresh_token replaced by 1//crewship-managed-no-refresh, sets GOOGLE_GENAI_USE_GCA=true — the variable a headless gemini run selects the Google-login path with — and carries no GEMINI_API_KEY / GOOGLE_API_KEY, because a key in the environment wins over the login file. The run is billed flat_rate with CREWSHIP_SUBSCRIPTION_PLAN set to “Google AI Pro” / “Google AI Ultra” when the stored file names its tier in a plan field, and “Google AI” otherwise (Google’s tokens carry no plan claim). Revoking the credential removes the file from running containers; unassigning it removes the file at the next run start.
A Google access token lives about one hour, and the delivered file cannot renew itself — that is the point of the placeholder. Central refresh from the stored refresh token is available for PROVIDER_LOGIN imports when the server’s CREWSHIP_GEMINI_OAUTH_CLIENT_ID and CREWSHIP_GEMINI_OAUTH_CLIENT_SECRET match the client that issued the grant. Without that configuration, automatic refresh is unavailable. Refresh re-renders the file; uninterrupted use by an already running CLI is not a verified guarantee. The file shape is taken from the Gemini CLI source (packages/core/src/code_assist/oauth2.ts), not measured against a running binary — the CLI is not installed on the dev box.

Models

gemini-2.0-flash and gemini-1.5-pro are not available in the current Gemini API catalog — removed from picker. Note the dash-separated ID format (gemini-3-1-pro, not gemini-3.1-pro); Google’s models.list endpoint returns this canonical form.

Command shape

  • -p — non-interactive prompt mode
  • --output-format stream-json — JSONL events (PR #10883)
  • -m — model selector
  • --approval-mode plan — appended only for the MINIMAL profile (Gemini’s read-only mode; its named-tool allowlist --allowed-tools is deprecated in favour of the Policy Engine). CODING/FULL keep the default flow.
  • System prompt folded into prompt body since headless mode has no --system-instruction flag

MCP

Configured at /output/<slug>/.gemini/settings.json:
Crewship prefers httpUrl (HTTP streaming, current) over url (SSE, legacy) — url is only emitted when the source explicitly declares sse transport. Env-var syntax ${VAR} or $VAR (POSIX); both expanded by gemini-cli at MCP spawn.
Crewship also auto-injects two sidecar-hosted servers into .gemini/settings.json (injectMemoryMCP + injectRoutinesMCP): crewship-memory (http://127.0.0.1:9119/mcp/memory/<slug>) and crewship-routines (.../mcp/routines), both emitted as httpUrl entries. A user-declared server of the same name wins.

Memory

Canonical memory set including GEMINI.md (Gemini’s auto-discovery path) at /output/<slug>/.

Output stream

JSONL per geminicli.com/docs/cli/headless:

Troubleshooting

gemini: not found — npm install failed. Auth precedence trap — if both GEMINI_API_KEY (AI Studio) and GOOGLE_API_KEY (Cloud) are in the env, GOOGLE wins silently. Use one or the other. Exit code 52 with no JSON — auth failure (issue #20183). Orchestrator detects exit-without-result and surfaces as run error.