gemini-cli

MCP servers with the Gemini CLI

This document provides a guide to configuring and using Model Context Protocol (MCP) servers with the Gemini CLI.

What is an MCP server?

An MCP server is an application that exposes tools and resources to the Gemini CLI through the Model Context Protocol, allowing it to interact with external systems and data sources. MCP servers act as a bridge between the Gemini model and your local environment or other services like APIs.

An MCP server enables the Gemini CLI to:

With an MCP server, you can extend the Gemini CLI’s capabilities to perform actions beyond its built-in features, such as interacting with databases, APIs, custom scripts, or specialized workflows.

Core Integration Architecture

The Gemini CLI integrates with MCP servers through a sophisticated discovery and execution system built into the core package (packages/core/src/tools/):

Discovery Layer (mcp-client.ts)

The discovery process is orchestrated by discoverMcpTools(), which:

  1. Iterates through configured servers from your settings.json mcpServers configuration
  2. Establishes connections using appropriate transport mechanisms (Stdio, SSE, or Streamable HTTP)
  3. Fetches tool definitions from each server using the MCP protocol
  4. Sanitizes and validates tool schemas for compatibility with the Gemini API
  5. Registers tools in the global tool registry with conflict resolution

Execution Layer (mcp-tool.ts)

Each discovered MCP tool is wrapped in a DiscoveredMCPTool instance that:

Transport Mechanisms

The Gemini CLI supports three MCP transport types:

How to set up your MCP server

The Gemini CLI uses the mcpServers configuration in your settings.json file to locate and connect to MCP servers. This configuration supports multiple servers with different transport mechanisms.

Configure the MCP server in settings.json

You can configure MCP servers at the global level in the ~/.gemini/settings.json file or in your project’s root directory, create or open the .gemini/settings.json file. Within the file, add the mcpServers configuration block.

Configuration Structure

Add an mcpServers object to your settings.json file:

{ ...file contains other config objects
  "mcpServers": {
    "serverName": {
      "command": "path/to/server",
      "args": ["--arg1", "value1"],
      "env": {
        "API_KEY": "$MY_API_TOKEN"
      },
      "cwd": "./server-directory",
      "timeout": 30000,
      "trust": false
    }
  }
}

Configuration Properties

Each server configuration supports the following properties:

Required (one of the following)

Optional

OAuth Support for Remote MCP Servers

The Gemini CLI supports OAuth 2.0 authentication for remote MCP servers using SSE or HTTP transports. This enables secure access to MCP servers that require authentication.

Automatic OAuth Discovery

For servers that support OAuth discovery, you can omit the OAuth configuration and let the CLI discover it automatically:

{
  "mcpServers": {
    "discoveredServer": {
      "url": "https://api.example.com/sse"
    }
  }
}

The CLI will automatically:

Authentication Flow

When connecting to an OAuth-enabled server:

  1. Initial connection attempt fails with 401 Unauthorized
  2. OAuth discovery finds authorization and token endpoints
  3. Browser opens for user authentication (requires local browser access)
  4. Authorization code is exchanged for access tokens
  5. Tokens are stored securely for future use
  6. Connection retry succeeds with valid tokens

Browser Redirect Requirements

Important: OAuth authentication requires that your local machine can:

This feature will not work in:

Managing OAuth Authentication

Use the /mcp auth command to manage OAuth authentication:

# List servers requiring authentication
/mcp auth

# Authenticate with a specific server
/mcp auth serverName

# Re-authenticate if tokens expire
/mcp auth serverName

OAuth Configuration Properties

Token Management

OAuth tokens are automatically:

Authentication Provider Type

You can specify the authentication provider type using the authProviderType property:

{
  "mcpServers": {
    "googleCloudServer": {
      "httpUrl": "https://my-gcp-service.run.app/mcp",
      "authProviderType": "google_credentials",
      "oauth": {
        "scopes": ["https://www.googleapis.com/auth/userinfo.email"]
      }
    }
  }
}

Example Configurations

Python MCP Server (Stdio)

{
  "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
    }
  }
}

Node.js MCP Server (Stdio)

{
  "mcpServers": {
    "nodeServer": {
      "command": "node",
      "args": ["dist/server.js", "--verbose"],
      "cwd": "./mcp-servers/node",
      "trust": true
    }
  }
}

Docker-based MCP Server

{
  "mcpServers": {
    "dockerizedServer": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "API_KEY",
        "-v",
        "${PWD}:/workspace",
        "my-mcp-server:latest"
      ],
      "env": {
        "API_KEY": "$EXTERNAL_SERVICE_TOKEN"
      }
    }
  }
}

HTTP-based MCP Server

{
  "mcpServers": {
    "httpServer": {
      "httpUrl": "http://localhost:3000/mcp",
      "timeout": 5000
    }
  }
}

HTTP-based MCP Server 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
    }
  }
}

MCP Server with Tool Filtering

{
  "mcpServers": {
    "filteredServer": {
      "command": "python",
      "args": ["-m", "my_mcp_server"],
      "includeTools": ["safe_tool", "file_reader", "data_processor"],
      // "excludeTools": ["dangerous_tool", "file_deleter"],
      "timeout": 30000
    }
  }
}

Discovery Process Deep Dive

When the Gemini CLI starts, it performs MCP server discovery through the following detailed process:

1. Server Iteration and Connection

For each configured server in mcpServers:

  1. Status tracking begins: Server status is set to CONNECTING
  2. Transport selection: Based on configuration properties:
    • httpUrlStreamableHTTPClientTransport
    • urlSSEClientTransport
    • commandStdioClientTransport
  3. Connection establishment: The MCP client attempts to connect with the configured timeout
  4. Error handling: Connection failures are logged and the server status is set to DISCONNECTED

2. Tool Discovery

Upon successful connection:

  1. Tool listing: The client calls the MCP server’s tool listing endpoint
  2. Schema validation: Each tool’s function declaration is validated
  3. Tool filtering: Tools are filtered based on includeTools and excludeTools configuration
  4. Name sanitization: Tool names are cleaned to meet Gemini API requirements:
    • Invalid characters (non-alphanumeric, underscore, dot, hyphen) are replaced with underscores
    • Names longer than 63 characters are truncated with middle replacement (___)

3. Conflict Resolution

When multiple servers expose tools with the same name:

  1. First registration wins: The first server to register a tool name gets the unprefixed name
  2. Automatic prefixing: Subsequent servers get prefixed names: serverName__toolName
  3. Registry tracking: The tool registry maintains mappings between server names and their tools

4. Schema Processing

Tool parameter schemas undergo sanitization for Gemini API compatibility:

5. Connection Management

After discovery:

Tool Execution Flow

When the Gemini model decides to use an MCP tool, the following execution flow occurs:

1. Tool Invocation

The model generates a FunctionCall with:

2. Confirmation Process

Each DiscoveredMCPTool implements sophisticated confirmation logic:

Trust-based Bypass

if (this.trust) {
  return false; // No confirmation needed
}

Dynamic Allow-listing

The system maintains internal allow-lists for:

User Choice Handling

When confirmation is required, users can choose:

3. Execution

Upon confirmation (or trust bypass):

  1. Parameter preparation: Arguments are validated against the tool’s schema
  2. MCP call: The underlying CallableTool invokes the server with:

    const functionCalls = [
      {
        name: this.serverToolName, // Original server tool name
        args: params,
      },
    ];
    
  3. Response processing: Results are formatted for both LLM context and user display

4. Response Handling

The execution result contains:

How to interact with your MCP server

Using the /mcp Command

The /mcp command provides comprehensive information about your MCP server setup:

/mcp

This displays:

Example /mcp Output

MCP Servers Status:

📡 pythonTools (CONNECTED)
  Command: python -m my_mcp_server --port 8080
  Working Directory: ./mcp-servers/python
  Timeout: 15000ms
  Tools: calculate_sum, file_analyzer, data_processor

🔌 nodeServer (DISCONNECTED)
  Command: node dist/server.js --verbose
  Error: Connection refused

🐳 dockerizedServer (CONNECTED)
  Command: docker run -i --rm -e API_KEY my-mcp-server:latest
  Tools: docker__deploy, docker__status

Discovery State: COMPLETED

Tool Usage

Once discovered, MCP tools are available to the Gemini model like built-in tools. The model will automatically:

  1. Select appropriate tools based on your requests
  2. Present confirmation dialogs (unless the server is trusted)
  3. Execute tools with proper parameters
  4. Display results in a user-friendly format

Status Monitoring and Troubleshooting

Connection States

The MCP integration tracks several states:

Server Status (MCPServerStatus)

Discovery State (MCPDiscoveryState)

Common Issues and Solutions

Server Won’t Connect

Symptoms: Server shows DISCONNECTED status

Troubleshooting:

  1. Check configuration: Verify command, args, and cwd are correct
  2. Test manually: Run the server command directly to ensure it works
  3. Check dependencies: Ensure all required packages are installed
  4. Review logs: Look for error messages in the CLI output
  5. Verify permissions: Ensure the CLI can execute the server command

No Tools Discovered

Symptoms: Server connects but no tools are available

Troubleshooting:

  1. Verify tool registration: Ensure your server actually registers tools
  2. Check MCP protocol: Confirm your server implements the MCP tool listing correctly
  3. Review server logs: Check stderr output for server-side errors
  4. Test tool listing: Manually test your server’s tool discovery endpoint

Tools Not Executing

Symptoms: Tools are discovered but fail during execution

Troubleshooting:

  1. Parameter validation: Ensure your tool accepts the expected parameters
  2. Schema compatibility: Verify your input schemas are valid JSON Schema
  3. Error handling: Check if your tool is throwing unhandled exceptions
  4. Timeout issues: Consider increasing the timeout setting

Sandbox Compatibility

Symptoms: MCP servers fail when sandboxing is enabled

Solutions:

  1. Docker-based servers: Use Docker containers that include all dependencies
  2. Path accessibility: Ensure server executables are available in the sandbox
  3. Network access: Configure sandbox to allow necessary network connections
  4. Environment variables: Verify required environment variables are passed through

Debugging Tips

  1. Enable debug mode: Run the CLI with --debug for verbose output
  2. Check stderr: MCP server stderr is captured and logged (INFO messages filtered)
  3. Test isolation: Test your MCP server independently before integrating
  4. Incremental setup: Start with simple tools before adding complex functionality
  5. Use /mcp frequently: Monitor server status during development

Important Notes

Security Considerations

Performance and Resource Management

Schema Compatibility

This comprehensive integration makes MCP servers a powerful way to extend the Gemini CLI’s capabilities while maintaining security, reliability, and ease of use.

Returning Rich Content from Tools

MCP tools are not limited to returning simple text. You can return rich, multi-part content, including text, images, audio, and other binary data in a single tool response. This allows you to build powerful tools that can provide diverse information to the model in a single turn.

All data returned from the tool is processed and sent to the model as context for its next generation, enabling it to reason about or summarize the provided information.

How It Works

To return rich content, your tool’s response must adhere to the MCP specification for a CallToolResult. The content field of the result should be an array of ContentBlock objects. The Gemini CLI will correctly process this array, separating text from binary data and packaging it for the model.

You can mix and match different content block types in the content array. The supported block types include:

Example: Returning Text and an Image

Here is an example of a valid JSON response from an MCP tool that returns both a text description and an image:

{
  "content": [
    {
      "type": "text",
      "text": "Here is the logo you requested."
    },
    {
      "type": "image",
      "data": "BASE64_ENCODED_IMAGE_DATA_HERE",
      "mimeType": "image/png"
    },
    {
      "type": "text",
      "text": "The logo was created in 2025."
    }
  ]
}

When the Gemini CLI receives this response, it will:

  1. Extract all the text and combine it into a single functionResponse part for the model.
  2. Present the image data as a separate inlineData part.
  3. Provide a clean, user-friendly summary in the CLI, indicating that both text and an image were received.

This enables you to build sophisticated tools that can provide rich, multi-modal context to the Gemini model.

MCP Prompts as Slash Commands

In addition to tools, MCP servers can expose predefined prompts that can be executed as slash commands within the Gemini CLI. This allows you to create shortcuts for common or complex queries that can be easily invoked by name.

Defining Prompts on the Server

Here’s a small example of a stdio MCP server that defines prompts:

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({
  name: 'prompt-server',
  version: '1.0.0',
});

server.registerPrompt(
  'poem-writer',
  {
    title: 'Poem Writer',
    description: 'Write a nice haiku',
    argsSchema: { title: z.string(), mood: z.string().optional() },
  },
  ({ title, mood }) => ({
    messages: [
      {
        role: 'user',
        content: {
          type: 'text',
          text: `Write a haiku${mood ? ` with the mood ${mood}` : ''} called ${title}. Note that a haiku is 5 syllables followed by 7 syllables followed by 5 syllables `,
        },
      },
    ],
  }),
);

const transport = new StdioServerTransport();
await server.connect(transport);

This can be included in settings.json under mcpServers with:

"nodeServer": {
  "command": "node",
  "args": ["filename.ts"],
}

Invoking Prompts

Once a prompt is discovered, you can invoke it using its name as a slash command. The CLI will automatically handle parsing arguments.

/poem-writer --title="Gemini CLI" --mood="reverent"

or, using positional arguments:

/poem-writer "Gemini CLI" reverent

When you run this command, the Gemini CLI executes the prompts/get method on the MCP server with the provided arguments. The server is responsible for substituting the arguments into the prompt template and returning the final prompt text. The CLI then sends this prompt to the model for execution. This provides a convenient way to automate and share common workflows.

Managing MCP Servers with gemini mcp

While you can always configure MCP servers by manually editing your settings.json file, the Gemini CLI provides a convenient set of commands to manage your server configurations programmatically. These commands streamline the process of adding, listing, and removing MCP servers without needing to directly edit JSON files.

Adding a Server (gemini mcp add)

The add command configures a new MCP server in your settings.json. Based on the scope (-s, --scope), it will be added to either the user config ~/.gemini/settings.json or the project config .gemini/settings.json file.

Command:

gemini mcp add [options] <name> <commandOrUrl> [args...]

Options (Flags):

Adding an stdio server

This is the default transport for running local servers.

# Basic syntax
gemini mcp add <name> <command> [args...]

# Example: Adding a local server
gemini mcp add my-stdio-server -e API_KEY=123 /path/to/server arg1 arg2 arg3

# Example: Adding a local python server
gemini mcp add python-server python server.py --port 8080

Adding an HTTP server

This transport is for servers that use the streamable HTTP transport.

# Basic syntax
gemini mcp add --transport http <name> <url>

# Example: Adding an HTTP server
gemini mcp add --transport http http-server https://api.example.com/mcp/

# Example: Adding an HTTP server with an authentication header
gemini mcp add --transport http secure-http https://api.example.com/mcp/ --header "Authorization: Bearer abc123"

Adding an SSE server

This transport is for servers that use Server-Sent Events (SSE).

# Basic syntax
gemini mcp add --transport sse <name> <url>

# Example: Adding an SSE server
gemini mcp add --transport sse sse-server https://api.example.com/sse/

# Example: Adding an SSE server with an authentication header
gemini mcp add --transport sse secure-sse https://api.example.com/sse/ --header "Authorization: Bearer abc123"

Listing Servers (gemini mcp list)

To view all MCP servers currently configured, use the list command. It displays each server’s name, configuration details, and connection status.

Command:

gemini mcp list

Example Output:

✓ stdio-server: command: python3 server.py (stdio) - Connected
✓ http-server: https://api.example.com/mcp (http) - Connected
✗ sse-server: https://api.example.com/sse (sse) - Disconnected

Removing a Server (gemini mcp remove)

To delete a server from your configuration, use the remove command with the server’s name.

Command:

gemini mcp remove <name>

Example:

gemini mcp remove my-server

This will find and delete the “my-server” entry from the mcpServers object in the appropriate settings.json file based on the scope (-s, --scope).