Skip to content

feat(cli): support Open Plugins MCP servers#23630

Open
NTaylorMullen wants to merge 8 commits intontm/gh.1592from
ntm/gh.1595
Open

feat(cli): support Open Plugins MCP servers#23630
NTaylorMullen wants to merge 8 commits intontm/gh.1592from
ntm/gh.1595

Conversation

@NTaylorMullen
Copy link
Copy Markdown
Collaborator

@NTaylorMullen NTaylorMullen commented Mar 24, 2026

Summary

Implement support for the Open Plugins MCP Servers specification in Gemini CLI. This allows Open Plugins (plugin.json) to define one or more MCP servers that are automatically discovered and configured when the plugin is loaded.

Details

  • Manifest Support: Implemented discovery of .mcp.json at the plugin root and support for mcpServers (as a path string, array of paths, or direct record) in plugin.json.
  • Variable Expansion: Added support for ${PLUGIN_ROOT} variable expansion in MCP server command, args, env, and cwd fields. This ensures bundled scripts or binaries within a plugin can be correctly referenced regardless of the installation path.
  • Namespacing: Aligned MCP server names with the pluginName:mcpServerName format to ensure proper tool namespacing (e.g., mcp_pluginName:mcpServerName_toolName).
  • Refactoring: Isolated the MCP server resolution logic into a dedicated method in plugin.ts for better maintainability.
  • Compatibility: Maintained compatibility with the Gemini API by ensuring tool names follow the standard mcp_ prefix format, avoiding "more than one colon" errors while still providing clear namespacing.
  • Rebased: Rebased on ntm/gh.1592 to include skill support for Open Plugins.

Related Issues

Fixes https://github.com/google-gemini/maintainers-gemini-cli/issues/1595

How to Validate

  1. Create an Open Plugin with a .mcp.json or mcpServers field in plugin.json.
  2. Reference a bundled script using ${PLUGIN_ROOT}.
  3. Run Gemini CLI and verify the tools are available via /mcp list.
  4. Invoke a tool and verify it executes correctly with the expanded paths.
  5. Automated tests cover:
    • packages/cli/src/config/open-plugin-mcp.test.ts: Discovery from .mcp.json and explicit paths.
    • packages/core/src/tools/mcp-plugin-expansion.test.ts: ${PLUGIN_ROOT} expansion logic.
    • packages/core/src/tools/mcp-plugin-namespacing.test.ts: pluginName:mcpServerName formatting.
    • packages/core/src/tools/mcp-plugin-naming.test.ts: API compatibility and tool name parsing.

Pre-Merge Checklist

  • Added/updated tests
  • Validated on MacOS

@NTaylorMullen NTaylorMullen requested review from a team as code owners March 24, 2026 03:27
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 24, 2026

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • ⚠️ Consider adding Evals: No behavioral evaluations (evals/*.eval.ts) were added or updated in this PR. Consider adding a test case to verify the new behavior and prevent regressions.
  • 🚀 Maintainer Reminder: Please ensure that these changes do not regress results on benchmark evals before merging.

This is an automated guidance message triggered by steering logic signatures.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Gemini CLI's extensibility by integrating support for Open Plugins to define and manage their own Model Context Protocol (MCP) servers. It introduces flexible configuration options for MCP servers within plugin manifests, enables dynamic path resolution for plugin-bundled executables, and establishes a clear namespacing convention to prevent conflicts. These changes allow Open Plugins to seamlessly provide custom tools and services to the CLI environment.

Highlights

  • Open Plugin MCP Server Support: Implemented comprehensive support for Open Plugins to define and discover MCP (Model Context Protocol) servers. This includes recognizing .mcp.json files at the plugin root and allowing mcpServers to be specified in plugin.json as a direct record, a path string, or an array of paths to external MCP configuration files.
  • Variable Expansion: Added support for ${PLUGIN_ROOT} variable expansion within MCP server configurations. This variable can now be used in the command, args, env, and cwd fields, ensuring that bundled scripts or binaries within a plugin are correctly referenced regardless of the plugin's installation location.
  • MCP Server Namespacing: Introduced a namespacing convention for Open Plugin MCP servers, formatting their names as pluginName:mcpServerName. This ensures proper identification and avoids conflicts, while maintaining compatibility with the existing mcp_ prefix for tool names.
  • Refactoring and Test Coverage: The logic for resolving MCP server configurations has been isolated into a dedicated method in plugin.ts for improved maintainability. Extensive test coverage has been added for MCP server discovery, variable expansion, and namespacing.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for Open Plugins MCP servers, including discovery of server configurations, variable expansion for plugin paths, and namespacing for tool names. The implementation is well-structured and includes relevant tests. However, I've identified a critical issue with unresolved merge conflict markers that must be fixed. Additionally, there's a potential bug in the tool name parsing logic when server names contain underscores, for which I've suggested an additional test case to ensure robustness.

Note: Security Review did not run due to the size of the PR.

Comment thread packages/cli/src/config/plugin.ts Outdated
Comment on lines +295 to +298
<<<<<<< HEAD
=======
// Features partially enabled for Open Plugins
>>>>>>> 559a26635 (feat(cli): support Open Plugins MCP servers)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file appears to contain unresolved merge conflict markers (<<<<<<<, =======, >>>>>>>). These must be resolved before the pull request can be merged.

expect(result.serverName).toBe('demo-plugin:demo-server');
expect(result.toolName).toBe('demo_tool');
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current test cases for parseMcpToolName don't cover scenarios where the server name part of a namespaced tool name contains an underscore. The underlying implementation in mcp-tool.ts appears to split on the first underscore, which will lead to incorrect parsing for names like mcp_my-plugin:my_server_my_tool.

Please add a test case to cover this scenario. This will likely require updating parseMcpToolName to correctly handle underscores in the server name part, for example by splitting on the last underscore.

Suggested test case to add:
it('should correctly parse namespaced MCP tool names with underscores in server name', () => {
const result = parseMcpToolName('mcp_my-plugin:my_server_my_tool');
expect(result.serverName).toBe('my-plugin:my_server');
expect(result.toolName).toBe('my_tool');
});

@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label Mar 24, 2026
- Updated skillLoader to support discovery in skills/ subdirectories
- Implemented convention-based skill discovery for Open Plugins
- Enforced namespacing for plugin skills (plugin:skill-name)
- Refactored skill resolution into resolvePluginSkills for better maintainability
- Added comprehensive tests for Open Plugin skill discovery

Fixes google-gemini/maintainers-gemini-cli#1592
- Implement discovery of .mcp.json at the plugin root
- Support explicit mcpServers path or record in plugin.json
- Add variable expansion for PLUGIN_ROOT in command, args, env, and cwd
- Align MCP server naming with the pluginName:mcpServerName format
- Ensure MCP tool names use standard mcp_ prefix for API compatibility
- Enable settings and mcpServers for Open Plugins
- Refactor MCP server resolution into dedicated method
- Improve type safety in tests and configuration loading

Fixes google-gemini/maintainers-gemini-cli#1595
- Remove stray conflict markers in plugin.ts
- Add missing MCPServerConfig import and type assertions in plugin.ts
- Fix missing sanitizationConfig property in mcp-plugin-expansion.test.ts

Part of google-gemini/maintainers-gemini-cli#1595

// 1. Explicit mcpServers in plugin.json
if (hydratedConfig.mcpServers) {
if (typeof hydratedConfig.mcpServers === 'string') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will zod handle this?

// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
return result.data.mcpServers as Record<string, MCPServerConfig>;
}
} catch (_e) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be swallowing this? Or only on ENOENT?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants