This document provides a guide to configuring and using Model Context Protocol (MCP) servers with the Gemini CLI.
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.
The Gemini CLI integrates with MCP servers through a sophisticated discovery and execution system built into the core package (packages/core/src/tools/
):
mcp-client.ts
)The discovery process is orchestrated by discoverMcpTools()
, which:
settings.json
mcpServers
configurationmcp-tool.ts
)Each discovered MCP tool is wrapped in a DiscoveredMCPTool
instance that:
The Gemini CLI supports three MCP transport types:
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.
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.
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
}
}
}
Each server configuration supports the following properties:
command
(string): Path to the executable for Stdio transporturl
(string): SSE endpoint URL (e.g., "http://localhost:8080/sse"
)httpUrl
(string): HTTP streaming endpoint URLargs
(string[]): Command-line arguments for Stdio transportheaders
(object): Custom HTTP headers when using url
or httpUrl
env
(object): Environment variables for the server process. Values can reference environment variables using $VAR_NAME
or ${VAR_NAME}
syntaxcwd
(string): Working directory for Stdio transporttimeout
(number): Request timeout in milliseconds (default: 600,000ms = 10 minutes)trust
(boolean): When true
, bypasses all tool call confirmations for this server (default: false
)includeTools
(string[]): List of tool names to include from this MCP server. When specified, only the tools listed here will be available from this server (whitelist behavior). If not specified, all tools from the server are enabled by default.excludeTools
(string[]): List of tool names to exclude from this MCP server. Tools listed here will not be available to the model, even if they are exposed by the server. Note: excludeTools
takes precedence over includeTools
- if a tool is in both lists, it will be excluded.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.
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:
When connecting to an OAuth-enabled server:
Important: OAuth authentication requires that your local machine can:
http://localhost:7777/oauth/callback
This feature will not work in:
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
enabled
(boolean): Enable OAuth for this serverclientId
(string): OAuth client identifier (optional with dynamic registration)clientSecret
(string): OAuth client secret (optional for public clients)authorizationUrl
(string): OAuth authorization endpoint (auto-discovered if omitted)tokenUrl
(string): OAuth token endpoint (auto-discovered if omitted)scopes
(string[]): Required OAuth scopesredirectUri
(string): Custom redirect URI (defaults to http://localhost:7777/oauth/callback
)tokenParamName
(string): Query parameter name for tokens in SSE URLsaudiences
(string[]): Audiences the token is valid forOAuth tokens are automatically:
~/.gemini/mcp-oauth-tokens.json
You can specify the authentication provider type using the authProviderType
property:
authProviderType
(string): Specifies the authentication provider. Can be one of the following:
dynamic_discovery
(default): The CLI will automatically discover the OAuth configuration from the server.google_credentials
: The CLI will use the Google Application Default Credentials (ADC) to authenticate with the server. When using this provider, you must specify the required scopes.{
"mcpServers": {
"googleCloudServer": {
"httpUrl": "https://my-gcp-service.run.app/mcp",
"authProviderType": "google_credentials",
"oauth": {
"scopes": ["https://www.googleapis.com/auth/userinfo.email"]
}
}
}
}
{
"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
}
}
}
{
"mcpServers": {
"nodeServer": {
"command": "node",
"args": ["dist/server.js", "--verbose"],
"cwd": "./mcp-servers/node",
"trust": true
}
}
}
{
"mcpServers": {
"dockerizedServer": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"API_KEY",
"-v",
"${PWD}:/workspace",
"my-mcp-server:latest"
],
"env": {
"API_KEY": "$EXTERNAL_SERVICE_TOKEN"
}
}
}
}
{
"mcpServers": {
"httpServer": {
"httpUrl": "http://localhost:3000/mcp",
"timeout": 5000
}
}
}
{
"mcpServers": {
"httpServerWithAuth": {
"httpUrl": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-api-token",
"X-Custom-Header": "custom-value",
"Content-Type": "application/json"
},
"timeout": 5000
}
}
}
{
"mcpServers": {
"filteredServer": {
"command": "python",
"args": ["-m", "my_mcp_server"],
"includeTools": ["safe_tool", "file_reader", "data_processor"],
// "excludeTools": ["dangerous_tool", "file_deleter"],
"timeout": 30000
}
}
}
When the Gemini CLI starts, it performs MCP server discovery through the following detailed process:
For each configured server in mcpServers
:
CONNECTING
httpUrl
→ StreamableHTTPClientTransport
url
→ SSEClientTransport
command
→ StdioClientTransport
DISCONNECTED
Upon successful connection:
includeTools
and excludeTools
configuration___
)When multiple servers expose tools with the same name:
serverName__toolName
Tool parameter schemas undergo sanitization for Gemini API compatibility:
$schema
properties are removedadditionalProperties
are strippedanyOf
with default
have their default values removed (Vertex AI compatibility)After discovery:
CONNECTED
or DISCONNECTED
When the Gemini model decides to use an MCP tool, the following execution flow occurs:
The model generates a FunctionCall
with:
Each DiscoveredMCPTool
implements sophisticated confirmation logic:
if (this.trust) {
return false; // No confirmation needed
}
The system maintains internal allow-lists for:
serverName
→ All tools from this server are trustedserverName.toolName
→ This specific tool is trustedWhen confirmation is required, users can choose:
Upon confirmation (or trust bypass):
MCP call: The underlying CallableTool
invokes the server with:
const functionCalls = [
{
name: this.serverToolName, // Original server tool name
args: params,
},
];
The execution result contains:
llmContent
: Raw response parts for the language model’s contextreturnDisplay
: Formatted output for user display (often JSON in markdown code blocks)/mcp
CommandThe /mcp
command provides comprehensive information about your MCP server setup:
/mcp
This displays:
CONNECTED
, CONNECTING
, or DISCONNECTED
/mcp
OutputMCP 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
Once discovered, MCP tools are available to the Gemini model like built-in tools. The model will automatically:
The MCP integration tracks several states:
MCPServerStatus
)DISCONNECTED
: Server is not connected or has errorsCONNECTING
: Connection attempt in progressCONNECTED
: Server is connected and readyMCPDiscoveryState
)NOT_STARTED
: Discovery hasn’t begunIN_PROGRESS
: Currently discovering serversCOMPLETED
: Discovery finished (with or without errors)Symptoms: Server shows DISCONNECTED
status
Troubleshooting:
command
, args
, and cwd
are correctSymptoms: Server connects but no tools are available
Troubleshooting:
Symptoms: Tools are discovered but fail during execution
Troubleshooting:
timeout
settingSymptoms: MCP servers fail when sandboxing is enabled
Solutions:
--debug
for verbose output/mcp
frequently: Monitor server status during developmenttrust
option bypasses all confirmation dialogs. Use cautiously and only for servers you completely control$schema
, additionalProperties
) for Gemini API compatibilityThis comprehensive integration makes MCP servers a powerful way to extend the Gemini CLI’s capabilities while maintaining security, reliability, and ease of use.
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.
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:
text
image
audio
resource
(embedded content)resource_link
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:
functionResponse
part for the model.inlineData
part.This enables you to build sophisticated tools that can provide rich, multi-modal context to the Gemini model.
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.
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"],
}
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.
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.
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...]
<name>
: A unique name for the server.<commandOrUrl>
: The command to execute (for stdio
) or the URL (for http
/sse
).[args...]
: Optional arguments for a stdio
command.Options (Flags):
-s, --scope
: Configuration scope (user or project). [default: “project”]-t, --transport
: Transport type (stdio, sse, http). [default: “stdio”]-e, --env
: Set environment variables (e.g. -e KEY=value).-H, --header
: Set HTTP headers for SSE and HTTP transports (e.g. -H “X-Api-Key: abc123” -H “Authorization: Bearer abc123”).--timeout
: Set connection timeout in milliseconds.--trust
: Trust the server (bypass all tool call confirmation prompts).--description
: Set the description for the server.--include-tools
: A comma-separated list of tools to include.--exclude-tools
: A comma-separated list of tools to exclude.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
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"
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"
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
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
).