Gemini CLI Notes
Background and Documentation
Configuration Layers
- User settings are in
~/.gemini/settings.json. - Project-specific
myproject/.gemini/settings.jsonfiles override~/.gemini/settings.json. You only need to specify settings whose user-level values you want to change. - API keys and some other settings are controlled via environment variables. It is recommended to store them in
~/.gemini/.envinstead of adding them directly to~/.zshrcor~/.bashrc. - Project-specific
myproject/.gemini/.envfiles shadow~/.gemini/.env. You must specify all environment variables, even if you don’t want to change their user-level values. .envtakes precedence oversettings.json, whereas command-line arguments trump both. See the Appendix at the end of the post for a deeper dive into how Gemini CLI processes configuration layers.- In particular, the current working directory will affect which
settings.json,.envandGEMINI.mdfilesgeminipicks up.
Authentication, Request Limits and Privacy
- The
"selectedAuthType"setting determines how you authenticate with Google’s AI services:"oauth-personal"(personal Google account),"gemini-api-key” (AI Studio) or"vertex-ai"(Vertex AI). - You will be prompted to pick an auth type the first time you launch Gemini CLI, or more generally any time
"selectedAuthType"isn’t found insettings.json. You can also use the/authREPL command to switch to a different auth type later. - The auth type determines the model request limits as well as what data Google collects. See the Terms of Service and Privacy Notice for details. Keep in mind that if you authenticate using your personal Google account or use the free Google AI tier, your code, prompts and responses will be used to train Google models.
- If
"selectedAuthType"is set to"oauth-personal", you will need to log into your Google account via the browser. This will create~/.gemini/google_accounts.jsonand~/.gemini/oauth_creds.json.- Currently (as of August 2025), you get the most free Gemini 2.5 Pro requests this way: 60 per minute and 1,000 per day.
- However, token caching is not available for this auth type. You can view your token usage for a given
geminisession using the/statsand/stats modelREPL commands.
- If
"selectedAuthType"is set to"gemini-api-key”, you will need toexport GEMINI_API_KEY="<Your Gemini API Key>"in e.g.~/.gemini/.env. You can obtain a Gemini API key here.- Currently (as of August 2025), the Free Tier rate limits for Gemini 2.5 Pro are 5 requests per minute and 100 requests per day. While this is considerably lower than what you get by authenticating using your personal Google account, token caching is available for this auth type.
- To get 1,000 requests per day using the Free Tier, you would need to switch to Gemini 2.5 Flash Lite (Flash Lite is a version of Lite optimized for low-latency use cases; Lite is not a “reasoning model”, unlike Pro). The lowest paid tier, Tier 1, gives you 150 requests per minute and 10,000 requests per day using Gemini 2.5 Pro.
- Anonymized usage stats, such what tools and models are used, are collected by default. Add
"usageStatisticsEnabled": falseto~/.gemini/settings.json” to opt out.
Model Selection
- You can use the
--modelcommand-line argument to override the default model (currently Gemini 2.5 Pro) like so:gemini --model <model>. - Supported
<model>values includegemini-{2.5, 2.0}-{pro, flash, flash-lite}. - You can also
export GEMINI_MODEL="<model>"in~/.gemini/.envor another.envfile.
Built-in Tools
- Gemini CLI comes with a number of built-in tools with the following execution flow. Their definitions live here.
- You can extend the list of built-in tools using MCP Servers. See this page for details.
- Use the
/toolsREPL command to list the tools available in a givengeminisession. For a longer description of each tool, run/tools desc. - Use the
coreToolssetting insettings.jsonto explicitly list what tools should be made available. For example,"coreTools" : []means that no tools will be available whereas"coreTools": ["LSTool"]means that onlyLSToolwill be available. - The name a tool appears under when you run
/toolsmay not match the one you need to use incoreTools. For example,LSToolshows up as “ReadFolder”. This is becauseLSTool.Nameis set toReadFolderinls.ts, where its definition lives. - Most built-in tools follow the pattern of
FooBarToolfor thesettings.json name, “FooBar” for the/toolsname andfoo-bar.tsfor the definition, but there are a handful of exceptions of whichLSToolis one. -
Below are the
settings.jsonnames for the built-in tools, along with what/toolscalls them and where they are defined:settings.json name /tools name definition EditTool“Edit” edit.ts GlobTool“FindFiles” glob.ts WebSearchTool“GoogleSearch” web-search.ts ReadFileTool“ReadFile” read-file.ts LSTool“ReadFolder” ls.ts ReadManyFilesTool“ReadManyFiles” read-many-files.ts MemoryTool“Save Memory” memoryTool.ts GrepTool“SearchText” grep.ts ShellTool“Shell” shell.ts WebFetchTool“WebFetch” web-fetch.ts WriteFileTool“WriteFile” write-file.ts - The default tools set correponds to having the following
coreToolssetting insettings.json:"coreTools": ["EditTool", "GlobTool", "WebSearchTool", "ReadFileTool", "LSTool", "ReadManyFilesTool", "MemoryTool", "GrepTool", "ShellTool", "WebFetchTool", "WriteFileTool"] - You can also use the
excludeToolssetting insettings.jsonto remove specific tools from the default list. For example, adding"execludeTools": ["ShellTool"]tosettings.jsonwill removeShellfrom the list of available/tools. - A tool listed in both
coreToolsandexcludeToolsis excluded. This means that you could list the default tool set incoreToolsand specify just the ones you want to disallow inexcludeTools. - For example, if
settings.jsoncontains the following"coreTools": ["EditTool", "GlobTool", "WebSearchTool", "ReadFileTool", "LSTool", "ReadManyFilesTool", "MemoryTool", "GrepTool", "ShellTool", "WebFetchTool", "WriteFileTool"] "excludeTools": ["WebSearchTool", "ShellTool", "WebFetchTool"]then
/toolswon’t showGoogleSearch,ShellandWebFetch, whereas the rest of the default tools will remain available. - Keep in mind that
ShellToolcan execute arbitrary shell commands and thus poses a security risk. To help mitigate this,ShellToolsupports granular command restrictions. - For example, to enable only
gitto be executed, replace"coreTools": ["ShellTool"]with"coreTools": ["run_shell_command(git)"]insettings.json. - Although you can also use
run_shell_commandinexcludeTools, this is not recommended for security reasons. - Although restricting the commands
ShellToolcan execute viarun_shell_commanddoes provide a measure of security, it is nevertheless a good idea to enable sandboxing if you are going to makeShellToolavailable (which it is by default, with no command restrictions).
Sandboxing
- Sandboxing is off by default. Add
"sandbox": trueto~/.gemini/settings.jsonto turn it on. - When sandboxing is enabled, Gemini CLI will only be able to call tools supported by the sandbox environment, regardless of what tools are included via
coreToolsandexcludeToolsinsettings.json. - The default sandboxing methodology is platform-specific: Seatbelt on a Mac and Docker elsewhere.
- On a Mac,
export SEATBELT_PROFILE="<profile>"in~/.gemini/.envto select your Seatbelt profile. The built-in profiles are{permissive, restrictive}-{open, proxied, closed}. The default ispermissive-open, which restricts writes outside of the project directory but allows most other operations. export SEATBELT_PROFILE="custom"in.gemini/.envto use a custom Seatbelt profile stored in.gemini/sandbox-macos-custom.sb. You can start by copying one of the built-in profiles, which live here and follow the naming schemasandbox-macos-<profile-name>.sb(e.g.sandbox-macos-permissive-open.sbforpermissive-openandsandbox-macos-permissive-closed.sbforpermissive-closed).- See this page for some general pointers on creating custom Seatbelt profiles. They are written in a language called SBPL (“SandBox Profile Language”), which is a Scheme-based embedded DSL. The Apple Sandbox Guide has the details.
- Adding
"sandbox": true"tosettings.jsonis the equivalent of runninggemini --sandbox(the--sandboxcommand-line argument is a boolean flag). Alternatively, you can explicitly set"sandbox"to one of the supported methodologies:"docker","sandbox-exec"(Mac only) or"podman". - In particular, you can use Docker-based sandboxing on the Mac by specifying
"sandbox: "docker"insettings.json. You will need Docker Desktop for the Mac to be installed and running for this to work properly. - Similar to having a custom Seatbelt profile, you can also create a custom Dockerfile in
myproject/.gemini/sandbox.Dockerfile, as described here. - Per the docs, you should be able to add
export BUILD_SANDBOX=1tomyproject/.gemini/.envand havegeminiautomatically build the custom Docker image. - When I tried this on a Mac, though (with Gemini CLI installed via
brew install gemini-cli), I got the following error:ERROR: cannot build sandbox using installed gemini binary; run `npm link ./packages/cli` under gemini-cli repo to switch to linked binary.This is apparently a known issue.
Instructional Context (“Memory”)
- Gemini CLI loads instructional context (aka “memory”) from files named
GEMINI.md(the name can be changed via thecontextFileNamesetting insettings.json). - For an example, have a look at Gemini CLI’s own GEMINI.md.
- Context loaded from
GEMINI.mdfiles uses up context window tokens. This should not be material for Gemini 2.5 Pro, whose context window is large (1 million tokens). - Store user-level context in
~/.gemini/GEMINI.md. You can add to it dynamically using the/memory addREPL command. - Store
myproject-specific context inmyproject/GEMINI.md(rather thanmyproject/.gemini/GEMINI.md). In other words, put it in the same sort of places where aREADME.mdwould go. - Project-specific context will be merged with user-level context. Run the
/memory showREPL command to see the overall, merged context. - Context can be controlled in hierarchical way using multiple
GEMINI.mdfiles, with the directory you launchgeminifrom determining which ones are loaded. The details are here.
An Illustrative Example
Say that you are on a Mac and didn’t set any Gemini CLI-related environment variables in ~/.zshrc or ~/.bashrc. Assume that your user-level Gemini CLI configuration looks like this:
~/.gemini/settings.json:
{
"theme": "Dracula",
"usageStatisticsEnabled": false,
"sandbox": true,
"selectedAuthType": "gemini-api-key"
}
~/.gemini/.env:
export GEMINI_API_KEY="<Your Gemini API Key>" https://aistudio.google.com/apikey
export GEMINI_MODEL="gemini-2.5-flash-lite" # gemini-{2.5, 2.0}-{pro, flash, flash-lite}
~/.gemini/GEMINI.md:
## User-level context
Now suppose that you have a project called myproject, configured like this:
myproject/.gemini/settings.json:
{
"selectedAuthType": "oauth-personal",
"excludeTools": ["ShellTool"]
}
myproject/.gemini/.env:
export SEATBELT_PROFILE="custom" # {permissive, restrictive}-{open, proxied, closed}
myproject/.gemini/sandbox-macos-custom.sb:
;; a suitably modified copy of sandbox-macos-permissive-open.sb, say
myproject/GEMINI.md:
## Project-specific context
myproject/some_module/GEMINI.md:
## Module-specific context
- If you run
geminioutsidemyproject:- You will authenticate using a Gemini API key, as per
~/.gemini/settings.json - The API key will be read from
~/.gemini/.env(commenting outGEMINI_API_KEYwill result in an error). - Sandboxing will be enabled, as per
~/.gemini/settings.json. - Since no sandboxing methodology was specified explicitly,
sandbox-execwill be used (the Mac default). - The Seatbelt profile used will be
permissive-open(the default). - The model used will be Gemini 2.5 Flash Lite, as per
~/.gemini/.env. - The default tool set will be availalbe. Run the
/toolsREPL command to confirm. - The instructional context should consist of the user-level context in
~/.gemini/GEMINI.mdalone, unless otherGEMINI.mdfiles happen to have been picked up based on your current working directory. Run the/memory showREPL command to confirm.
- You will authenticate using a Gemini API key, as per
- On the other hand, if you
cd myproject; gemini:- You will authenticate using your Google account, as per
myproject/.gemini/settings.json. - Since there is no need for an API key, commenting out
GEMINI_API_KEYin~/.gemini/.envwon’t have an effect. - The Seatbelt profile used will be
myproject/.gemini/sandbox-macos-custom.sb, as dictated bymyproject/.gemini/.env. - Irrespective of what
~/.gemini/.envsays, the model used will be Gemini 2.5 Pro (the default), even though you didn’t specifyGEMINI_MODELinmyproject/.gemini/.env. Sincegeminifindsmyproject/.gemini/.envfirst, the contents of~/.gemini/.envare irrelevant. ShellToolwon’t be available, permyproject/.gemini/settings.json. Run the/toolsREPL command to confirm.- The instructional context will be a combination of user-level context from
~/.gemini/GEMINI.md, project-specific context frommyproject/GEMINI.mdand module-specific context frommyproject/some_module/GEMINI.md. Run the/memory showREPL command to confirm. - Since command-line argument take precedence over
settings.jsonand.envfiles, even after youcd myprojectyou can still:- Turn off sandboxing via
gemini --sandbox false - Explicitly select a different model via
gemini --model gemini-2.5-flash.
- Turn off sandboxing via
- You will authenticate using your Google account, as per
VSCode Integration
There is now a VSCode extension called Gemini CLI Companion, which lets Gemini CLI talk to VSCode for a Cursor-like experience, albeit limited to Gemini models (this is separate from the existing Gemini Code Assist VSCode extension, which provides GitHub Copilot-style code completions). gemini will see what files you have open as well as what the current selection is, and the changes it proposes will be displayed directly in the editor. While integration is clunkier than Cursor overall, you get to use Microsoft’s official extensions such as the C++ one.
You can either install Gemini CLI Companion manually or launch gemini from VSCode’s built-in terminal and use the /ide install REPL command. You can then run the /ide status REPL command to confirm that gemini successfully connected to VSCode.
At the moment (September 2025) there seems to be a known issue with sandboxing disrupting communication between Gemini CLI Companion and gemini. The official workaround, at least for now, is to turn sandboxing off completely. You can do this at the myproject level by creating myproject/.gemini/settings.json with the following content:
{
"sandbox": false
}
Appendix: Configuration Layer Processing
We can use sandboxing to illustrate the order in which Gemini CLI processes “configuration layers”, since sandboxing is off by default and can alternatively be turned on via settings.json files, .env files and command-line arguments:
- Create an empty project directory:
mkdir -p ~/junk/myproject. cd ~/junk/myprojectso thatmyprojectis your current project.- Run
gemini. Sandboxing is off (the status bar at the bottom will say “no sandbox (see /docs)”). Exitgemini. - Add
"sandbox": trueto the user-level settings in~/.gemini/settings.json. You should also see additional settings there, such as"theme"and"selectedAuthType". - Run
gemini. Sandboxing is on (on a Mac, the status bar will say “macOS Seatbelt (permissive-open)” if you are using the default Seatbelt profile). Exitgemini. - Create a project-specific
settings.jsonfile:mkdir .gemini; echo '{"sandbox": false}' > .gemini/settings.json. - Run
gemini. Sandboxing is off, because project-levelsettings.jsonsettings override user-levelsettings.jsonsettings. Note that you only need to specify the value ofsandbox, the setting you want to override. Exitgemini. - Set the
GEMINI_SANDBOXenvironment variable via a user-level.envfile:echo 'export GEMINI_SANDBOX="true"' >> ~/.gemini/.env. - Run
gemini. Sandboxing in on, because environment variables take precedence oversettings.jsonsettings. Exitgemini. - Create a project-specific
.envfile:echo 'export GEMINI_SANDBOX="false"' > .gemini/.env.- This is sufficient if
"selectedAuthType"is set to"oauth-personal"in~/.gemini/settings.json. - However, unlike with project-level
settings.jsonoverrides (where onlysandboxneeded to be specified), all relevant environment variables must be specified in.gemini/.envand not justGEMINI_SANDBOX. - For example, if
"selectedAuthType"is set to"gemini-api-key"in~/.gemini/settings.json, you will need to addexport GEMINI_API_KEY="<Your Gemini API Key>"tomyproject/.gemini/.envin order to successfully authenticate yourself when runninggeminifrommyproject.
- This is sufficient if
- Run
gemini. Sandboxing in off, because the project-specific.gemini/.envfile shadows the user-level~/.gemini/.envfile. Exitgemini. - Run
gemini --sandbox. Sandboxing is on, because command-line arguments take precedence over environment variables.