From 54f0ac8d86ba400cf4b75b5d8a96d17a4517bd8c Mon Sep 17 00:00:00 2001 From: glorydavid03023 Date: Thu, 2 Jul 2026 07:47:38 -0500 Subject: [PATCH] feat(mcp): add windsurf host to init-client config Add `windsurf` to `gittensory-mcp init-client --print`. Windsurf reads ~/.codeium/windsurf/mcp_config.json using the same shared `mcpServers` JSON shape as claude/cursor/mcp, so it reuses that snippet branch (unlike vscode's `servers`/`type` shape). Updates the CLI usage text, the empty-client and unsupported-client error messages, the README example + host description, and the public MCP-clients docs page (docs.mcp-clients.tsx) generate-config command list so the docs match the new CLI surface. A test asserts the windsurf snippet equals the shared mcpServers snippet. No issue because issue creation is restricted on this repo; this is a small additive host mirroring the vscode host addition (#1770), no schema/API change. --- apps/gittensory-ui/src/routes/docs.mcp-clients.tsx | 3 ++- packages/gittensory-mcp/README.md | 3 ++- packages/gittensory-mcp/bin/gittensory-mcp.js | 10 ++++++---- test/unit/mcp-cli-basics.test.ts | 4 ++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/gittensory-ui/src/routes/docs.mcp-clients.tsx b/apps/gittensory-ui/src/routes/docs.mcp-clients.tsx index 10bd2612db..849f8280b6 100644 --- a/apps/gittensory-ui/src/routes/docs.mcp-clients.tsx +++ b/apps/gittensory-ui/src/routes/docs.mcp-clients.tsx @@ -39,7 +39,8 @@ function McpClients() { code={`gittensory-mcp init-client --print codex gittensory-mcp init-client --print claude gittensory-mcp init-client --print cursor -gittensory-mcp init-client --print mcp`} +gittensory-mcp init-client --print mcp +gittensory-mcp init-client --print windsurf`} />

--print mcp uses the same JSON snippet as Claude Desktop and Cursor for other diff --git a/packages/gittensory-mcp/README.md b/packages/gittensory-mcp/README.md index a6da3b9656..27afff8c9e 100644 --- a/packages/gittensory-mcp/README.md +++ b/packages/gittensory-mcp/README.md @@ -48,6 +48,7 @@ gittensory-mcp init-client --print codex gittensory-mcp init-client --print claude gittensory-mcp init-client --print cursor gittensory-mcp init-client --print vscode +gittensory-mcp init-client --print windsurf gittensory-mcp init-client --print codex --agent-profile miner-planner gittensory-mcp completion bash gittensory-mcp completion zsh @@ -159,7 +160,7 @@ The same capabilities are exposed to MCP clients as: ### Client config -`init-client --print ` prints the stdio MCP config for a host: `codex` (TOML), `claude`, `cursor`, and `mcp` (the shared `mcpServers` JSON shape), and `vscode` (VS Code's native `servers` map with `"type": "stdio"`, for `.vscode/mcp.json`). It prints config only; it never edits client files. +`init-client --print ` prints the stdio MCP config for a host: `codex` (TOML), `claude`, `cursor`, `mcp`, and `windsurf` (the shared `mcpServers` JSON shape; Windsurf reads `~/.codeium/windsurf/mcp_config.json`), and `vscode` (VS Code's native `servers` map with `"type": "stdio"`, for `.vscode/mcp.json`). It prints config only; it never edits client files. ### Agent profiles diff --git a/packages/gittensory-mcp/bin/gittensory-mcp.js b/packages/gittensory-mcp/bin/gittensory-mcp.js index 280189ec7c..54d4127d33 100755 --- a/packages/gittensory-mcp/bin/gittensory-mcp.js +++ b/packages/gittensory-mcp/bin/gittensory-mcp.js @@ -1860,7 +1860,7 @@ function printHelp() { gittensory-mcp changelog [--json] gittensory-mcp doctor [--profile name] [--cwd path] [--exit-code] [--json] gittensory-mcp cache status|list|clear [--json] - gittensory-mcp init-client --print codex|claude|cursor|mcp|vscode [--agent-profile miner-planner|maintainer-triage|repo-owner-intake] [--json] + gittensory-mcp init-client --print codex|claude|cursor|mcp|vscode|windsurf [--agent-profile miner-planner|maintainer-triage|repo-owner-intake] [--json] gittensory-mcp decision-pack --login [--json] gittensory-mcp repo-decision --login --repo owner/repo [--json] gittensory-mcp analyze-branch --login [--repo owner/repo] [--base origin/main] [--branch-eligibility eligible|ineligible|unknown] [--pending-merged-prs 3] [--expected-open-prs 0] [--projected-credibility 0.8] [--scenario-note "..."] [--validation "passed|npm test|summary"] [--json] @@ -2402,7 +2402,7 @@ function shellArg(value) { function initClient(options) { const client = String(options.print ?? options.client ?? "").toLowerCase(); - if (!client) throw new Error("Pass --print codex, --print claude, --print cursor, --print mcp, or --print vscode."); + if (!client) throw new Error("Pass --print codex, --print claude, --print cursor, --print mcp, --print vscode, or --print windsurf."); const command = options.command ?? "gittensory-mcp"; const snippet = clientSnippet(client, command); const agentProfile = resolveAgentProfile(options.agentProfile); @@ -2801,7 +2801,9 @@ function redactPrivateValidationMetrics(text) { function clientSnippet(client, command) { if (client === "codex") return `[mcp_servers.gittensory]\ncommand = ${JSON.stringify(command)}\nargs = ["--stdio"]`; - if (client === "claude" || client === "cursor" || client === "mcp") { + // claude/cursor/mcp and Windsurf all consume the shared `mcpServers` JSON shape (Windsurf reads + // ~/.codeium/windsurf/mcp_config.json), so they share one snippet. + if (client === "claude" || client === "cursor" || client === "mcp" || client === "windsurf") { return JSON.stringify( { mcpServers: { @@ -2832,7 +2834,7 @@ function clientSnippet(client, command) { 2, ); } - throw new Error(`Unsupported client: ${client}. Use codex, claude, cursor, mcp, or vscode.`); + throw new Error(`Unsupported client: ${client}. Use codex, claude, cursor, mcp, vscode, or windsurf.`); } async function getDecisionPackWithCache(login) { diff --git a/test/unit/mcp-cli-basics.test.ts b/test/unit/mcp-cli-basics.test.ts index 8405314ad4..23a9cc5921 100644 --- a/test/unit/mcp-cli-basics.test.ts +++ b/test/unit/mcp-cli-basics.test.ts @@ -28,6 +28,10 @@ describe("gittensory-mcp CLI — basics", () => { const generic = JSON.parse(run(["init-client", "--print", "mcp", "--json"])) as { snippet: string }; expect(generic.snippet).toBe(claude.snippet); + // Windsurf consumes the same shared `mcpServers` JSON shape (~/.codeium/windsurf/mcp_config.json). + const windsurf = JSON.parse(run(["init-client", "--print", "windsurf", "--json"])) as { snippet: string }; + expect(windsurf.snippet).toBe(claude.snippet); + const vscode = JSON.parse(run(["init-client", "--print", "vscode", "--json"])) as { snippet: string }; // VS Code uses a `servers` map with an explicit transport type, not the `mcpServers` shape. expect(vscode.snippet).toContain('"servers"');