Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Aug 29, 2025

This PR adds support for defining and initializing MCP (Model Context Protocol) servers programmatically through the IPC socket API, addressing the issue where MCP servers could only be configured through file-based configuration.

Problem

Previously, MCP servers could only be defined through:

  • Global settings file (cline_mcp_settings.json)
  • Project-level configuration (.roo/mcp.json)

This limitation prevented headless VSCode environments from using MCP servers when configuration was passed programmatically through the IPC API.

Solution

This PR introduces support for "runtime" MCP servers that can be:

  • Defined programmatically via the IPC API configuration
  • Initialized dynamically without requiring file-based configuration
  • Managed alongside file-based servers with proper prioritization

Changes

  • McpHub.ts: Added initializeRuntimeMcpServers() method to handle programmatically defined servers
  • api.ts: Modified startNewTask() to detect and initialize MCP servers from configuration
  • mcp.ts: Added "runtime" as a new server source type
  • global-settings.ts: Added mcpServers as an optional property in GlobalSettings schema
  • Tests: Added comprehensive test coverage for the new functionality

Testing

  • ✅ All existing tests pass
  • ✅ New tests added for runtime MCP server initialization
  • ✅ TypeScript type checking passes
  • ✅ Linting passes

Usage Example

// Via IPC API
await api.startNewTask({
  configuration: {
    apiProvider: "openai",
    mcpServers: {
      "my-server": {
        type: "stdio",
        command: "node",
        args: ["server.js"],
        env: { NODE_ENV: "production" }
      }
    }
  },
  text: "Task description"
})

Fixes #7518


Important

Adds runtime MCP server support via IPC API, enabling dynamic server configuration without file-based settings.

  • Behavior:
    • Adds support for runtime MCP servers via IPC API, allowing dynamic configuration without file-based settings.
    • Prioritizes runtime servers over project and global servers.
  • Implementation:
    • McpHub.ts: Introduces initializeRuntimeMcpServers() for handling runtime servers.
    • api.ts: Updates startNewTask() to initialize runtime MCP servers from configuration.
    • global-settings.ts: Adds mcpServers to GlobalSettings schema.
  • Testing:
    • api.spec.ts: Adds tests for runtime MCP server initialization, including cases with complex configurations and empty server objects.
  • Misc:
    • Updates McpServer type in mcp.ts to include "runtime" as a source.

This description was created by Ellipsis for 18305a9. You can customize this summary. It will automatically update as commits are pushed.

- Add initializeRuntimeMcpServers method to McpHub for programmatic server initialization
- Update API.startNewTask to detect and initialize MCP servers from configuration
- Add "runtime" as a new server source type alongside "global" and "project"
- Update type definitions to include mcpServers in GlobalSettings
- Add comprehensive tests for the new functionality

This allows MCP servers to be defined and initialized through the IPC socket API
configuration rather than only through file-based configuration, enabling headless
VSCode environments to use MCP servers programmatically.

Fixes #7518
- Update method signatures to accept "runtime" as valid source parameter
- Fix createPlaceholderConnection to handle runtime source
- Update findConnection and fetch methods to support runtime servers
@roomote roomote bot requested review from cte, jr and mrubens as code owners August 29, 2025 10:15
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Aug 29, 2025

// Initialize runtime servers with "runtime" source
try {
await this.updateServerConnections(this.runtimeServers, "runtime" as any, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

The initializeRuntimeMcpServers method correctly stores runtime configurations and calls updateServerConnections. Consider avoiding the 'as any' cast for the source parameter when calling updateServerConnections; using the proper union type ('runtime') can preserve type safety.

Suggested change
await this.updateServerConnections(this.runtimeServers, "runtime" as any, false)
await this.updateServerConnections(this.runtimeServers, "runtime", false)

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 29, 2025
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

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

Reviewing my own code because apparently I trust no one, not even myself.

isConnecting: boolean = false
private refCount: number = 0 // Reference counter for active clients
private configChangeDebounceTimers: Map<string, NodeJS.Timeout> = new Map()
private runtimeServers: Record<string, any> = {} // Store runtime MCP servers
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The runtimeServers property stores runtime servers indefinitely in memory. Could we consider clearing this when all runtime servers are disconnected to prevent potential memory leaks in long-running sessions? Maybe add a cleanup method or clear it when the last runtime server disconnects?

const mcpHub = provider.getMcpHub()
if (mcpHub) {
// Initialize runtime MCP servers
await mcpHub.initializeRuntimeMcpServers(configuration.mcpServers)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

When initializeRuntimeMcpServers fails, should we log this error or notify the user? Currently, if the mcpHub exists but initialization fails, the error is silently swallowed in McpHub. Consider adding error handling here:

Suggested change
await mcpHub.initializeRuntimeMcpServers(configuration.mcpServers)
if (configuration.mcpServers && typeof configuration.mcpServers === "object") {
const mcpHub = provider.getMcpHub()
if (mcpHub) {
try {
// Initialize runtime MCP servers
await mcpHub.initializeRuntimeMcpServers(configuration.mcpServers)
} catch (error) {
console.error('Failed to initialize runtime MCP servers:', error)
// Optionally notify user or continue without MCP servers
}
}
}


mcpEnabled: z.boolean().optional(),
enableMcpServerCreation: z.boolean().optional(),
mcpServers: z.record(z.string(), z.any()).optional(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The mcpServers property uses z.any() which bypasses type safety. Could we define a proper Zod schema for MCP server configurations? This would provide better validation and type safety. Something like:

Suggested change
mcpServers: z.record(z.string(), z.any()).optional(),
mcpServers: z.record(z.string(), z.union([
z.object({
type: z.literal('stdio'),
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string()).optional(),
disabled: z.boolean().optional(),
alwaysAllow: z.array(z.string()).optional()
}),
z.object({
type: z.literal('sse'),
url: z.string().url(),
headers: z.record(z.string()).optional(),
disabled: z.boolean().optional()
})
])).optional(),

* Initialize runtime MCP servers passed programmatically (e.g., through IPC API)
* @param servers Record of server configurations
*/
public async initializeRuntimeMcpServers(servers: Record<string, any>): Promise<void> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Consider adding JSDoc comments to document the purpose and usage patterns of this new method. This would help future developers understand when and how to use runtime MCP servers:

Suggested change
public async initializeRuntimeMcpServers(servers: Record<string, any>): Promise<void> {
/**
* Initialize runtime MCP servers passed programmatically (e.g., through IPC API)
* These servers have the highest priority and override project/global servers with the same name.
* Runtime servers are not persisted to configuration files.
* @param servers Record of server configurations keyed by server name
* @returns Promise<void>
*/
public async initializeRuntimeMcpServers(servers: Record<string, any>): Promise<void> {

})

describe("startNewTask", () => {
it("should initialize runtime MCP servers when mcpServers is provided in configuration", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good test coverage for the happy path! Consider adding tests for error scenarios:

  • Invalid server configurations
  • Initialization failures
  • What happens when initializeRuntimeMcpServers throws an error

This would ensure the error handling is robust.

@daniel-lxs
Copy link
Member

This doesn't look like a good implementation, maybe it makes more sense to allow setting them up via an env var. Closing as the issue needs better scoping.

@daniel-lxs daniel-lxs closed this Sep 1, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Sep 1, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Sep 1, 2025
@daniel-lxs daniel-lxs deleted the feature/mcp-runtime-servers-7518 branch September 1, 2025 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Defining MCP servers through IPC socket API

4 participants