
How-Tos
How to add an MCP server in Gemini CLI
Add a local stdio or HTTP MCP server to Gemini CLI in settings.json, including headers, environment variables, and tool filters.
Searcher → Analyst → Writer → Editor · subagentic-20261025-2000
An MCP server is the bridge between Gemini CLI and a system the CLI does not ship with. It exposes tools and resources through the Model Context Protocol so the CLI can list those tools, call them with defined arguments, and read data the server exposes — files, API payloads, reports, and similar sources.
The documented way to add one is the mcpServers object in your settings.json file. A second, top-level mcp object sets global rules for every server. This guide uses only those documented fields: a local process over stdio, or a remote endpoint over SSE or streamable HTTP.
What the CLI expects
Gemini CLI supports three transports:
- Stdio spawns a subprocess and talks over stdin and stdout. Set
command. - SSE connects to a Server-Sent Events endpoint. Set
url. - Streamable HTTP uses HTTP streaming. Set
httpUrl.
Each server needs one of those. Optional fields include args, headers, env, cwd, timeout, trust, includeTools, and excludeTools. The request timeout defaults to 600,000 milliseconds (10 minutes). trust defaults to false, so tool calls still ask for confirmation.
mcp.allowed is a list of server names that may connect. If it is set, only names in that list — matching keys in mcpServers — are connected. mcp.excluded is a list of names that will not be connected.
Do not put underscores in server names. Every discovered tool gets a fully qualified name of the form mcp_{serverName}_{toolName}, and the policy parser splits on the first underscore after the mcp_ prefix. A name like my_server can make wildcard rules fail silently. The docs recommend a hyphenated name such as my-server.
Add a local stdio server
Set command to the executable, args to its arguments, and cwd to the working directory. env is the environment for that process only.
A documented Python server:
{
"mcpServers": {
"pythonTools": {
"command": "python",
"args": ["-m", "my_mcp_server", "--port", "8080"],
"cwd": "./mcp-servers/python",
"env": {
"DATABASE_URL": "$DB_CONNECTION_STRING",
"API_KEY": "${EXTERNAL_API_KEY}"
},
"timeout": 15000
}
}
}
The same guide also shows a Node stdio server. Copy the block as a whole; the executable, arguments, working directory, and trust flag belong together:
{
"mcpServers": {
"nodeServer": {
"command": "node",
"args": ["dist/server.js", "--verbose"],
"cwd": "./mcp-servers/node",
"trust": true
}
}
}
trust set to true skips tool-call confirmations for that server. Leave it false until you have seen the confirmation prompt.
Values in env expand $VARIABLE_NAME or ${VARIABLE_NAME} on every platform, and %VARIABLE_NAME% on Windows. A variable that is not defined expands to an empty string.
The CLI also redacts sensitive variables from the environment it inherits when it spawns a server. That includes core project keys such as GEMINI_API_KEY and GOOGLE_API_KEY, plus names matching *TOKEN*, *SECRET*, *PASSWORD*, *KEY*, *AUTH*, and *CREDENTIAL*, along with certificate and private-key patterns. A variable reaches the server only if you list it in that server's env block. Explicit entries are trusted and are not redacted. Prefer expansion over a hardcoded secret. The docs show that pattern for the official GitHub MCP server:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@github/github-mcp-server"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_PERSONAL_ACCESS_TOKEN"
}
}
}
}
Add an HTTP or SSE server
Use httpUrl for streamable HTTP and url for SSE. A headers object applies when either field is set.
A local HTTP server from the docs:
{
"mcpServers": {
"httpServer": {
"httpUrl": "http://localhost:3000/mcp",
"timeout": 5000
}
}
}
The same shape with custom headers:
{
"mcpServers": {
"httpServerWithAuth": {
"httpUrl": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-api-token",
"X-Custom-Header": "custom-value",
"Content-Type": "application/json"
},
"timeout": 5000
}
}
}
Remote servers on SSE or HTTP can use OAuth 2.0. If the server supports discovery, a url alone is enough: a 401 starts discovery, the CLI finds authorization and token endpoints, registers a client when the server supports that, and stores tokens in ~/.gemini/mcp-oauth-tokens.json. Inside a session, /mcp auth lists servers that need authentication. /mcp auth followed by the server name starts or repeats the flow. OAuth needs a local browser and a localhost redirect. It will not work headless, over SSH without X11 forwarding, or in a container without a browser.
Limit which tools the model sees
includeTools is an allowlist. If you set it, only those names from that server are available. excludeTools always wins: a name in both lists is excluded. If an extension also configures the same server, exclusions are combined and inclusions are intersected, so a local settings.json can veto a tool the extension would otherwise expose. Local env values override the extension when the same variable is set in both places. Scalar fields such as command, url, and timeout are replaced by your local values when you set them.
On startup the CLI walks mcpServers, picks a transport from httpUrl, then url, then command, and connects with the configured timeout. A failed connection is logged and the server is marked DISCONNECTED. Tool names are sanitized for the Gemini API: characters other than letters, numbers, underscore, hyphen, dot, and colon become underscores, and names longer than 63 characters are truncated with a middle replacement.
Confirm the server
In the CLI, run:
/mcp
That lists configured servers, a status of CONNECTED, CONNECTING, or DISCONNECTED, a configuration summary that omits sensitive data, and the tools from each server. Connected servers also show a Resources section. You can reference a resource with the same @ syntax used for local files:
@server://resource/path
On submit, the CLI reads that resource and injects the content.
If a server stays DISCONNECTED, check command, args, and cwd, run the server command yourself, confirm dependencies are installed, read the CLI error output, and verify the CLI can execute the command. A server that connects but lists no tools may not be registering tools, or its listing response may not match the protocol. If a tool is discovered and then fails, check that it accepts the expected parameters and that the input schema is valid JSON Schema; raising timeout is the documented response to timeouts. If servers fail while sandboxing is enabled, the docs recommend Docker-based servers that already include their dependencies.
Unless you set trust to true, the first call still asks you to proceed once, always allow that tool, always allow that server, or cancel.
What to do next
Paste one documented block — the Python stdio server or the HTTP server with headers — into mcpServers in your settings.json. Start Gemini CLI and run /mcp. Confirm CONNECTED and a tool list before you ask the model to call anything, and leave trust false until you have seen that confirmation prompt.