|
Download docs/tools/mcp-server.md from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 41.9 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/docs/tools/mcp-server.md
- Command line
-
hf download hf://SaylorTwift/gemini-cli/docs/tools/mcp-server.md
-
curl -L -o mcp-server.md https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/docs/tools/mcp-server.md
41.9 kB
| # MCP servers with Gemini CLI | |
| This document provides a guide to configuring and using Model Context Protocol | |
| (MCP) servers with 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 Gemini CLI to: | |
| - **Discover tools:** List available tools, their descriptions, and parameters | |
| through standardized schema definitions. | |
| - **Execute tools:** Call specific tools with defined arguments and receive | |
| structured responses. | |
| - **Access resources:** Read data from specific resources that the server | |
| exposes (files, API payloads, reports, etc.). | |
| With an MCP server, you can extend 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 | |
| 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 | |
| 6. **Fetches and registers resources** if the server exposes any | |
| ### Execution layer (`mcp-tool.ts`) | |
| Each discovered MCP tool is wrapped in a `DiscoveredMCPTool` instance that: | |
| - **Handles confirmation logic** based on server trust settings and user | |
| preferences | |
| - **Manages tool execution** by calling the MCP server with proper parameters | |
| - **Processes responses** for both the LLM context and user display | |
| - **Maintains connection state** and handles timeouts | |
| ### Transport mechanisms | |
| Gemini CLI supports three MCP transport types: | |
| - **Stdio Transport:** Spawns a subprocess and communicates via stdin/stdout | |
| - **SSE Transport:** Connects to Server-Sent Events endpoints | |
| - **Streamable HTTP Transport:** Uses HTTP streaming for communication | |
| ## Working with MCP resources | |
| Some MCP servers expose contextual “resources” in addition to the tools and | |
| prompts. Gemini CLI discovers these automatically and gives you the possibility | |
| to reference them in the chat. For more information on the tools used to | |
| interact with these resources, see [MCP resource tools](mcp-resources.md). | |
| ### Discovery and listing | |
| - When discovery runs, the CLI fetches each server’s `resources/list` results. | |
| - The `/mcp` command displays a Resources section alongside Tools and Prompts | |
| for every connected server. | |
| This returns a concise, plain-text list of URIs plus metadata. | |
| ### Referencing resources in a conversation | |
| You can use the same `@` syntax already known for referencing local files: | |
| ``` | |
| @server://resource/path | |
| ``` | |
| Resource URIs appear in the completion menu together with filesystem paths. When | |
| you submit the message, the CLI calls `resources/read` and injects the content | |
| in the conversation. | |
| ## How to set up your MCP server | |
| 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 in your `settings.json` file in two main ways: | |
| through the top-level `mcpServers` object for specific server definitions, and | |
| through the `mcp` object for global settings that control server discovery and | |
| execution. | |
| #### Global MCP settings (`mcp`) | |
| The `mcp` object in your `settings.json` lets you define global rules for all | |
| MCP servers. | |
| - **`mcp.serverCommand`** (string): A global command to start an MCP server. | |
| - **`mcp.allowed`** (array of strings): A list of MCP server names to allow. If | |
| this is set, only servers from this list (matching the keys in the | |
| `mcpServers` object) will be connected to. | |
| - **`mcp.excluded`** (array of strings): A list of MCP server names to exclude. | |
| Servers in this list will not be connected to. | |
| **Example:** | |
| ```json | |
| { | |
| "mcp": { | |
| "allowed": ["my-trusted-server"], | |
| "excluded": ["experimental-server"] | |
| } | |
| } | |
| ``` | |
| #### Server-specific configuration (`mcpServers`) | |
| The `mcpServers` object is where you define each individual MCP server you want | |
| the CLI to connect to. | |
| ### Configuration structure | |
| Add an `mcpServers` object to your `settings.json` file: | |
| ```json | |
| { ...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) | |
| - **`command`** (string): Path to the executable for Stdio transport | |
| - **`url`** (string): SSE endpoint URL (for example, | |
| `"http://localhost:8080/sse"`) | |
| - **`httpUrl`** (string): HTTP streaming endpoint URL | |
| #### Optional | |
| - **`args`** (string[]): Command-line arguments for Stdio transport | |
| - **`headers`** (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}` syntax (all | |
| platforms), or `%VAR_NAME%` (Windows only). | |
| - **`cwd`** (string): Working directory for Stdio transport | |
| - **`timeout`** (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 (allowlist 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. `excludeTools` takes precedence over `includeTools`. If | |
| a tool is in both lists, it will be excluded. | |
| - **`targetAudience`** (string): The OAuth Client ID allowlisted on the | |
| IAP-protected application you are trying to access. Used with | |
| `authProviderType: 'service_account_impersonation'`. | |
| - **`targetServiceAccount`** (string): The email address of the Google Cloud | |
| Service Account to impersonate. Used with | |
| `authProviderType: 'service_account_impersonation'`. | |
| ### Environment variable expansion | |
| Gemini CLI automatically expands environment variables in the `env` block of | |
| your MCP server configuration. This lets you securely reference variables | |
| defined in your shell or environment without hardcoding sensitive information | |
| directly in your `settings.json` file. | |
| The expansion utility supports: | |
| - **POSIX/Bash syntax:** `$VARIABLE_NAME` or `${VARIABLE_NAME}` (supported on | |
| all platforms) | |
| - **Windows syntax:** `%VARIABLE_NAME%` (supported only when running on Windows) | |
| If a variable is not defined in the current environment, it resolves to an empty | |
| string. | |
| **Example:** | |
| ```json | |
| "env": { | |
| "API_KEY": "$MY_EXTERNAL_TOKEN", | |
| "LOG_LEVEL": "$LOG_LEVEL", | |
| "TEMP_DIR": "%TEMP%" | |
| } | |
| ``` | |
| ### Security and environment sanitization | |
| To protect your credentials, Gemini CLI performs environment sanitization when | |
| spawning MCP server processes. | |
| #### Automatic redaction | |
| By default, the CLI redacts sensitive environment variables from the base | |
| environment (inherited from the host process). This prevents the accidental | |
| leakage of sensitive host environment variables (like AWS keys or GitHub tokens) | |
| to arbitrary third-party MCP servers that might execute malicious code or log | |
| your environment. This includes: | |
| - Core project keys: `GEMINI_API_KEY`, `GOOGLE_API_KEY`, etc. | |
| - Variables matching sensitive patterns: `*TOKEN*`, `*SECRET*`, `*PASSWORD*`, | |
| `*KEY*`, `*AUTH*`, `*CREDENTIAL*`. | |
| - Certificates and private key patterns. | |
| #### Explicit overrides | |
| If an environment variable must be passed to an MCP server, you must explicitly | |
| state it in the `env` property of the server configuration in `settings.json` | |
| (or `mcp_config.json` if configuring standard MCP clients or remote skills). | |
| Explicitly defined variables (including those from extensions) are trusted and | |
| are **not** subjected to the automatic redaction process. | |
| This follows the security principle that if a variable is explicitly configured | |
| by the user for a specific server, it constitutes informed consent to share that | |
| specific data with that server. | |
| <!-- prettier-ignore --> | |
| > [!NOTE] | |
| > Even when explicitly defined, you should avoid hardcoding secrets. | |
| > Instead, use environment variable expansion | |
| > (for example, `"MY_KEY": "$MY_KEY"`) to securely pull the value from your host | |
| > environment at runtime. | |
| **Example: Passing a GitHub Token securely to the | |
| [official GitHub MCP server](https://github.com/github/github-mcp-server) via | |
| `mcp_config.json`** | |
| ```json | |
| { | |
| "mcpServers": { | |
| "github": { | |
| "command": "npx", | |
| "args": ["-y", "@github/github-mcp-server"], | |
| "env": { | |
| "GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_PERSONAL_ACCESS_TOKEN" | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| ### OAuth support for remote MCP servers | |
| 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: | |
| ```json | |
| { | |
| "mcpServers": { | |
| "discoveredServer": { | |
| "url": "https://api.example.com/sse" | |
| } | |
| } | |
| } | |
| ``` | |
| The CLI will automatically: | |
| - Detect when a server requires OAuth authentication (401 responses) | |
| - Discover OAuth endpoints from server metadata | |
| - Perform dynamic client registration if supported | |
| - Handle the OAuth flow and token management | |
| #### 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 | |
| <!-- prettier-ignore --> | |
| > [!IMPORTANT] | |
| > OAuth authentication requires that your local machine can: | |
| > | |
| > - Open a web browser for authentication | |
| > - Receive redirects on `http://localhost:<random-port>/oauth/callback` (or a specific port if configured via `redirectUri`) | |
| This feature will not work in: | |
| - Headless environments without browser access | |
| - Remote SSH sessions without X11 forwarding | |
| - Containerized environments without browser support | |
| #### Authorization server requirements (RFC 9207) | |
| <!-- prettier-ignore --> | |
| > [!IMPORTANT] | |
| > To protect against OAuth Identity Provider (IdP) mix-up attacks, Gemini CLI | |
| > validates the `iss` (issuer) parameter per | |
| > [RFC 9207](https://www.rfc-editor.org/rfc/rfc9207). When an expected issuer is | |
| > discovered or configured, authorization servers **must** return the `iss` | |
| > parameter in the callback redirect matching the issuer URL. Responses missing | |
| > `iss` or with mismatched issuers are rejected with HTTP 400. | |
| ##### Expected authorization callback example | |
| When the authorization server redirects the user back to Gemini CLI, the | |
| redirect URI must include the `iss` parameter: | |
| ```http | |
| HTTP/1.1 302 Found | |
| Location: http://localhost:<port>/oauth/callback?code=AUTH_CODE&state=STATE&iss=https%3A%2F%2Fauth.example.com | |
| ``` | |
| - **Valid response (accepted):** `iss` matches the configured or discovered | |
| issuer (`https://auth.example.com`). | |
| - **Missing `iss` (rejected):** | |
| `http://localhost:<port>/oauth/callback?code=AUTH_CODE&state=STATE` (fails | |
| with HTTP 400: `Missing issuer parameter in response`). | |
| - **Mismatched `iss` (rejected):** `iss` points to a different domain or | |
| includes userinfo (fails with HTTP 400: `Issuer mismatch`). | |
| ##### Configuration example with explicit issuer | |
| If your remote MCP server uses an authorization server with a known issuer URL: | |
| ```json | |
| { | |
| "mcpServers": { | |
| "secureRemoteServer": { | |
| "url": "https://mcp.example.com/sse", | |
| "oauth": { | |
| "enabled": true, | |
| "issuer": "https://auth.example.com", | |
| "authorizationUrl": "https://auth.example.com/oauth/authorize", | |
| "tokenUrl": "https://auth.example.com/oauth/token", | |
| "clientId": "gemini-cli-client", | |
| "scopes": ["mcp:read", "mcp:write"] | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| #### Managing OAuth authentication | |
| Use the `/mcp auth` command to manage OAuth authentication: | |
| ```bash | |
| # 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 | |
| - **`enabled`** (boolean): Enable OAuth for this server | |
| - **`clientId`** (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) | |
| - **`issuer`** (string): Authorization server issuer URL (auto-discovered if | |
| omitted; validated per RFC 9207) | |
| - **`tokenUrl`** (string): OAuth token endpoint (auto-discovered if omitted) | |
| - **`scopes`** (string[]): Required OAuth scopes | |
| - **`redirectUri`** (string): Custom redirect URI (defaults to an OS-assigned | |
| random port, e.g., `http://localhost:<random-port>/oauth/callback`) | |
| - **`tokenParamName`** (string): Query parameter name for tokens in SSE URLs | |
| - **`audiences`** (string[]): Audiences the token is valid for | |
| #### Token management | |
| OAuth tokens are automatically: | |
| - **Stored securely** in `~/.gemini/mcp-oauth-tokens.json` | |
| - **Refreshed** when expired (if refresh tokens are available) | |
| - **Validated** before each connection attempt | |
| - **Cleaned up** when invalid or expired | |
| #### Authentication provider type | |
| 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. | |
| - **`service_account_impersonation`**: The CLI will impersonate a Google Cloud | |
| Service Account to authenticate with the server. This is useful for | |
| accessing IAP-protected services (this was specifically designed for Cloud | |
| Run services). | |
| #### Google credentials | |
| ```json | |
| { | |
| "mcpServers": { | |
| "googleCloudServer": { | |
| "httpUrl": "https://my-gcp-service.run.app/mcp", | |
| "authProviderType": "google_credentials", | |
| "oauth": { | |
| "scopes": ["https://www.googleapis.com/auth/userinfo.email"] | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| #### Service account impersonation | |
| To authenticate with a server using Service Account Impersonation, you must set | |
| the `authProviderType` to `service_account_impersonation` and provide the | |
| following properties: | |
| - **`targetAudience`** (string): The OAuth Client ID allowlisted on the | |
| IAP-protected application you are trying to access. | |
| - **`targetServiceAccount`** (string): The email address of the Google Cloud | |
| Service Account to impersonate. | |
| The CLI will use your local Application Default Credentials (ADC) to generate an | |
| OIDC ID token for the specified service account and audience. This token will | |
| then be used to authenticate with the MCP server. | |
| #### Setup instructions | |
| 1. **[Create](https://cloud.google.com/iap/docs/oauth-client-creation) or use an | |
| existing OAuth 2.0 client ID.** To use an existing OAuth 2.0 client ID, | |
| follow the steps in | |
| [How to share OAuth Clients](https://cloud.google.com/iap/docs/sharing-oauth-clients). | |
| 2. **Add the OAuth ID to the allowlist for | |
| [programmatic access](https://cloud.google.com/iap/docs/sharing-oauth-clients#programmatic_access) | |
| for the application.** Since Cloud Run is not yet a supported resource type | |
| in gcloud iap, you must allowlist the Client ID on the project. | |
| 3. **Create a service account.** | |
| [Documentation](https://cloud.google.com/iam/docs/service-accounts-create#creating), | |
| [Cloud Console Link](https://console.cloud.google.com/iam-admin/serviceaccounts) | |
| 4. **Add both the service account and users to the IAP Policy** in the | |
| "Security" tab of the Cloud Run service itself or via gcloud. | |
| 5. **Grant all users and groups** who will access the MCP Server the necessary | |
| permissions to | |
| [impersonate the service account](https://cloud.google.com/docs/authentication/use-service-account-impersonation) | |
| (for example, `roles/iam.serviceAccountTokenCreator`). | |
| 6. **[Enable](https://console.cloud.google.com/apis/library/iamcredentials.googleapis.com) | |
| the IAM Credentials API** for your project. | |
| ### Example configurations | |
| #### Python MCP server (stdio) | |
| ```json | |
| { | |
| "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) | |
| ```json | |
| { | |
| "mcpServers": { | |
| "nodeServer": { | |
| "command": "node", | |
| "args": ["dist/server.js", "--verbose"], | |
| "cwd": "./mcp-servers/node", | |
| "trust": true | |
| } | |
| } | |
| } | |
| ``` | |
| #### Docker-based MCP server | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "mcpServers": { | |
| "httpServer": { | |
| "httpUrl": "http://localhost:3000/mcp", | |
| "timeout": 5000 | |
| } | |
| } | |
| } | |
| ``` | |
| #### HTTP-based MCP Server with custom headers | |
| ```json | |
| { | |
| "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 | |
| ```json | |
| { | |
| "mcpServers": { | |
| "filteredServer": { | |
| "command": "python", | |
| "args": ["-m", "my_mcp_server"], | |
| "includeTools": ["safe_tool", "file_reader", "data_processor"], | |
| // "excludeTools": ["dangerous_tool", "file_deleter"], | |
| "timeout": 30000 | |
| } | |
| } | |
| } | |
| ``` | |
| ### SSE MCP server with SA impersonation | |
| ```json | |
| { | |
| "mcpServers": { | |
| "myIapProtectedServer": { | |
| "url": "https://my-iap-service.run.app/sse", | |
| "authProviderType": "service_account_impersonation", | |
| "targetAudience": "YOUR_IAP_CLIENT_ID.apps.googleusercontent.com", | |
| "targetServiceAccount": "your-sa@your-project.iam.gserviceaccount.com" | |
| } | |
| } | |
| } | |
| ``` | |
| ## Discovery process deep dive | |
| When 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: | |
| - `httpUrl` → `StreamableHTTPClientTransport` | |
| - `url` → `SSEClientTransport` | |
| - `command` → `StdioClientTransport` | |
| 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: | |
| - Characters other than letters, numbers, underscore (`_`), hyphen (`-`), dot | |
| (`.`), and colon (`:`) are replaced with underscores | |
| - Names longer than 63 characters are truncated with middle replacement | |
| (`...`) | |
| ### 3. Tool naming and namespaces | |
| To prevent collisions across multiple servers or conflicting built-in tools, | |
| every discovered MCP tool is assigned a strict namespace. | |
| 1. **Automatic FQN:** All MCP tools are unconditionally assigned a fully | |
| qualified name (FQN) using the format `mcp_{serverName}_{toolName}`. | |
| 2. **Registry tracking:** The tool registry maintains metadata mappings between | |
| these FQNs and their original server identities. | |
| 3. **Overwrites:** If two servers share the exact same alias in your | |
| configuration and provide tools with the exact same name, the last registered | |
| tool overwrites the previous one. | |
| 4. **Policies:** To configure permissions (like auto-approval or denial) for MCP | |
| tools, see | |
| [Special syntax for MCP tools](../reference/policy-engine.md#special-syntax-for-mcp-tools) | |
| in the Policy Engine documentation. | |
| <!-- prettier-ignore --> | |
| > [!WARNING] | |
| > Do not use underscores (`_`) in your MCP server names (for example, use | |
| > `my-server` rather than `my_server`). The policy parser splits Fully Qualified | |
| > Names (`mcp_server_tool`) on the _first_ underscore following the `mcp_` | |
| > prefix. If your server name contains an underscore, the parser will | |
| > misinterpret the server identity, which can cause wildcard rules and security | |
| > policies to fail silently. | |
| ### 4. Schema processing | |
| Tool parameter schemas undergo sanitization for Gemini API compatibility: | |
| - **`$schema` properties** are removed | |
| - **`additionalProperties`** are stripped | |
| - **`anyOf` with `default`** have their default values removed (Vertex AI | |
| compatibility) | |
| - **Recursive processing** applies to nested schemas | |
| ### 5. Connection management | |
| After discovery: | |
| - **Persistent connections:** Servers that successfully register tools maintain | |
| their connections | |
| - **Cleanup:** Servers that provide no usable tools have their connections | |
| closed | |
| - **Status updates:** Final server statuses are set to `CONNECTED` or | |
| `DISCONNECTED` | |
| ## 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: | |
| - **Tool name:** The registered name (potentially prefixed) | |
| - **Arguments:** JSON object matching the tool's parameter schema | |
| ### 2. Confirmation process | |
| Each `DiscoveredMCPTool` implements sophisticated confirmation logic: | |
| #### Trust-based bypass | |
| ```typescript | |
| if (this.trust) { | |
| return false; // No confirmation needed | |
| } | |
| ``` | |
| #### Dynamic allow-listing | |
| The system maintains internal allow-lists for: | |
| - **Server-level:** `serverName` → All tools from this server are trusted | |
| - **Tool-level:** `serverName.toolName` → This specific tool is trusted | |
| #### User choice handling | |
| When confirmation is required, users can choose: | |
| - **Proceed once:** Execute this time only | |
| - **Always allow this tool:** Add to tool-level allow-list | |
| - **Always allow this server:** Add to server-level allow-list | |
| - **Cancel:** Abort execution | |
| ### 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: | |
| ```typescript | |
| 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: | |
| - **`llmContent`:** Raw response parts for the language model's context | |
| - **`returnDisplay`:** Formatted output for user display (often JSON in markdown | |
| code blocks) | |
| ## How to interact with your MCP server | |
| ### Using the `/mcp` command | |
| The `/mcp` command provides comprehensive information about your MCP server | |
| setup: | |
| ```bash | |
| /mcp | |
| ``` | |
| This displays: | |
| - **Server list:** All configured MCP servers | |
| - **Connection status:** `CONNECTED`, `CONNECTING`, or `DISCONNECTED` | |
| - **Server details:** Configuration summary (excluding sensitive data) | |
| - **Available tools:** List of tools from each server with descriptions | |
| - **Discovery state:** Overall discovery process status | |
| ### 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: mcp_dockerizedServer_docker_deploy, mcp_dockerizedServer_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: | |
| #### Overriding extension configurations | |
| If an MCP server is provided by an extension (for example, the | |
| `google-workspace` extension), you can still override its settings in your local | |
| `settings.json`. Gemini CLI merges your local configuration with the extension's | |
| defaults: | |
| - **Tool lists:** Tool lists are merged securely to ensure the most restrictive | |
| policy wins: | |
| - **Exclusions (`excludeTools`):** Arrays are combined (unioned). If either | |
| source blocks a tool, it remains disabled. | |
| - **Inclusions (`includeTools`):** Arrays are intersected. If both sources | |
| provide an allowlist, only tools present in **both** lists are enabled. If | |
| only one source provides an allowlist, that list is respected. | |
| - **Precedence:** `excludeTools` always takes precedence over `includeTools`. | |
| This ensures you always have veto power over tools provided by an extension | |
| and that an extension cannot re-enable tools you have omitted from your | |
| personal allowlist. | |
| - **Environment variables:** The `env` objects are merged. If the same variable | |
| is defined in both places, your local value takes precedence. | |
| - **Scalar properties:** Properties like `command`, `url`, and `timeout` are | |
| replaced by your local values if provided. | |
| **Example override:** | |
| ```json | |
| { | |
| "mcpServers": { | |
| "google-workspace": { | |
| "excludeTools": ["gmail.send"] | |
| } | |
| } | |
| } | |
| ``` | |
| #### Server status (`MCPServerStatus`) | |
| - **`DISCONNECTED`:** Server is not connected or has errors | |
| - **`CONNECTING`:** Connection attempt in progress | |
| - **`CONNECTED`:** Server is connected and ready | |
| #### Discovery state (`MCPDiscoveryState`) | |
| - **`NOT_STARTED`:** Discovery hasn't begun | |
| - **`IN_PROGRESS`:** Currently discovering servers | |
| - **`COMPLETED`:** Discovery finished (with or without errors) | |
| ### 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 (use F12 | |
| to open debug console in interactive mode) | |
| 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 | |
| - **Trust settings:** The `trust` option bypasses all confirmation dialogs. Use | |
| cautiously and only for servers you completely control | |
| - **Access tokens:** Be security-aware when configuring environment variables | |
| containing API keys or tokens. See | |
| [Security and environment sanitization](#security-and-environment-sanitization) | |
| for details on how Gemini CLI protects your credentials. | |
| - **Sandbox compatibility:** When using sandboxing, ensure MCP servers are | |
| available within the sandbox environment | |
| - **Private data:** Using broadly scoped personal access tokens can lead to | |
| information leakage between repositories. | |
| ### Performance and resource management | |
| - **Connection persistence:** The CLI maintains persistent connections to | |
| servers that successfully register tools | |
| - **Automatic cleanup:** Connections to servers providing no tools are | |
| automatically closed | |
| - **Timeout management:** Configure appropriate timeouts based on your server's | |
| response characteristics | |
| - **Resource monitoring:** MCP servers run as separate processes and consume | |
| system resources | |
| ### Schema compatibility | |
| - **Property stripping:** The system automatically removes certain schema | |
| properties (`$schema`, `additionalProperties`) for Gemini API compatibility | |
| - **Name sanitization:** Tool names are automatically sanitized to meet API | |
| requirements | |
| - **Conflict resolution:** Tool name conflicts between servers are resolved | |
| through automatic prefixing | |
| 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 lets you 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`](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result). | |
| The `content` field of the result should be an array of `ContentBlock` objects. | |
| 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` | |
| ### 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: | |
| ```json | |
| { | |
| "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 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 Gemini CLI. This lets you 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: | |
| ```ts | |
| 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: | |
| ```json | |
| { | |
| "mcpServers": { | |
| "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. | |
| ```bash | |
| /poem-writer --title="Gemini CLI" --mood="reverent" | |
| ``` | |
| or, using positional arguments: | |
| ```bash | |
| /poem-writer "Gemini CLI" reverent | |
| ``` | |
| When you run this command, 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, 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:** | |
| ```bash | |
| 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 (for example, `-e KEY=value`). | |
| - `-H, --header`: Set HTTP headers for SSE and HTTP transports (for example, | |
| `-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. | |
| #### Adding an stdio server | |
| This is the default transport for running local servers. | |
| ```bash | |
| # Basic syntax | |
| gemini mcp add [options] <name> <command> [args...] | |
| # Example: Adding a local server | |
| gemini mcp add -e API_KEY=123 -e DEBUG=true my-stdio-server /path/to/server arg1 arg2 arg3 | |
| # Example: Adding a local python server | |
| gemini mcp add python-server python server.py -- --server-arg my-value | |
| ``` | |
| #### Adding an HTTP server | |
| This transport is for servers that use the streamable HTTP transport. | |
| ```bash | |
| # 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 --header "Authorization: Bearer abc123" secure-http https://api.example.com/mcp/ | |
| ``` | |
| #### Adding an SSE server | |
| This transport is for servers that use Server-Sent Events (SSE). | |
| ```bash | |
| # 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 --header "Authorization: Bearer abc123" secure-sse https://api.example.com/sse/ | |
| ``` | |
| ### 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. This | |
| command has no flags. | |
| **Command:** | |
| ```bash | |
| gemini mcp list | |
| ``` | |
| <!-- prettier-ignore --> | |
| > [!NOTE] | |
| > For security, `stdio` MCP servers (those using the | |
| > `command` property) are only tested and displayed as "Connected" if the | |
| > current folder is trusted. If the folder is untrusted, they will show as | |
| > "Disconnected". Use `gemini trust` to trust the current folder. | |
| **Example output:** | |
| ```sh | |
| ✓ 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 | |
| ``` | |
| ## Troubleshooting and Diagnostics | |
| To minimize noise during startup, MCP connection errors for background servers | |
| are "silent by default." If issues are detected during startup, a single | |
| informational hint will be shown: _"MCP issues detected. Run /mcp list for | |
| status."_ | |
| Detailed, actionable diagnostics for a specific server are automatically | |
| re-enabled when: | |
| 1. You run an interactive command like `/mcp list`, `/mcp auth`, etc. | |
| 2. The model attempts to execute a tool from that server. | |
| 3. You invoke an MCP prompt from that server. | |
| You can also use `gemini mcp list` from your shell to see connection errors for | |
| all configured servers. | |
| ### Removing a server (`gemini mcp remove`) | |
| To delete a server from your configuration, use the `remove` command with the | |
| server's name. | |
| **Command:** | |
| ```bash | |
| gemini mcp remove <name> | |
| ``` | |
| **Options (flags):** | |
| - `-s, --scope`: Configuration scope (user or project). [default: "project"] | |
| **Example:** | |
| ```bash | |
| 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`). | |
| ### Enabling/disabling a server (`gemini mcp enable`, `gemini mcp disable`) | |
| Temporarily disable an MCP server without removing its configuration, or | |
| re-enable a previously disabled server. | |
| **Commands:** | |
| ```bash | |
| gemini mcp enable <name> [--session] | |
| gemini mcp disable <name> [--session] | |
| ``` | |
| **Options (flags):** | |
| - `--session`: Apply change only for this session (not persisted to file). | |
| Disabled servers appear in `/mcp` status as "Disabled" but won't connect or | |
| provide tools. Enablement state is stored in | |
| `~/.gemini/mcp-server-enablement.json`. | |
| The same commands are available as slash commands during an active session: | |
| `/mcp enable <name>` and `/mcp disable <name>`. | |
| ## Instructions | |
| Gemini CLI supports | |
| [MCP server instructions](https://modelcontextprotocol.io/specification/2025-06-18/schema#initializeresult), | |
| which will be appended to the system instructions. | |