Skip to content

feat: MCP client selector in delega init#9

Merged
ryanmcmillan merged 2 commits intomainfrom
feature/mcp-client-selector
Mar 22, 2026
Merged

feat: MCP client selector in delega init#9
ryanmcmillan merged 2 commits intomainfrom
feature/mcp-client-selector

Conversation

@ryanmcmillan
Copy link
Member

What

After setup completes, delega init now prompts:

Which MCP client do you use?
  1. Claude Code / Claude Desktop
  2. Cursor
  3. Windsurf
  4. VS Code (Copilot)
  5. Continue
  6. Codex
  7. OpenClaw
  8. Other / manual
Select an option [1-8]:

Then outputs the correct config JSON with the right wrapper keys and file path for that client.

Why

Previously hardcoded claude_desktop_config.json output — users of Cursor, VS Code, Windsurf, etc. had to manually restructure the JSON. Now it's copy-paste-ready for any MCP client.

Config differences by client

Client Wrapper File
Claude Code / Desktop mcpServers claude_desktop_config.json / .mcp.json
Cursor mcpServers .cursor/mcp.json
Windsurf mcpServers ~/.codeium/windsurf/mcp_config.json
VS Code servers .vscode/mcp.json
Continue experimental.modelContextProtocol.servers ~/.continue/config.json
Codex mcpServers codex.json
OpenClaw mcp.servers ~/.openclaw/openclaw.json
Other mcpServers (generic)

Changes

  • printSuccess()async (awaits promptChoice)
  • Added McpClient interface + MCP_CLIENTS array + DELEGA_SERVER_ENTRY constant
  • Configs match canonical snippets from docs.html and ~/clawd/drafts/delega/mcp-configs/
  • Self-hosted env var (DELEGA_API_URL) still conditionally added
  • TypeScript builds clean

After setup, prompt user to choose their MCP client:
Claude Code, Cursor, Windsurf, VS Code, Continue, Codex,
OpenClaw, or Other. Outputs the correct config format and
file path for each client.

Configs match the canonical snippets from docs.html:
- VS Code uses 'servers' (not 'mcpServers')
- Continue uses 'experimental.modelContextProtocol.servers'
- OpenClaw uses 'mcp.servers'
- All others use 'mcpServers'
@ryanmcmillan
Copy link
Member Author

@greptile review

@greptile-apps
Copy link

greptile-apps bot commented Mar 22, 2026

Greptile Summary

This PR adds a post-setup MCP client selector to delega init, replacing the hardcoded claude_desktop_config.json output with client-specific config snippets for Claude, Cursor, Windsurf, VS Code, Continue, Codex, OpenClaw, and a generic fallback. The implementation is well-structured, the Codex TOML output addresses the previous review comment, and the VS Code type: "stdio" field was added as suggested.

Two issues remain:

  • Continue config uses deprecated format (src/commands/init.ts lines 606–610): The generated snippet targets experimental.modelContextProtocol.servers in ~/.continue/config.json, which Continue's documentation now marks as Deprecated. Current Continue uses config.yaml with a top-level mcpServers array, or per-server discovery files under ~/.continue/mcpServers/*.json. The generated config will not work for users on a current version of Continue.
  • TOML string values are not escaped (src/commands/init.ts lines 617–629): The buildToml helper interpolates env values directly into TOML basic strings without escaping backslashes or double-quotes. Values containing those characters will produce syntactically invalid TOML that Codex cannot parse.

Confidence Score: 3/5

  • Safe to merge if the Continue config format is corrected; the TOML escaping bug is low-risk in practice but should still be fixed.
  • The core feature works correctly for the majority of clients. The TOML escaping gap is latent (API keys are typically alphanumeric) but is a real correctness bug. More impactfully, the Continue config targets a deprecated JSON format that will silently produce a non-functional setup for all current Continue users.
  • src/commands/init.ts — specifically the Continue client entry (lines 606–610) and the Codex buildToml helper (lines 617–629).

Important Files Changed

Filename Overview
src/commands/init.ts Adds MCP client selector to printSuccess(). Two issues found: the Continue entry generates the deprecated config.json format (should use config.yaml or per-server JSON files), and the Codex TOML builder lacks string escaping for backslashes and double-quotes in env values.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[delega init completes setup] --> B[printSuccess called]
    B --> C[promptChoice: Which MCP client?]
    C --> D{client.format}
    D -- toml --> E{client.buildToml defined?}
    E -- yes --> F[buildToml renders TOML string]
    E -- no --> G[fall through to JSON path]
    D -- json / undefined --> H[buildConfig returns Record]
    H --> I[JSON.stringify config]
    F --> J[indent + console.log]
    G --> I
    I --> J
    J --> K[Show file path hint to user]

    C --> L1[Claude Code / Desktop → mcpServers]
    C --> L2[Cursor → mcpServers]
    C --> L3[Windsurf → mcpServers]
    C --> L4[VS Code → servers + type:stdio]
    C --> L5[Continue → experimental.modelContextProtocol.servers ⚠️ deprecated]
    C --> L6[Codex → TOML via buildToml ⚠️ no escaping]
    C --> L7[OpenClaw → mcp.servers]
    C --> L8[Other → mcpServers generic]
Loading

Last reviewed commit: "fix: Codex TOML conf..."

@ryanmcmillan
Copy link
Member Author

@greptile review - both P1 (Codex TOML) and P2 (VS Code stdio) have been fixed in commit f327f63

@ryanmcmillan ryanmcmillan merged commit 3373529 into main Mar 22, 2026
2 checks passed
Comment on lines +617 to +629
buildToml: (env) => {
const lines = [
"[mcp_servers.delega]",
`command = "npx"`,
`args = ["-y", "@delega-dev/mcp"]`,
"",
"[mcp_servers.delega.env]",
];
for (const [key, value] of Object.entries(env)) {
lines.push(`${key} = "${value}"`);
}
return lines.join("\n");
},
Copy link

Choose a reason for hiding this comment

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

P2 TOML values are not escaped

TOML basic strings (double-quoted) require that " and \ characters in the value be escaped as \" and \\. The current code interpolates env values directly without any escaping:

lines.push(`${key} = "${value}"`);

If an env value contains a literal backslash or double-quote, the generated TOML will be syntactically invalid and codex will fail to parse the config file.

Suggested change
buildToml: (env) => {
const lines = [
"[mcp_servers.delega]",
`command = "npx"`,
`args = ["-y", "@delega-dev/mcp"]`,
"",
"[mcp_servers.delega.env]",
];
for (const [key, value] of Object.entries(env)) {
lines.push(`${key} = "${value}"`);
}
return lines.join("\n");
},
buildToml: (env) => {
const escapeTOML = (s: string) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
const lines = [
"[mcp_servers.delega]",
`command = "npx"`,
`args = ["-y", "@delega-dev/mcp"]`,
"",
"[mcp_servers.delega.env]",
];
for (const [key, value] of Object.entries(env)) {
lines.push(`${key} = "${escapeTOML(value)}"`);
}
return lines.join("\n");
},

@ryanmcmillan ryanmcmillan deleted the feature/mcp-client-selector branch March 22, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant