New PolicyLayer is now the system of record for AI agent authority. Never answer your agent twice
Home / Integrations / Gemini CLI

Gemini CLI MCP setup: the complete config reference

Where Gemini CLI’s MCP config lives, the mcpServers format and its url vs httpUrl distinction, and how to fix the common failures — plus how to put a policy gate in front of every tool call.

QUICK ANSWERQuick answer: user config in ~/.gemini/settings.json, project config in .gemini/settings.json. Top-level key is mcpServers.

Where Gemini CLI keeps its MCP config.

ScopePathNotes
User ~/.gemini/settings.json Available in every project.
Project .gemini/settings.json At the project root; takes precedence over user settings.
System /etc/gemini-cli/settings.json Admin-managed overrides (macOS: /Library/Application Support/GeminiCli/settings.json; Windows: C:\ProgramData\gemini-cli\settings.json). Beats user and project settings.

The config format, key by key.

A top-level mcpServers object, one entry per server. The transport is chosen by which key is present: command for stdio, url for SSE, httpUrl for streamable HTTP.

KeyWhat it does
command Executable for a stdio server.
args Array of arguments passed to the command.
env Environment variables; $VAR and ${VAR} expand from your shell.
cwd Working directory for a stdio server.
httpUrl Endpoint for a streamable HTTP server.
url Endpoint for an SSE server — not interchangeable with httpUrl.
headers HTTP headers for remote servers — where auth tokens go.
timeout Request timeout in ms (default 600,000).
trust true skips the per-call confirmation prompt for this server.
includeTools / excludeTools Allowlist / blocklist of tool names (exclude wins).
~/.gemini/settings.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_TOKEN"
      },
      "timeout": 15000
    }
  }
}

REMOTE SERVER (HTTP):

~/.gemini/settings.json
{
  "mcpServers": {
    "my-http-server": {
      "httpUrl": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

What Gemini CLI speaks.

TransportStatusHow to declare it
stdio Supported Declare command + args.
Streamable HTTP Supported Declare httpUrl.
SSE Supported Declare url. Using the wrong key for the server’s actual transport fails to connect.

Adding a server, three ways.

01 CLI — gemini mcp add

Flags: -s user|project picks the scope, -t stdio|sse|http the transport, -e KEY=value env vars, -H "Name: value" headers.

TERMINAL
# Local stdio server
gemini mcp add -s user github npx -- -y @modelcontextprotocol/server-github

# Remote streamable HTTP server
gemini mcp add -s user -t http my-server https://example.com/mcp \
  -H "Authorization: Bearer <token>"
02 Edit settings.json

Add entries under mcpServers in the user or project file. Manage with gemini mcp list, gemini mcp remove, and gemini mcp enable/disable.

03 Extensions

Gemini CLI extensions can bundle MCP servers and merge them with your local config — install once, get the servers with it.

Check it's actually connected.

  1. Run /mcp inside Gemini CLI — it lists each server with connection status, discovery state and discovered tools.
  2. Watch for the startup warning MCP issues detected; it points you to /mcp list.
  3. Tools get fully qualified names of the form mcp_<server>_<tool> — ask Gemini to call one to confirm the round trip.

When it doesn't work.

Remote server never connects

Check the key: httpUrl is for streamable HTTP, url is for SSE. Pointing the wrong key at the endpoint fails silently — most modern servers want httpUrl.

Env var not expanding in the config

Only $VAR, ${VAR} (and %VAR% on Windows) expand, and the variable must exist in the shell that launched the CLI.

Long tool calls aborting

The default timeout is 600,000 ms but server entries that set it lower will cut long calls short — raise it on the server entry.

Too many tools, or name collisions between servers

Scope each server with includeTools / excludeTools (exclude wins). Tools are namespaced as mcp_<server>_<tool> — and avoid underscores in server names, since the parser splits the name on underscores.

Settings edits not taking effect

Check precedence — system settings override user and project files. /settings inside the CLI shows what actually resolved.

Put a policy gate in front of it.

A standard GitHub MCP wired into Gemini CLI. Every call hits GitHub directly with no policy gate.

~/.gemini/settings.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
      }
    }
  }
}

Register GitHub in PolicyLayer, mint a grant, point Gemini CLI at the proxy URL via httpUrl. PolicyLayer evaluates every call against the grant’s policy before it reaches GitHub.

~/.gemini/settings.json
{
  "mcpServers": {
    "github": {
      "httpUrl": "https://proxy.policylayer.com/mcp/<server-uuid>/",
      "headers": {
        "Authorization": "Bearer <grant-token>"
      }
    }
  }
}

The <server-uuid> appears on each server's detail page. The <grant-token> shows once at mint time. See the Quick start for the full setup walk-through — and if you operate under SOC 2, HIPAA, GDPR or similar, the compliance hub maps how gateway-mediated MCP traffic evidences each framework.

What the gateway adds.

Rate limits
Cap tool calls per minute, hour, or day, per grant or shared across the team.
Access controls
Allow, deny, or conditionally gate any tool against the call's arguments.
Spend caps
Increment a counter by the call's amount; deny when the daily total exceeds your budget.
Audit logs
Every call records the grant, tool, argument keys, and the rule that decided.

A policy in practice.

Allow listing and issue creation. Deny merges into main. Deny everything else by default.

policy.json
{
  "version": "1",
  "default": "deny",
  "tools": {
    "list_repositories": {},
    "create_issue": {},
    "merge_pull_request": {
      "deny_if": [
        {
          "conditions": [
            { "path": "args.base", "op": "eq", "value": "main" }
          ]
        }
      ]
    }
  }
}

See Writing policies for the policy format, operators, and quota shapes.

Gemini CLI MCP questions.

Where is the Gemini CLI MCP config?+

Under the mcpServers key in ~/.gemini/settings.json (user scope) or .gemini/settings.json at the project root. System-level settings files can override both — /settings inside the CLI shows what resolved.

What is the difference between url and httpUrl in Gemini CLI?+

httpUrl declares a streamable HTTP server; url declares an SSE server. They are not interchangeable — using url against a streamable HTTP endpoint fails to connect. Most current servers want httpUrl.

How do I check MCP server status in Gemini CLI?+

Type /mcp inside the CLI. It shows every server’s connection status, discovery state and tool list. Tools get fully qualified names of the form mcp_<server>_<tool>.

What does the trust setting do in Gemini CLI?+

trust: true skips the per-call confirmation dialogue for that server. Convenient for vetted servers, but it removes the only human check — pair it with server-side policy if the tools can write or spend.

Can I restrict which tools a Gemini CLI MCP server exposes?+

Yes — includeTools allowlists and excludeTools blocklists tool names per server, with exclude taking precedence. For argument-level conditions, rate limits and audit logs, add a policy gateway like PolicyLayer in front.

Take your agents live. Without losing control.

Route your MCP traffic through PolicyLayer. Every tool call is checked against your policy before it runs: allow, deny, or require approval. Per-identity grants. Full audit log. Live in minutes.

Instant setup, no code required.

46,500+ MCP servers and 515,000+ tools scanned and risk-classified.

// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.