How does Gemini CLI use MCP?
Gemini CLI connects to MCP (Model Context Protocol) servers listed under mcpServers in your settings.json, and every tool those servers expose becomes a tool the model can call. You can add servers by editing the JSON or with the gemini mcp add command, and check them in a session with /mcp.
The MCP server docs describe three transports, picked by which key you set:
| Key | Transport | Typical use |
|---|---|---|
command |
stdio | A local process such as npx, node, python or docker |
httpUrl |
Streamable HTTP | A remote or local HTTP server |
url |
SSE (Server-Sent Events) | Older remote servers |
Besides tools, Gemini CLI also picks up MCP prompts (they become slash commands) and MCP resources (you can reference them with @).
How do you add an MCP server with gemini mcp add?
The command writes the config for you. By default it uses stdio and project scope (.gemini/settings.json):
# local stdio server
gemini mcp add playwright npx @playwright/mcp@latest
# pass environment variables
gemini mcp add -e API_KEY=123 my-server /path/to/server arg1
# remote HTTP server with an auth header
gemini mcp add --transport http --header "Authorization: Bearer abc123" secure-http https://api.example.com/mcp/
# SSE server
gemini mcp add --transport sse sse-server https://api.example.com/sse/
# add for every project instead of this one
gemini mcp add --scope user playwright npx @playwright/mcp@latest
The flags documented in the MCP reference:
| Flag | Meaning |
|---|---|
-s, --scope |
user or project (default project) |
-t, --transport |
stdio, sse or http (default stdio) |
-e, --env |
Set an environment variable, KEY=value |
-H, --header |
Set an HTTP header for SSE and HTTP servers |
--timeout |
Connection timeout in milliseconds |
--trust |
Skip all tool confirmation prompts for this server |
--description |
A description for the server |
--include-tools, --exclude-tools |
Comma-separated tool allow or block lists |
To pass a flag to the server itself rather than to Gemini CLI, put it after --, as in gemini mcp add python-server python server.py -- --server-arg my-value.
The other management commands:
gemini mcp list # every server, with Connected or Disconnected
gemini mcp remove my-server # delete it (add --scope user if it lives there)
gemini mcp disable my-server # keep the config, stop connecting
gemini mcp enable my-server # turn it back on
enable and disable accept --session to apply only to the current session. Enablement state is stored in ~/.gemini/mcp-server-enablement.json.
How do you configure mcpServers in settings.json?
You can always write the JSON yourself. User-wide servers go in ~/.gemini/settings.json; project servers go in .gemini/settings.json. Here is the GitHub server from Google's MCP setup tutorial, which runs in Docker:
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:latest"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}
Each server needs one of command, url or httpUrl. The optional fields:
| Field | What it does |
|---|---|
args |
Arguments for a stdio command |
env |
Environment variables for the server; values can use $VAR or ${VAR} |
cwd |
Working directory for a stdio server |
headers |
HTTP headers for url or httpUrl servers |
timeout |
Request timeout in ms (default 600,000, which is 10 minutes) |
trust |
true skips every confirmation for this server's tools (default false) |
includeTools |
Only these tools are available (allowlist) |
excludeTools |
These tools are hidden; wins over includeTools |
A top-level mcp object sets rules for all servers: mcp.allowed lists the only server names allowed to connect and mcp.excluded lists names to skip. The --allowed-mcp-server-names launch flag does the same for one run.
What do more examples look like?
A local HTTP server with a timeout:
{
"mcpServers": {
"httpServer": {
"httpUrl": "http://localhost:3000/mcp",
"timeout": 5000
}
}
}
Playwright's browser automation server, using the standard config from the Playwright MCP README, which points Gemini CLI users to the same block:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
A server limited to a few safe tools:
{
"mcpServers": {
"filteredServer": {
"command": "python",
"args": ["-m", "my_mcp_server"],
"includeTools": ["safe_tool", "file_reader"],
"timeout": 30000
}
}
}
For ideas on which servers are worth adding, see the best MCP servers guide. When a server's README publishes an mcpServers JSON block like Playwright's, you can paste it into Gemini CLI's settings.json as long as it only uses the fields listed above.
How do you use MCP tools in a session?
Restart Gemini CLI (or run /mcp reload) after changing the config. Then:
/mcpor/mcp listshows each server's status, tools, prompts and resources./mcp descadds descriptions and/mcp schemaadds descriptions and schemas.- Ask in plain language, such as "list the open PRs in my repo." The model picks the matching tool and asks for confirmation unless the server is trusted.
- MCP prompts run as slash commands, for example
/poem-writer --title="Gemini CLI"or with positional arguments. - MCP resources are referenced like files:
@server://resource/path.
Every MCP tool gets a fully qualified name in the form mcp_{serverName}_{toolName}, such as mcp_github_list_pull_requests. The docs warn against underscores in server names: use my-server, not my_server, because the policy parser splits the name on the first underscore after mcp_ and rules can "fail silently."
How do remote servers and OAuth work?
For remote servers using SSE or HTTP, Gemini CLI supports OAuth 2.0. If a server answers with 401 Unauthorized, the CLI discovers its OAuth endpoints, opens your browser, and stores the tokens for future sessions. Manage it with:
/mcp auth list servers that need authentication
/mcp auth serverName sign in, or sign in again after tokens expire
The browser flow needs a local browser and a redirect to http://localhost:<random-port>/oauth/callback, so it won't work in headless environments, remote SSH sessions without X11 forwarding, or containers without browser support. In those cases, use a header with an API token instead.
For Google Cloud services, the config also supports authProviderType values such as service_account_impersonation, with targetAudience and targetServiceAccount.
How does Gemini CLI keep MCP servers safe?
- Environment redaction. When it starts a server, Gemini CLI strips sensitive variables it inherited from your shell, such as
GEMINI_API_KEY,GOOGLE_API_KEYand anything matching patterns like*TOKEN*,*SECRET*or*KEY*. A server only gets a secret if you list it in that server'senvblock. - Use expansion, not literals. Write
"MY_KEY": "$MY_KEY"so the value comes from your environment at runtime instead of sitting in the file. - Trust is opt in.
trust: trueor--trustturns off every confirmation for that server. Leave it off for servers that can write or delete. - Folder trust. stdio servers only start, and only show as Connected in
gemini mcp list, when the current folder is trusted. Run/permissions trustin a session to trust it. - Filter tools.
includeToolsandexcludeToolskeep risky tools away from the model entirely.
How do extensions bundle MCP servers?
Extensions can ship MCP servers in their gemini-extension.json under the same mcpServers key, so gemini extensions install <url> can set up a server for you. The extension reference notes that all server options are supported except trust, and that if an extension and your settings.json define a server with the same name, the one in settings.json wins.
If you move to Antigravity CLI, note that Google's migration guide moves MCP definitions out of settings.json into separate mcp_config.json files and renames the remote url or httpUrl key to serverUrl.
How does this compare to MCP in other agents?
The mcpServers JSON shape is close to what other agents use, so a server's config usually ports with small changes. Claude Code adds servers with claude mcp add and has its own scopes; see Claude Code MCP. If you're deciding whether a job needs a server at all, skills vs MCP explains when a SKILL.md folder is the lighter choice.
MCP configs and the prompts you use with them are worth keeping somewhere permanent. Kipt stores prompts and Agent Skills as Markdown in a private GitHub repo you own, with {{name}} blanks for the parts that change, such as a repo or table name.