Gemini API CLI Official Guide (Part 1): Giving Your AI Agent a Stateless Multimodal CLI Toolbox
Verified environment: 2026-11-14 21:53 (Asia/Taipei, UTC+8) on macOS Apple Silicon (ts-m1), gemini-api 0.4.6 (supplemented by our 2026-11-15 live Paid Tier run documented in Section 7). Built for both international devel
Verified environment:
2026-11-14 21:53(Asia/Taipei, UTC+8) on macOS Apple Silicon (ts-m1),gemini-api 0.4.6(supplemented by our2026-11-15live Paid Tier run documented in Section 7). Built for both international developers (Dev.to) and the Taiwan / APAC developer community & GDE workshops.π¬ Video & Bilingual Navigation
- βΆοΈ 70-second Walkthrough Video (YouTube 16:9): https://youtu.be/Rb5ij419w2Y
- β‘ 13-second Highlight (YouTube Shorts 9:16): https://youtube.com/shorts/82-Z_Jq-ezQ
- π± Facebook Reel (9:16): https://www.facebook.com/reel/1484807533581243/
- πΉπΌ Original Traditional Chinese Edition (Substack): https://memo.jimmyliao.net/p/gemini-api-cli-part-1-agent-api
1. Introduction & the 2026 CLI Landscape Shift
June 18, 2026 marks a watershed moment for Google's individual developer CLI entry points: gemini-cli consumer access for free personal accounts and Google AI Pro/Ultra (Google One) plans transitioned to Antigravity CLI (agy). That transition applies to specific personal/consumer account scopes and should not be oversimplified as every gemini-cli mode or enterprise/paid API path disappearing overnight. See the official Google blog announcement for the exact scope.
Developers can now adopt a clean two-track architecture:
-
agy(or Codex / Claude Code) as the Agent Brain & Host: handles reasoning, planning, file edits, and long-horizon coding tasks. -
gemini-apias the Stateless Multimodal CLI Toolbox: exposes image generation, video generation, multi-speaker TTS, music composition, transcription, and server-side Managed Agents over shell primitives. Look at the official repository (google-gemini/gemini-api-cli) to see how it is specifically positioned to equip any shell-capable agent with Gemini models.
Here, stateless means the CLI binary itself does not maintain hidden local chat history between runs; the underlying Interactions API can still persist server-side interactions, resume via --previous-interaction-id, or run background jobs. Mistaking "stateless CLI" for "no server-side state exists" leads to misdesigning multi-turn media pipelines.
2. Installation & Standard Authentication
gemini-api ships as a standalone Go binary. On macOS or Linux, install it using the official installer script:
curl -fsSL https://raw.githubusercontent.com/google-gemini/gemini-api-cli/main/scripts/install.sh | bash
command -v gemini-api
gemini-api --version
On ts-m1 (Darwin / arm64), the installer skipped /usr/local/bin (non-writable) and installed /Users/jimmyliao/.local/bin/gemini-api (v0.4.6; build timestamp 2026-11-11 02:46:39 Asia/Taipei). Ensure $HOME/.local/bin is on your PATH:
export PATH="$HOME/.local/bin:$PATH"
Because latest tracks newer releases over time, pin GEMINI_VERSION in CI per the official CLI installation docs.
For standard authentication, use either an environment variable or interactive configuration (choose one; no need to mix both):
export GEMINI_API_KEY="YOUR_API_KEY"
# OR interactive OS Keychain storage:
gemini-api configure
gemini-api whoami
Note that configure stores secrets in your OS Keychain, whereas --no-keyring / GEMINI_NO_KEYRING=true alters secret resolution and should not be casually enabled without understanding the boundary. In our clean isolation harness, every subshell explicitly unset GEMINI_API_KEY / GEMINI_ACCESS_TOKEN and exported GEMINI_NO_KEYRING=true; gemini-api whoami reported both credentials [unset] and API version v1beta. Crucially, whoami inspects local configuration sourcesβit does not prove remote API entitlement or quota. See experiments/01-cli-introspection/results.md for the full capture.
3. Why Is This CLI Built for AI Agents?
AI agents routinely trip over stale CLI flags, dump raw base64 media into context windows, or hang forever on interactive prompts. gemini-api avoids those traps with machine-discoverable schemas and direct file I/O.
First, probing the documentation page itself via curl -sS -I https://aistudio.google.com/docs/cli returns:
content-type: text/markdown; charset=utf-8
x-llms-txt: /llms.txt
link: </llms.txt>; rel="llms-txt", </llms-full.txt>; rel="llms-full-txt"
On the binary side, four introspection flags govern agent self-discovery:
gemini-api --usage # Complete KDL command tree
gemini-api generate --schema # Request body JSON Schema
gemini-api agent run --schema
gemini-api generate "Test prompt" --dry-run -o json
Caveat from our v0.4.6 introspection: --schema is not uniform across every subcommand. generate, image, video, and agent run succeeded, while analyze, tts, and transcribe returned exit code 2 (unknown flag: --schema). Inspect each subcommand's --help first, and check agent run --schema whenever you need full request body fidelity.
Dry-run redaction was also verified: passing a synthetic dummy --api-key outputs "X-Goog-Api-Key": ["[REDACTED]"]. Note carefully that --dry-run validates local request constructionβit does not verify server model access, billing, or IAM permissions.
While the CLI supports both JSON and TOON structured output, gemini-api v0.4.6 always emits a JSON request envelope under --dry-run:
{"dry_run":true,"request":{"method":"POST","url":"https://generativelanguage.googleapis.com/v1beta/interactions","headers":{"Accept":["text/event-stream"],"Content-Type":["application/json"],"User-Agent":["google-genai-cli/0.4.6 gl-go/go1.26.10"]},"body":{"input":"Test prompt","model":"gemini-3.8-flash","stream":true}}}
Built-in --jq also has a quirk under --dry-run: running generate "Test prompt" --dry-run --jq '.body.model' still prints the full envelope (and flips stream to false). Pipe -o json into external jq instead when filtering dry-run payloads:
gemini-api generate "Test prompt" --dry-run -o json | jq -r '.request.body.model'
Full dummy-key dry-run traces and HTTP header checks are archived in experiments/02-part1-standard-workflows/sample-dry-runs.md.
4. Core Commands & Multimodal Primitives
Using synthetic local fixtures (input.txt 64 bytes, silence.wav 0.1s 16 kHz mono PCM), all six core commands succeeded cleanly under --dry-run (exit code 0):
cd experiments/02-part1-standard-workflows
gemini-api generate "Test prompt" --dry-run --output-format json
gemini-api analyze -i input.txt "Summarize" --dry-run
gemini-api image "Minimalist cloud database icon" --out /tmp/gapi-test.jpg --dry-run
gemini-api tts "Welcome to the Taiwan developer community" --out voice.wav --dry-run
gemini-api transcribe -i silence.wav --out transcript.md --dry-run
gemini-api video "A cloud above Taipei" --out cloud.mp4 --dry-run
Every subcommand targets POST https://generativelanguage.googleapis.com/v1beta/interactions. Understanding how their JSON bodies differ explains how to wire multimodal pipelines:
| Command | Default Model (v0.4.6) |
Key Request Payload Observation |
|---|---|---|
generate |
gemini-3.8-flash |
input string, stream:true
|
analyze |
gemini-3.8-flash |
user_input.content array containing text/media + prompt, store:false, stream:false
|
image |
gemini-nano-banana-2.1 |
response_format:{"type":"image"}, stream:false
|
tts |
gemini-3.8-flash-tts |
response_format.type:audio, speech_config:[{"voice":"Kore"}], store:false
|
transcribe |
gemini-3.5-transcribe |
audio/wav input, transcription_config.mode.type:verbatim, diarization & word timestamps |
video |
gemini-omni-1.2-flash |
response_format.type:video, background:true, stream:false
|
File bytes never bloat agent context on --dry-run: analyze summarizes files as "text":"<bytes:64>" and audio as "data":"<bytes:3244>". Abbreviated TTS request body observed on v0.4.6:
{
"generation_config": {"speech_config": [{"voice": "Kore"}]},
"input": [{"content": [{"text": "Welcome to the Taiwan developer community", "type": "text"}], "type": "user_input"}],
"model": "gemini-3.8-flash-tts",
"response_format": {"type": "audio"},
"store": false,
"stream": false
}
Output handling flags such as --out remain client-side and stay out of the HTTP body. Per --help, tts outputs 24 kHz mono PCM WAV (adjusting .mp3 targets back to .wav), transcribe supports md, text, json, and srt, and video waits on background completion unless --async is passed.
4.1 End-to-End Scenario (Part 1 Perspective): 6-Step 9:16 AI Reels Pipeline
Our running scenarioβ"Understand in 15 Seconds Why AI Agents Need a Multimodal CLI Toolbox"βchains these primitives into a version-controlled pipeline:
-
Storyboard:
generate --stdincreates the 3-scene 9:16 breakdown. -
Visual Keyframes:
image --aspect-ratio 9:16 --image-size 1Kgenerates Scene 1, followed byimage -i scene1-keyframe.jpgto preserve character and visual style into Scene 2 (--previous-interaction-idcan also continue live server interactions). -
Video Motion:
video --aspect-ratio 9:16 --resolution 720p -iturns the approved Scene 1 keyframe into motion (background:true). -
Dual-Speaker Voiceover:
tts --multi-speaker "Host=Kore,CoHost=Puck". -
BGM & Subtitles:
music+transcribe --format srt. -
Safe-Zone & Alignment QA:
analyzeinspects the 9:16 composition againststoryboard.json.
See examples/reels-storyboard-pipeline/run-reels-pipeline.sh and the verbatim trace examples/reels-storyboard-pipeline/dry-run-trace.md.
Runnable Part 1 Example (sample-part1-reels-primitives.sh)
Run directly from the workspace root (examples/part1-multimodal-cli/sample-part1-reels-primitives.sh); synthetic fixtures/* validate MIME handling without incurring API charges:
bash <<'PART_SAMPLE'
(
set +x
set -euo pipefail
cd examples/part1-multimodal-cli
unset GEMINI_API_KEY GEMINI_ACCESS_TOKEN GEMINI_ENVIRONMENT_KEY GEMINI_USER_PROJECT
export GEMINI_NO_KEYRING=true
R=../reels-storyboard-pipeline
echo 'Step: offline schema discovery' >&2
gemini-api video --schema --dry-run </dev/null
echo 'Step: storyboard, keyframes, and style continuity (synthetic MIME fixtures)' >&2
gemini-api generate --stream=false --stdin 'Generate a 3-scene storyboard from the brief:' --dry-run < "$R/storyboard-brief.txt"
gemini-api image 'Taipei tech Reels keyframe' --aspect-ratio 9:16 --image-size 1K --output-mime-type image/jpeg --out /tmp/part1-scene1.jpg --dry-run </dev/null
gemini-api image 'Continue Scene 1 style' -i "$R/fixtures/scene1-keyframe.png" --aspect-ratio 9:16 --image-size 1K --output-mime-type image/jpeg --out /tmp/part1-scene2.jpg --dry-run </dev/null
echo 'Step: video, dual-speaker voiceover, music, and captions' >&2
gemini-api video 'Slow camera push on keyframe' --aspect-ratio 9:16 --resolution 720p -i "$R/fixtures/scene1-keyframe.png" --out /tmp/part1-scene1.mp4 --dry-run </dev/null
gemini-api tts --multi-speaker "Host=Kore,CoHost=Puck" -f "$R/dialogue.txt" --out /tmp/part1-voice.wav --dry-run </dev/null
gemini-api music 'Tech short background music' --out /tmp/part1-music.wav --dry-run </dev/null
gemini-api transcribe --format srt -i "$R/fixtures/voiceover-sample.wav" --out /tmp/part1-captions.srt --dry-run </dev/null
echo 'Step: keyframe & storyboard QA' >&2
gemini-api analyze -i "$R/fixtures/scene1-keyframe.png" -i "$R/storyboard.json" 'Check Reels safe-zone and storyboard alignment' --dry-run </dev/null
)
PART_SAMPLE
5. Managed Agents & Self-Hosted Agent Substrate Outlook
Beyond direct model primitives, gemini-api can launch server-managed Interactions API agents:
gemini-api agent run "Compare WebRTC SFU architectures" \
--agent deep-research-preview-04-2026 \
--background --stream=false --dry-run
Inspecting the upstream source snapshot (2030ff1) under internal/sdk/models/interactions/ reveals several typed agent configurations alongside Deep Research:
-
AntigravityAgentConfig(type:"antigravity",model,max_total_tokens) -
CodeMenderAgentConfig(type:"code-mender", FIND/FIX request & session controls) -
DynamicAgentConfig(type:"dynamic")
Important boundary: SDK type definitions do not guarantee account entitlement, nor does logging into agy locally automatically authorize API Managed Agents.
Similarly, the Self-Hosted Environments docs and Agent Substrate example (ate-gemini) outline running tool execution on your own Kubernetes/gVisor compute using either environments connect (single worker) or environments poll + environments serve (short-lived lease tokens so sandboxes never hold project API keys). Remember the security division: ate-gemini validates component mTLS, while multi-tenant user authentication and ACL enforcement remain your application's responsibility.
6. Preview of Part 2: Keyless OAuth (ADC) & User Tier Boundaries
Want to stop distributing plaintext GEMINI_API_KEY secrets across laptops and containers? In Part 2, we inspect the Keyless OAuth path (GEMINI_ACCESS_TOKEN + --user-project), troubleshoot ACCESS_TOKEN_SCOPE_INSUFFICIENT, ship a safe wrapper (bin/gapi-adc), and map Free Tier, Paid Tier 1β3, and Google AI Pro/Ultra boundaries.
7. Live Verification Addendum (2026-11-15): Full Β§4.1 Reels Run & Cost Ledger
Following the --dry-run validation above, we executed all 8 Β§4.1 multimodal steps live against project gde-jimmyliao-redeem (Paid Tier) inside tmux (2026-11-15 00:20:54 β 00:24:23 Asia/Taipei) and assembled the final 9:16 video with burned-in bilingual subtitles using local ffmpeg 8.1:
-
Zero fallbacks triggered:
gemini-3.8-flash(storyboard & QA),gemini-nano-banana-2.1(Scene 1 & Scene 2768Γ1376keyframes with crisp Traditional Chinese + English labels),gemini-omni-1.2-flash(5.03s720p video at$0.3527),gemini-3.8-flash-tts(9.44sdual-speaker voiceover),lyria-3.5(159.48strack), andgemini-3.5-transcribeall succeeded on the first call (Exit 0). -
Measured calls & cost: 8 paid calls + 4 read-only
$0agent statuspolls, consuming44,934tokens (4,506input +35,407output +5,021thought) for a calculated total of$0.54853125 USD(~$0.5485). Keyframe-first gating saved~$0.705 USDby skipping redundant video renders on Scenes 2 & 3. -
Two practical quirks caught live:
gemini-api music --out bgm.wavwroteaudio/mpeg(MP3,"extension_mismatch": true) instead of uncompressed WAV, andgemini-3.5-transcribeconverted spoken Mandarin into Simplified Chinese and misheard"ε ι©ι¦εΉ"(verify keyframes first) as"ε ιͺζι"βreinforcing why subtitle review matters before publishing.
Full per-call formulas and verified deliverables are in experiments/06-live-execution-and-cost-log/cost-and-call-ledger.md and examples/reels-storyboard-pipeline/output/final-reel.mp4.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.