Gemini CLI (gemini)
Output
GEMINI.md # canonical entry-point pointer body (written by sync)
.gemini/agents/<name>.md # one per agent, Gemini's native subagent surface
.gemini/commands/<name>.toml # one per command
.gemini/skills/<name>/SKILL.md # one folder per skill, bundled assets included
.gemini/commands/skill-<name>.toml # additional command form, only when emit-skills-as-commands: true
.gemini/settings.json # when MCP and/or hook entries exist (merged with existing user config)
.geminiignore # when ignore entries exist
Rules: unscoped rules inline into the root
GEMINI.md. A rule withscope: services/paymentsinstead reachesservices/payments/GEMINI.md. Aglobsfield alone does not create a directory scope. Remove legacyoutputs.gemini.rules-fileoverrides before using scoped rules. See scoped context for selector and runtime limits.Agents: one native subagent per agent at
.gemini/agents/<name>.md. Gemini CLI's subagents doc states "Custom agents are defined as Markdown files (.md) with YAML frontmatter ... Project-level:.gemini/agents/*.md(Shared with your team)", cross-confirmed by/agents reload, which "Rescans agent directories (~/.gemini/agentsand.gemini/agents)". That surface buys automatic delegation, an isolated context window,@nameinvocation, and the/agentslisting.Until this release, agents emitted as a slash-command TOML instead. An agent was a prompt the user had to type rather than a subagent Gemini could delegate to, and it shared a directory and a
<name>.tomlfilename with commands, so a same-named agent and command overwrote each other (target-audit 2026-09-11, #733).Frontmatter carries the two required fields,
nameanddescription(falling back to the spec name), pluskind,model,temperature,max_turns, andtimeout_minswhen declared; the body is the system prompt.mcpServers(inline per-agent MCP servers) is documented too and has no agnostic-ai field, so it reaches the file throughx-gemini.A spec's generic
toolslist translates onto Gemini's own tool names:Readtoread_file,Writetowrite_file,Edittoreplace,Globtoglob,Greptogrep_search,Bashtorun_shell_command,WebFetchtoweb_fetch,WebSearchtogoogle_web_search. A name outside that set is dropped with a coverage note rather than written unconfirmed: an unknown entry here restricts the subagent to a tool that does not exist, while an absenttoolskey inherits every tool from the parent session. Setx-gemini.toolsto write Gemini's own vocabulary directly, including the documented*,mcp_*, andmcp_<server>_*wildcards; that override wins outright over the translated form.Set
outputs.gemini.emit-agents-as-commands: trueto also keep writing the old<name>.tomlslash command, for a project that already types/name. With the key off, a managed TOML an earlier sync left there is swept.Skills: native Agent Skills folders under
.gemini/skills/<name>/SKILL.md(the workspace tier Gemini CLI scans). It also reads the cross-tool.agents/skills/alias, which takes precedence over.gemini/skills/within the same tier when a skill shares a name in both (target-audit 2026-08-08, #563). Gemini CLI resolves that conflict itself at session start, so no sync-time detection is needed here. Bundled sibling files propagate byte-for-byte. Setoutputs.gemini.emit-skills-as-commands: trueto additionally emit oneskill-<name>.tomlcommand per skill.Commands: one TOML per command spec under
.gemini/commands/<name>.toml, the directory Gemini reads project slash commands from.descriptionfrontmatter maps to the TOMLdescription; the body becomes theprompt. Agents left this directory in #733, so a command and an agent may now share a name without overwriting each other.MCP + hooks: written into
.gemini/settings.json(mcpServersmap,hooksmap). Gemini keys the endpoint by transport: streamable-HTTP servers (type: http) usehttpUrl, SSE servers (type: sse) useurl. The adapter routes each automatically. Stdio servers also acceptcwd(working directory), the same cross-tool field Codex reads.Every server, any transport, also accepts
timeout(milliseconds),trust(bypass tool-call confirmations),description,includeTools, andexcludeTools; all five pass through verbatim (geminicli.com/docs/reference/configuration, #661).Hooks route by
eventfrontmatter. Gemini CLI documents 11 events:BeforeTool,AfterTool,BeforeAgent,AfterAgent,Notification,SessionStart,SessionEnd,PreCompress,BeforeModel,AfterModel,BeforeToolSelection. Each definition containsmatcherand a nestedhooksarray of{type: "command", command}handlers, as required by the hook reference. Portable hook timeouts convert from seconds to milliseconds; the vendor default is 60000 ms. Acommandlist becomes separate handlers kept in one definition. Setx-gemini.sequential: trueto run them in order.descriptionreaches each handler,x-gemini.namesets its display name, andx-gemini.envsupplies per-handler environment variables. Pre-existing user keys survive syncs.Ignore: ignore specs emit as
.geminiignore(gitignore syntax), the file Gemini CLI reads. Multiple specs concatenate. Override viaoutputs.gemini.ignore-file. Up to v0.49 this wrote.aiexclude, which belongs to Gemini Code Assist and Gemini CLI never opens; a managed.aiexcludeis removed on the next sync. (#625)Import:
import geminireads every native directory on its own pass..gemini/agents/*.mdbecomes agent specs,.gemini/commands/*.tomlbecomes command specs,.gemini/skills/<name>/becomes skill folders, and.gemini/settings.jsonbecomes MCP and hook specs. A command'spromptbecomes the spec body in either form Gemini documents, the triple-quoted block or the single-line string, anddescriptionstays in frontmatter.A project synced before #733 emitted its agents as command TOMLs; those import as commands, since
.gemini/commands/is the slash-command directory, and a re-sync writes them back to the same path. The mirror TOMLsemit-agents-as-commandsandemit-skills-as-commandswrite import as command specs too, for the same reason; the emitted bytes stay identical across the round-trip (#750).Native nested hooks preserve commands, matchers, names, descriptions, environment maps, timeouts, and sequential groups. Distinct definitions with the same command and matcher import into separate files. A single handler's timeout imports in seconds when it is a whole second; otherwise
x-gemini.timeoutkeeps the native milliseconds. Multiple handlers stay together underx-gemini.hooks, which replacescommandemission for Gemini; old flat hook files still import (#762).
Config keys
| Key | Default | Notes |
|---|---|---|
outputs.gemini.agents-dir | .gemini/agents | |
outputs.gemini.commands-dir | .gemini/commands | |
outputs.gemini.skills-dir | .gemini/skills | |
outputs.gemini.mcp-file | .gemini/settings.json | also holds hooks |
outputs.gemini.emit-skills-as-commands | false | |
outputs.gemini.emit-agents-as-commands | false | |
outputs.gemini.rules-file | unset | writes legacy concatenated rules and skips the pointer-body write |
outputs.gemini.ignore-file | .geminiignore |
Verify
- Install:
npm install -g @google/gemini-cli(docs). - Check the tree:
ls GEMINI.md .gemini/agents/ .gemini/commands/ .gemini/settings.json,head -2 .gemini/agents/*.md(frontmatter first),head -1 .gemini/commands/*.tomlfor the provenance header,python -m json.tool .gemini/settings.json > /dev/null. gemini --list-commandsparses every<name>.tomlwith no "invalid TOML" / "unknown field" errors, and/agentslists every.gemini/agents/<name>.mdas delegatable.gemini --list-mcp-serversshows eachmcpServers.<name>ready.- Trigger a hook by performing the matcher action (e.g. an
AfterTool); the hook command runs.