Gemini CLI is Google's open-source coding agent for the terminal: it reads and edits your code, runs shell commands, fetches web pages, grounds answers in Google Search, and connects to MCP servers, all driven by Gemini models with a context window of up to a million tokens. It runs interactively or headless with JSON output for scripts, keeps project instructions in GEMINI.md files, and has a GitHub Action for reviews and issue triage.
The context around it has changed. In May 2026 Google announced that personal use moves to a new, separate Antigravity CLI, and since June 18, 2026 Gemini CLI no longer serves the free tier or Google AI Pro and Ultra subscribers. It still works with paid Gemini API keys, Vertex AI, and Gemini Code Assist Standard or Enterprise licences, and the repository is still active, with weekly releases under Apache-2.0. The README's free-tier section predates the change.
- Repository: github.com/google-gemini/gemini-cli
- Licence: Apache-2.0 (Apache License 2.0)
- Language: TypeScript. Stars: 107.2K. Forks: 14.6K. Last push: Sep 26, 2026.
- Scan: safe, Sep 25, 2026, commit 2fe7c2d
Who it is for
Teams on Google Cloud or a Gemini Code Assist licence who want an open-source agent in the terminal or in CI, and developers with a paid Gemini API key who want to read and control the agent they run.
Getting started
1. Install with npm (or brew install gemini-cli; npx @google/gemini-cli runs it without installing)
npm install -g @google/gemini-cli2. Give it a paid Gemini API key, or sign in with a Code Assist licence or Vertex AI
export GEMINI_API_KEY="YOUR_API_KEY"3. Start it in a project
cd your-project && geminiSince June 18, 2026 personal Google accounts, the free tier and AI Pro and Ultra plans no longer work here; Google points those users to Antigravity CLI. A paid API key, Vertex AI or a Code Assist Standard or Enterprise licence still does.
Safety scan
We cloned google-gemini/gemini-cli at commit 2fe7c2d on Sep 25, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets: all 29 candidates are fake tokens and keys in tests, most of them in the tests for the environment sanitizer that strips real credentials before the agent runs commands. The bare IPs are test cases for its private-address check (CGNAT and benchmark ranges, 8.8.8.8).
- The pattern hits are the Antigravity banner, which prints Google's curl | bash install command for the Antigravity CLI and does not run it, and a comment in shell-utils.ts about passing the CLI's own parser script to PowerShell with -EncodedCommand.
- Five committed binaries: ripgrep builds for macOS, Linux and Windows in packages/core/vendor/ripgrep, about 21 MB, used by the search tool. They carry ripgrep's own project strings, but they are prebuilt files you take on trust rather than code you can read. The one installer script deploys an internal maintenance agent to a Google-internal host.
- Known advisories: 135, 5 critical, all in the main lockfile. Two are runtime dependencies pinned in the CLI and core packages: simple-git 3.28.0 (an unsafe-operations guard bypass) and shell-quote 1.8.3 (newlines not escaped in quote()). Both need hostile input to reach; the other critical ones are Vitest and tar in the build tooling.
- 47 workflows. Three use pull_request_target; the eval job checks out the pull request only after manual approval through a protected environment, and the other two do not run PR code. All 31 third-party actions pinned to a commit. Security policy, Dependabot and CodeQL all present.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | 29 candidates found and read; see the notes above. |
| Suspicious code | 8 pattern hits found and read; every one is listed under the raw findings. |
| Install-time code | 2 npm lifecycle scripts. 1 installer script |
| Committed binaries | 5 executable or compiled objects committed; listed under the raw findings. |
| CI workflows | 47 workflows. 3 use pull_request_target, none check out the pull request head. 0 of 31 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often auth.example.com, github.com, goo.gle, google.com. 9 URLs to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 135 advisories across 1,526 pinned packages: 5 critical, 72 high, 50 moderate, 8 low. package-lock.json: 1,513 packages, 127 advisories; tools/caretaker-agent/cloudrun/egress-service/package-lock.json: 271 packages, 7 advisories; tools/caretaker-agent/cloudrun/ingestion-service/package-lock.json: 313 packages, 9 advisories. |
| Project hygiene | Has security policy, automated dependency updates, CodeQL, licence file, contributing guide. |
| OpenSSF Scorecard | Not scored: the project is not in Scorecard's weekly index. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Secret candidates (29, redacted)
Pattern hits (8)
| Where | Rule | Match |
|---|---|---|
| packages/cli/src/ui/commands/helpCommand.test.ts:62 | download-piped-to-shell | text: `To install the Antigravity CLI on macOS, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`, |
| packages/cli/src/ui/commands/helpCommand.test.ts:75 | download-piped-to-shell | text: `To install the Antigravity CLI on Linux, run the following command:\n\n'curl -fsSL https://antigravity.google/cli/install.sh | bash'`, |
| packages/cli/src/ui/hooks/useBanner.test.ts:160 | download-piped-to-shell | `Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`, |
| packages/cli/src/ui/hooks/useBanner.test.ts:171 | download-piped-to-shell | `Welcome to Antigravity!\n \nTo install run "${chalk.bold('curl -fsSL https://antigravity.google/cli/install.sh | bash')}"`, |
| packages/cli/src/ui/utils/antigravityUtils.test.ts:25 | download-piped-to-shell | installCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash', |
| packages/cli/src/ui/utils/antigravityUtils.test.ts:36 | download-piped-to-shell | installCmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash', |
| packages/cli/src/ui/utils/antigravityUtils.ts:10 | download-piped-to-shell | 'curl -fsSL https://antigravity.google/cli/install.sh | bash'; |
| packages/core/src/utils/shell-utils.ts:195 | powershell-encoded | // Encode the parser script as UTF-16LE base64 so we can pass it via PowerShell's -EncodedCommand flag; |
URLs to bare IP addresses (9)
| Where | Rule | Match |
|---|---|---|
| packages/core/src/utils/fetch.spec.ts:211 | ip-literal-url | 'http://100.64.0.1:8080/', |
| packages/core/src/utils/fetch.spec.ts:212 | ip-literal-url | 'http://100.127.255.254/', |
| packages/core/src/utils/fetch.spec.ts:213 | ip-literal-url | 'http://198.18.0.1:8080/', |
| packages/core/src/utils/fetch.spec.ts:214 | ip-literal-url | 'http://198.19.255.254/', |
| packages/core/src/utils/fetch.spec.ts:389 | ip-literal-url | expect(await isPrivateIp('http://8.8.8.8/')).toBe(false); |
| packages/core/src/utils/fetch.spec.ts:390 | ip-literal-url | expect(await validateUrlDestination('http://8.8.8.8/')).toBe(true); |
| packages/core/src/utils/fetch.spec.ts:391 | ip-literal-url | expect(await isPrivateIp('http://93.184.216.34/')).toBe(false); |
| packages/core/src/utils/fetch.spec.ts:392 | ip-literal-url | expect(await validateUrlDestination('http://93.184.216.34/')).toBe(true); |
| packages/core/src/utils/fetch.test.ts:144 | ip-literal-url | expect(await isPrivateIp('http://8.8.8.8/')).toBe(false); |
npm lifecycle scripts (2)
package.jsonprepare:husky && npm run bundlepackages/vscode-ide-companion/package.jsonprepare:npm run generate:notices
Installer scripts (1)
- tools/caretaker-agent/scripts/deploy.sh, 93 lines; talks to pantheon.corp.google.com
Committed binaries (5)
packages/core/vendor/ripgrep/rg-linux-x64: ELF, 5 MBpackages/core/vendor/ripgrep/rg-win32-x64.exe: PE (Windows executable), 5 MBpackages/core/vendor/ripgrep/rg-darwin-x64: Mach-O, 4 MBpackages/core/vendor/ripgrep/rg-linux-arm64: ELF, 4 MBpackages/core/vendor/ripgrep/rg-darwin-arm64: Mach-O, 3 MB
Worst known vulnerabilities (24 of 135)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-w7jw-789q-3m8p | critical | shell-quote@1.8.3 | shell-quote quote() does not escape newlines in object .op values |
| GHSA-r275-fr43-pm7q | critical | simple-git@3.28.0 | simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key enables RCE |
| GHSA-5xrq-8626-4rwp | critical | vitest@3.2.4 | When Vitest UI server is listening, arbitrary file can be read and executed |
| GHSA-23hp-3jrh-7fpw | critical | tar@7.5.11 | node-tar: Decompression/parse DoS via unlimited input |
| GHSA-5xrq-8626-4rwp | critical | vitest@3.1.1 | When Vitest UI server is listening, arbitrary file can be read and executed |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@1.1.14 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@1.1.14 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@1.1.14 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-5375-pq7m-f5r2 | high | @grpc/grpc-js@1.14.3 | @grpc/grpc-js: A malformed request can cause a server crash |
| GHSA-99f4-grh7-6pcq | high | @grpc/grpc-js@1.14.3 | @grpc/grpc-js: An incoming malformed compressed message can cause a client or server crash |
| GHSA-345p-7cg4-v4c7 | high | @modelcontextprotocol/sdk@1.23.0 | @modelcontextprotocol/sdk has cross-client data leak via shared server/transport instance reuse |
| GHSA-8r9q-7v3j-jr4g | high | @modelcontextprotocol/sdk@1.23.0 | Anthropic's MCP TypeScript SDK has a ReDoS vulnerability |
| GHSA-w48q-cv73-mx4w | high | @modelcontextprotocol/sdk@1.23.0 | Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protection by default |
| GHSA-45rx-2jwx-cxfr | high | @opentelemetry/propagator-jaeger@2.7.1 | OpenTelemetry JavaScript: Denial of service in `JaegerPropagator` via unhandled exception on a malformed header |
| GHSA-2883-xcg3-v3hh | high | js-yaml@3.14.2 | js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources |
| GHSA-52cp-r559-cp3m | high | js-yaml@3.14.2 | js-yaml: YAML merge-key chains can force quadratic CPU consumption |
| GHSA-5p4m-2wfm-xmqj | high | js-yaml@3.14.2 | JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) - CVE-2026-59870 fix not backported |
| GHSA-hmw2-7cc7-3qxx | high | form-data@2.5.5 | form-data: CRLF injection in form-data via unescaped multipart field names and filenames |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@5.0.5 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@5.0.5 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@5.0.5 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@2.1.0 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@2.1.0 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@2.1.0 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
Workflows worth a look
- .github/workflows/eval-pr.yml: pull_request_target
- .github/workflows/pr-rate-limiter.yaml: pull_request_target
- .github/workflows/pr-size-labeler.yml: pull_request_target
By the numbers
| Stars | 107.2K |
|---|---|
| Forks | 14.6K |
| Contributors | 699 |
| Commits | 6,443 |
| Open issues | 529 |
| Open pull requests | 278 |
| Releases | 640 |
| Latest release | v0.61.0 |
| Licence | Apache-2.0 |
| Main language | TypeScript |
| Project age | 1 year |
| Last push | Sep 26, 2026 |
| Tracked files | 3,017 |
| Lines of code | 751.5K |
| Checkout size | 108 MB |
Lines by language: TypeScript 678.9K, Markdown 32.4K, JavaScript 13.1K, JSON 9,231, YAML 9,029, Python 5,905.
Questions
Is Gemini CLI free?
The software is Apache-2.0 and free, but free use of the model ended on June 18, 2026: Gemini CLI no longer serves the free tier, personal Google sign-in, or Google AI Pro and Ultra. It works with a paid Gemini API key billed per token, Vertex AI, or a Gemini Code Assist Standard or Enterprise licence.
What is Antigravity CLI, and is Gemini CLI going away?
Antigravity CLI is Google's new terminal agent, written in Go, which takes over personal and consumer-plan use. Gemini CLI remains for paid API keys, Vertex AI and enterprise Code Assist licences, and the repository is still releasing weekly. If you signed in with a personal Google account, you have to move to Antigravity CLI or a paid key.
Does Gemini CLI run commands without asking?
Not by default: it asks before shell commands and file changes, and a trusted-folders setting controls where it may act at all. A --yolo flag approves everything, and optional sandboxing runs tools in a container or under macOS Seatbelt. Either way, the files it reads are sent to Gemini as context.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
