diff --git a/docs/cli/tutorials/mcp-setup.md b/docs/cli/tutorials/mcp-setup.md index 8723a65892..76c2806f9d 100644 --- a/docs/cli/tutorials/mcp-setup.md +++ b/docs/cli/tutorials/mcp-setup.md @@ -89,7 +89,7 @@ don't need to learn special commands; just ask in natural language. The agent will: 1. Recognize the request matches a GitHub tool. -2. Call `github_list_pull_requests`. +2. Call `mcp_github_list_pull_requests`. 3. Present the data to you. ### Scenario: Creating an issue diff --git a/docs/extensions/reference.md b/docs/extensions/reference.md index dbba51fa40..e6012f4d33 100644 --- a/docs/extensions/reference.md +++ b/docs/extensions/reference.md @@ -262,12 +262,14 @@ but lower priority than user or admin policies. ```toml [[rule]] -toolName = "my_server__dangerous_tool" +mcpName = "my_server" +toolName = "dangerous_tool" decision = "ask_user" priority = 100 [[safety_checker]] -toolName = "my_server__write_data" +mcpName = "my_server" +toolName = "write_data" priority = 200 [safety_checker.checker] type = "in-process" diff --git a/docs/hooks/reference.md b/docs/hooks/reference.md index a750bc94b3..5242c3a13d 100644 --- a/docs/hooks/reference.md +++ b/docs/hooks/reference.md @@ -85,7 +85,7 @@ compared against the name of the tool being executed. `run_shell_command`). See the [Tools Reference](../reference/tools) for a full list of available tool names. - **MCP Tools**: Tools from MCP servers follow the naming pattern - `mcp____`. + `mcp__`. - **Regex Support**: Matchers support regular expressions (e.g., `matcher: "read_.*"` matches all file reading tools). diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 4b50b99280..c93d0c2e66 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -1176,13 +1176,20 @@ their corresponding top-level category object in your `settings.json` file. Configures connections to one or more Model-Context Protocol (MCP) servers for discovering and using custom tools. Gemini CLI attempts to connect to each -configured MCP server to discover available tools. If multiple MCP servers -expose a tool with the same name, the tool names will be prefixed with the -server alias you defined in the configuration (e.g., -`serverAlias__actualToolName`) to avoid conflicts. Note that the system might -strip certain schema properties from MCP tool definitions for compatibility. At -least one of `command`, `url`, or `httpUrl` must be provided. If multiple are -specified, the order of precedence is `httpUrl`, then `url`, then `command`. +configured MCP server to discover available tools. Every discovered tool is +prepended with the `mcp_` prefix and its server alias to form a fully qualified +name (FQN) (e.g., `mcp_serverAlias_actualToolName`) to avoid conflicts. Note +that the system might strip certain schema properties from MCP tool definitions +for compatibility. At least one of `command`, `url`, or `httpUrl` must be +provided. If multiple are specified, the order of precedence is `httpUrl`, then +`url`, then `command`. + +> **Warning:** Avoid using underscores (`_`) in your server aliases (e.g., use +> `my-server` instead of `my_server`). The underlying policy engine parses Fully +> Qualified Names (`mcp_server_tool`) using the first underscore after the +> `mcp_` prefix. An underscore in your server alias will cause the parser to +> misidentify the server name, which can cause security policies to fail +> silently. - **`mcpServers.`** (object): The server parameters for the named server. diff --git a/docs/reference/policy-engine.md b/docs/reference/policy-engine.md index c0a331d99d..2ea23d4be4 100644 --- a/docs/reference/policy-engine.md +++ b/docs/reference/policy-engine.md @@ -76,9 +76,13 @@ The `toolName` in the rule must match the name of the tool being called. - **Wildcards**: You can use wildcards to match multiple tools. - `*`: Matches **any tool** (built-in or MCP). - - `server__*`: Matches any tool from a specific MCP server. - - `*__toolName`: Matches a specific tool name across **all** MCP servers. - - `*__*`: Matches **any tool from any MCP server**. + - `mcp_server_*`: Matches any tool from a specific MCP server. + - `mcp_*_toolName`: Matches a specific tool name across **all** MCP servers. + - `mcp_*`: Matches **any tool from any MCP server**. + +> **Recommendation:** While FQN wildcards are supported, the recommended +> approach for MCP tools is to use the `mcpName` field in your TOML rules. See +> [Special syntax for MCP tools](#special-syntax-for-mcp-tools). #### Arguments pattern @@ -164,8 +168,8 @@ A rule matches a tool call if all of its conditions are met: 1. **Tool name**: The `toolName` in the rule must match the name of the tool being called. - - **Wildcards**: You can use wildcards like `*`, `server__*`, or - `*__toolName` to match multiple tools. See [Tool Name](#tool-name) for + - **Wildcards**: You can use wildcards like `*`, `mcp_server_*`, or + `mcp_*_toolName` to match multiple tools. See [Tool Name](#tool-name) for details. 2. **Arguments pattern**: If `argsPattern` is specified, the tool's arguments are converted to a stable JSON string, which is then tested against the @@ -224,7 +228,7 @@ toolName = "run_shell_command" subagent = "generalist" # (Optional) The name of an MCP server. Can be combined with toolName -# to form a composite name like "mcpName__toolName". +# to form a composite FQN internally like "mcp_mcpName_toolName". mcpName = "my-custom-server" # (Optional) Metadata hints provided by the tool. A rule matches if all @@ -301,7 +305,16 @@ priority = 100 ### Special syntax for MCP tools You can create rules that target tools from Model Context Protocol (MCP) servers -using the `mcpName` field or composite wildcard patterns. +using the `mcpName` field. **This is the recommended approach** for defining MCP +policies, as it is much more robust than manually writing Fully Qualified Names +(FQNs) or string wildcards. + +> **Warning:** Do not use underscores (`_`) in your MCP server names (e.g., 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. **1. Targeting a specific tool on a server** diff --git a/docs/tools/mcp-server.md b/docs/tools/mcp-server.md index bbb5c62aba..6b8cd22ac0 100644 --- a/docs/tools/mcp-server.md +++ b/docs/tools/mcp-server.md @@ -555,21 +555,34 @@ Upon successful connection: `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 + - 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. Conflict resolution +### 3. Tool naming and namespaces -When multiple servers expose tools with the same name: +To prevent collisions across multiple servers or conflicting built-in tools, +every discovered MCP tool is assigned a strict namespace. -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 +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. + +> **Warning:** Do not use underscores (`_`) in your MCP server names (e.g., 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 @@ -695,7 +708,7 @@ MCP Servers Status: 🐳 dockerizedServer (CONNECTED) Command: docker run -i --rm -e API_KEY my-mcp-server:latest - Tools: docker__deploy, docker__status + Tools: mcp_dockerizedServer_docker_deploy, mcp_dockerizedServer_docker_status Discovery State: COMPLETED ``` diff --git a/packages/core/src/policy/toml-loader.ts b/packages/core/src/policy/toml-loader.ts index 83dda26e9e..f5c176dc25 100644 --- a/packages/core/src/policy/toml-loader.ts +++ b/packages/core/src/policy/toml-loader.ts @@ -457,6 +457,11 @@ export async function loadPoliciesFromToml( const mcpName = rule.mcpName; if (mcpName) { + // TODO(mcp): Decouple mcpName rules from FQN string parsing + // to support underscores in server aliases natively. Leaving + // mcpName and toolName separate here and relying on metadata + // during policy evaluation will avoid underscore splitting bugs. + // See: https://github.com/google-gemini/gemini-cli/issues/21727 effectiveToolName = formatMcpToolName( mcpName, effectiveToolName,