Skip to content

feat(cli): auto-discover MCP servers in .continue/mcpServers#12922

Open
Rakesh1002 wants to merge 1 commit into
continuedev:mainfrom
Rakesh1002:feat/cli-mcp-json-discovery
Open

feat(cli): auto-discover MCP servers in .continue/mcpServers#12922
Rakesh1002 wants to merge 1 commit into
continuedev:mainfrom
Rakesh1002:feat/cli-mcp-json-discovery

Conversation

@Rakesh1002

@Rakesh1002 Rakesh1002 commented Jun 30, 2026

Copy link
Copy Markdown

Description

Closes #12254.

The CLI (cn) only discovers MCP servers from four sources: the active config's mcpServers: block, uses: references resolved by the unroller, --mcp, and --agent files. Unlike the IDE extensions, it ignores standalone server files placed in .continue/mcpServers/ — even though the docs describe that directory as the quick-start path.

Change

Adds loadJsonMcpServers (extensions/cli/src/services/loadJsonMcpServers.ts), which mirrors the IDE's core/context/mcp/json/loadJsonMcpConfigs.ts:

  • Scans the workspace .continue/mcpServers/ and the global ~/.continue/mcpServers/ (via env.continueHome, matching the existing skills loader).
  • Parses .json files in all three formats the IDE supports — single-server, Claude-desktop ({ "mcpServers": { … } }), and Claude-code (top-level + per-project) — reusing @continuedev/config-yaml's schemas and convertJsonMcpConfigToYamlMcpConfig so the output matches the assistant's mcpServers shape.
  • De-duplicates by server name and skips invalid files with a warning rather than throwing.

ConfigService.getAdditionalBlocksFromOptions merges the discovered servers into the unrolled assistant, so cn now reaches parity with the IDE.

Tests

loadJsonMcpServers.test.ts — 6 vitest cases against the real @continuedev/config-yaml (empty dir, single stdio file named after the file, Claude-desktop map, http transport mapping, invalid-file skip, name de-duplication). npm run lint + tsc --noEmit pass; existing ConfigService/MCPService suites unaffected.

Notes

  • Scoped to .json to match the IDE's loader (which filters to .json); YAML discovery could be a follow-up.
  • Uses JSON.parse (no new dependency); switching to JSONC for comment support is a possible follow-up.

Summary by cubic

Add CLI auto-discovery of MCP servers from .continue/mcpServers (workspace and global) and merge them into the assistant config, bringing cn to parity with the IDE. Supports single-server, Claude Desktop, and Claude Code JSON formats with name de-dupe and safe skips.

  • New Features
    • Added loadJsonMcpServers to scan workspace and env.continueHome .continue/mcpServers/.
    • Parses .json files in supported formats using @continuedev/config-yaml schemas and convertJsonMcpConfigToYamlMcpConfig.
    • Merged discovered servers in ConfigService.getAdditionalBlocksFromOptions.
    • De-duplicates by server name, warns on invalid files, and maps http to streamable-http.

Written for commit a129774. Summary will update on new commits.

Review in cubic

The CLI only loaded MCP servers from the active config's mcpServers block,
`uses` references, and --mcp/--agent flags. Unlike the IDE extensions, it
ignored standalone server files dropped into .continue/mcpServers, which the
docs describe as the quick-start path.

Add loadJsonMcpServers, which scans the workspace .continue/mcpServers and the
global ~/.continue/mcpServers for JSON files (single-server, Claude-desktop, and
Claude-code formats), converts them to the assistant mcpServers shape, and
de-duplicates by name. ConfigService merges the discovered servers into the
unrolled assistant, bringing the CLI to parity with the IDE.

Closes continuedev#12254
@Rakesh1002 Rakesh1002 requested a review from a team as a code owner June 30, 2026 13:12
@Rakesh1002 Rakesh1002 requested review from sestinj and removed request for a team June 30, 2026 13:12
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 30, 2026
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@Rakesh1002

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@cubic-dev-ai cubic-dev-ai Bot left a comment

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.

4 issues found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="extensions/cli/src/services/loadJsonMcpServers.test.ts">

<violation number="1" location="extensions/cli/src/services/loadJsonMcpServers.test.ts:54">
P3: Weak assertion in Claude-desktop test: only checks server name, does not verify command/args properties are correctly parsed through convertJsonMcpConfigToYamlMcpConfig</violation>
</file>

<file name="extensions/cli/src/services/ConfigService.ts">

<violation number="1" location="extensions/cli/src/services/ConfigService.ts:162">
P2: The new MCP JSON discovery hook is not guarded inside ConfigService, so an unexpected exception from `loadJsonMcpServers` can abort config loading, startup, switchConfig, or reload instead of being treated as an optional discovery failure with a warning.</violation>

<violation number="2" location="extensions/cli/src/services/ConfigService.ts:163">
P2: Auto-discovered MCP servers should be filtered against servers already present in `additional.mcpServers` before pushing, and the precedence relative to the loaded assistant config should be explicit. Currently the JSON discovery path appends blindly, relying on downstream merge order and risking silent override of config-defined servers.</violation>
</file>

<file name="extensions/cli/src/services/loadJsonMcpServers.ts">

<violation number="1" location="extensions/cli/src/services/loadJsonMcpServers.ts:76">
P2: Workspace MCP server discovery defaults to `process.cwd()`, which may miss `.continue/mcpServers/` at the project root when `cn` is launched from a subdirectory. The IDE equivalent resolves actual workspace directories instead of relying on the shell cwd.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

}

private processJsonMcpServers(additional: AssistantUnrolled): void {
for (const server of loadJsonMcpServers()) {

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.

P2: Auto-discovered MCP servers should be filtered against servers already present in additional.mcpServers before pushing, and the precedence relative to the loaded assistant config should be explicit. Currently the JSON discovery path appends blindly, relying on downstream merge order and risking silent override of config-defined servers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/cli/src/services/ConfigService.ts, line 163:

<comment>Auto-discovered MCP servers should be filtered against servers already present in `additional.mcpServers` before pushing, and the precedence relative to the loaded assistant config should be explicit. Currently the JSON discovery path appends blindly, relying on downstream merge order and risking silent override of config-defined servers.</comment>

<file context>
@@ -157,6 +159,12 @@ export class ConfigService
   }
 
+  private processJsonMcpServers(additional: AssistantUnrolled): void {
+    for (const server of loadJsonMcpServers()) {
+      additional.mcpServers!.push(server);
+    }
</file context>

Comment on lines +162 to +166
private processJsonMcpServers(additional: AssistantUnrolled): void {
for (const server of loadJsonMcpServers()) {
additional.mcpServers!.push(server);
}
}

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.

P2: The new MCP JSON discovery hook is not guarded inside ConfigService, so an unexpected exception from loadJsonMcpServers can abort config loading, startup, switchConfig, or reload instead of being treated as an optional discovery failure with a warning.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/cli/src/services/ConfigService.ts, line 162:

<comment>The new MCP JSON discovery hook is not guarded inside ConfigService, so an unexpected exception from `loadJsonMcpServers` can abort config loading, startup, switchConfig, or reload instead of being treated as an optional discovery failure with a warning.</comment>

<file context>
@@ -157,6 +159,12 @@ export class ConfigService
     }
   }
 
+  private processJsonMcpServers(additional: AssistantUnrolled): void {
+    for (const server of loadJsonMcpServers()) {
+      additional.mcpServers!.push(server);
</file context>
Suggested change
private processJsonMcpServers(additional: AssistantUnrolled): void {
for (const server of loadJsonMcpServers()) {
additional.mcpServers!.push(server);
}
}
private processJsonMcpServers(additional: AssistantUnrolled): void {
try {
for (const server of loadJsonMcpServers()) {
additional.mcpServers!.push(server);
}
} catch (e) {
logger.warn(`Failed to load JSON MCP servers: ${getErrorString(e)}`);
}
}

* Returns configs in the same shape as the rest of the assistant's mcpServers.
*/
export function loadJsonMcpServers(
cwd: string = process.cwd(),

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.

P2: Workspace MCP server discovery defaults to process.cwd(), which may miss .continue/mcpServers/ at the project root when cn is launched from a subdirectory. The IDE equivalent resolves actual workspace directories instead of relying on the shell cwd.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/cli/src/services/loadJsonMcpServers.ts, line 76:

<comment>Workspace MCP server discovery defaults to `process.cwd()`, which may miss `.continue/mcpServers/` at the project root when `cn` is launched from a subdirectory. The IDE equivalent resolves actual workspace directories instead of relying on the shell cwd.</comment>

<file context>
@@ -0,0 +1,134 @@
+ * Returns configs in the same shape as the rest of the assistant's mcpServers.
+ */
+export function loadJsonMcpServers(
+  cwd: string = process.cwd(),
+): MCPServerConfig[] {
+  const servers: MCPServerConfig[] = [];
</file context>


const servers = loadJsonMcpServers(cwd);

expect(servers.map((s) => s.name)).toEqual(["weather"]);

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.

P3: Weak assertion in Claude-desktop test: only checks server name, does not verify command/args properties are correctly parsed through convertJsonMcpConfigToYamlMcpConfig

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/cli/src/services/loadJsonMcpServers.test.ts, line 54:

<comment>Weak assertion in Claude-desktop test: only checks server name, does not verify command/args properties are correctly parsed through convertJsonMcpConfigToYamlMcpConfig</comment>

<file context>
@@ -0,0 +1,91 @@
+
+    const servers = loadJsonMcpServers(cwd);
+
+    expect(servers.map((s) => s.name)).toEqual(["weather"]);
+  });
+
</file context>

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

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI: auto-discover MCP servers in .continue/mcpServers/ like the IDE does

1 participant