From 7e06992f3b693e2dc86ebe10e5bee9bdeebcabcf Mon Sep 17 00:00:00 2001 From: miracle Date: Sat, 5 Sep 2026 22:22:55 +0800 Subject: [PATCH] feat(mcp): add Qoder configuration --- .../editor/EditorSettingsDialog.vue | 26 +++++++++++++++++-- apps/desktop/src/i18n/locales/en.ts | 1 + apps/desktop/src/i18n/locales/es.ts | 1 + apps/desktop/src/i18n/locales/it.ts | 1 + apps/desktop/src/i18n/locales/ja.ts | 1 + apps/desktop/src/i18n/locales/ko.ts | 1 + apps/desktop/src/i18n/locales/pt-BR.ts | 1 + apps/desktop/src/i18n/locales/tr.ts | 1 + apps/desktop/src/i18n/locales/zh-CN.ts | 1 + apps/desktop/src/i18n/locales/zh-TW.ts | 1 + .../__tests__/mcp/mcpConfigTemplates.spec.ts | 15 ++++++++++- .../__tests__/mcp/mcpPolicySelection.spec.ts | 13 +++++++++- .../desktop/src/lib/mcp/mcpConfigTemplates.ts | 4 +++ 13 files changed, 63 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index 22aebcc3fd..e2387e1648 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -174,7 +174,7 @@ import { currentExecutableStatementRange, type SqlTextRange } from "@/lib/sql/sq import { executableStatementRangeCacheForDoc, executableStatementRangeStartingAt, type ExecutableStatementRangeCache } from "@/lib/sql/executableStatementRangeCache"; import { EMPTY_TABLE_COLUMN_TEMPLATE_DATA_TYPE, parseTableColumnTemplateFields, TABLE_COLUMN_TEMPLATE_DATABASE_TYPES, tableColumnTemplateRowsToSettings } from "@/lib/table/tableColumnTemplates"; import { DEFAULT_SQL_VARIABLE_SYNTAX_TOGGLES, normalizeSqlVariableSyntaxOverrides, SQL_VARIABLE_SYNTAX_DATABASE_TYPES, SQL_VARIABLE_SYNTAX_KEYS, SQL_VARIABLE_SYNTAX_TOKENS, type SqlVariableSyntaxOverrides, type SqlVariableSyntaxToggles } from "@/lib/sql/sqlVariableSyntax"; -import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpDeepSeekHarnessConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl, type McpLaunchConfig } from "@/lib/mcp/mcpConfigTemplates"; +import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpDeepSeekHarnessConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, buildMcpQoderConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl, type McpLaunchConfig } from "@/lib/mcp/mcpConfigTemplates"; import { beginMcpStatusRequest, mcpUpdateAvailability } from "@/lib/mcp/mcpUpdateStatus"; import { isMcpPolicyMutationBlocked, MCP_CAPABILITY_ROWS, MCP_EXECUTION_MODE_COLUMNS, mcpExecutionModeFromPolicy, mcpPolicyFieldsForExecutionMode, type McpExecutionMode } from "@/lib/mcp/mcpPolicySelection"; import { isMacOS, isWindows } from "@/lib/backend/platform"; @@ -2118,7 +2118,7 @@ async function exportDebugLogs() { } // ---------- MCP Server ---------- -type McpConfigTab = "claude" | "cursor" | "codebuddy" | "zcode" | "trae" | "vscode" | "windsurf" | "codex" | "deepseek-harness" | "opencode" | "pi" | "cherry-studio"; +type McpConfigTab = "claude" | "cursor" | "codebuddy" | "zcode" | "trae" | "vscode" | "windsurf" | "codex" | "deepseek-harness" | "opencode" | "pi" | "cherry-studio" | "qoder"; type McpCopyKind = "install" | "uninstall" | "http-endpoint" | "http-token" | "http-config" | `${McpConfigTab}-config`; type McpTransportTab = "stdio" | "http"; @@ -2571,6 +2571,12 @@ const mcpTraeRecommendedConfig = computed(() => { return buildMcpTraeConfig(mcpLaunchConfig.value, nativeBinPath ?? undefined); }); +const mcpQoderRecommendedConfig = computed(() => { + // Qoder follows TRAE's mcpServers JSON format and has the same Windows path parsing limitation. + const nativeBinPath = !isWeb && isWindows() ? mcpStatus.value?.native_bin_path : undefined; + return buildMcpQoderConfig(mcpLaunchConfig.value, nativeBinPath ?? undefined); +}); + const mcpVsCodeRecommendedConfig = computed(() => buildMcpVsCodeConfig(mcpLaunchConfig.value)); const mcpCherryStudioRecommendedConfig = computed(() => buildMcpCherryStudioConfig(mcpLaunchConfig.value)); @@ -8341,6 +8347,7 @@ LIMIT 100;OpenCode Pi Cherry Studio + Qoder @@ -8517,6 +8524,21 @@ LIMIT 100; + + +
+
+ {{ t("settings.mcpQoderConfigPath") }} +
+
+
{{ mcpQoderRecommendedConfig }}
+ +
+
+
diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 5b6985ff72..01a54464dc 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -7150,6 +7150,7 @@ export default { mcpCodeBuddyConfigPath: "CodeBuddy Code can use ~/.codebuddy/.mcp.json globally or .mcp.json in the project.", mcpZCodeConfigPath: "ZCode: Settings > MCP Servers > New MCP Server > Full configuration; choose the User or Workspace scope, then paste the JSON configuration.", mcpTraeConfigPath: "TRAE: Settings > MCP > Add > Add Manually, then paste the JSON configuration.", + mcpQoderConfigPath: "Qoder: Settings > MCP > Add Manually, then paste the JSON configuration.", mcpCherryStudioConfigPath: "Cherry Studio: Settings > MCP Servers > Add Server > Import JSON, then paste the configuration.", mcpVsCodeConfigPath: "VS Code/Copilot can use .vscode/mcp.json in the workspace or mcp.json in the user profile.", mcpWindsurfConfigPath: "Windsurf can use ~/.codeium/windsurf/mcp_config.json.", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index 9dafbac88c..b6e1dbdedf 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -6764,6 +6764,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code puede usar ~/.codebuddy/.mcp.json globalmente o .mcp.json en el proyecto.", mcpZCodeConfigPath: "ZCode: Configuración > Servidores MCP > Nuevo servidor MCP > Configuración completa; elige el ámbito Usuario o Espacio de trabajo y pega la configuración JSON.", mcpTraeConfigPath: "TRAE: Configuración > MCP > Agregar > Agregar manualmente; luego pega la configuración JSON.", + mcpQoderConfigPath: "Qoder: Configuración > MCP > Agregar manualmente; luego pega la configuración JSON.", mcpCherryStudioConfigPath: "Cherry Studio: Configuración > Servidores MCP > Agregar servidor > Importar JSON; luego pega la configuración.", mcpVsCodeConfigPath: "VS Code/Copilot puede usar .vscode/mcp.json en el espacio de trabajo o mcp.json en el perfil de usuario.", mcpWindsurfConfigPath: "Windsurf puede usar ~/.codeium/windsurf/mcp_config.json.", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index be209b76f8..c47dfefa43 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -6764,6 +6764,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code può usare ~/.codebuddy/.mcp.json globalmente oppure .mcp.json a livello di progetto.", mcpZCodeConfigPath: "ZCode: Impostazioni > Server MCP > Nuovo server MCP > Configurazione completa; scegli l'ambito Utente o Area di lavoro, quindi incolla la configurazione JSON.", mcpTraeConfigPath: "TRAE: Impostazioni > MCP > Aggiungi > Aggiungi manualmente, poi incolla la configurazione JSON.", + mcpQoderConfigPath: "Qoder: Impostazioni > MCP > Aggiungi manualmente, poi incolla la configurazione JSON.", mcpCherryStudioConfigPath: "Cherry Studio: Impostazioni > Server MCP > Aggiungi server > Importa JSON, quindi incolla la configurazione.", mcpVsCodeConfigPath: "VS Code/Copilot può usare .vscode/mcp.json nell'area di lavoro o mcp.json nel profilo utente.", mcpWindsurfConfigPath: "Windsurf può usare ~/.codeium/windsurf/mcp_config.json.", diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts index 8c1c4651d4..20e5b69035 100644 --- a/apps/desktop/src/i18n/locales/ja.ts +++ b/apps/desktop/src/i18n/locales/ja.ts @@ -6771,6 +6771,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Codeはグローバル ~/.codebuddy/.mcp.json またはプロジェクトレベルの .mcp.json を使用できます。", mcpZCodeConfigPath: "ZCode:設定 > MCP サーバー > 新しい MCP サーバー > 完全な設定を開き、ユーザーまたはワークスペースのスコープを選択して JSON 設定を貼り付けます。", mcpTraeConfigPath: "TRAE: 設定 > MCP > 追加 > 手動で追加 からJSON設定を貼り付けます。", + mcpQoderConfigPath: "Qoder: 設定 > MCP > 手動で追加 からJSON設定を貼り付けます。", mcpCherryStudioConfigPath: "Cherry Studio: 設定 > MCPサーバー > サーバーを追加 > JSONをインポート から設定を貼り付けます。", mcpVsCodeConfigPath: "VS Code/Copilotはワークスペースの .vscode/mcp.json またはユーザープロファイルの mcp.json を使用できます。", mcpWindsurfConfigPath: "Windsurfは ~/.codeium/windsurf/mcp_config.json を使用できます。", diff --git a/apps/desktop/src/i18n/locales/ko.ts b/apps/desktop/src/i18n/locales/ko.ts index a3ee15bc92..24dc7f563a 100644 --- a/apps/desktop/src/i18n/locales/ko.ts +++ b/apps/desktop/src/i18n/locales/ko.ts @@ -6517,6 +6517,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code는 전역 ~/.codebuddy/.mcp.json 또는 프로젝트의 .mcp.json을 사용할 수 있습니다.", mcpZCodeConfigPath: "ZCode: 설정 > MCP 서버 > 새 MCP 서버 > 전체 구성에서 사용자 또는 작업 영역 범위를 선택한 다음 JSON 구성을 붙여넣으세요.", mcpTraeConfigPath: "TRAE: 설정 > MCP > 추가 > 수동 추가 후 JSON 설정을 붙여넣으세요.", + mcpQoderConfigPath: "Qoder: 설정 > MCP > 수동 추가 후 JSON 설정을 붙여넣으세요.", mcpCherryStudioConfigPath: "Cherry Studio: 설정 > MCP 서버 > 서버 추가 > JSON 가져오기 후 설정을 붙여넣으세요.", mcpVsCodeConfigPath: "VS Code/Copilot은 작업 영역의 .vscode/mcp.json 또는 사용자 프로필의 mcp.json을 사용할 수 있습니다.", mcpWindsurfConfigPath: "Windsurf는 ~/.codeium/windsurf/mcp_config.json을 사용할 수 있습니다.", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index c56c6362ca..0edea6b246 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -6766,6 +6766,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "O CodeBuddy Code pode usar ~/.codebuddy/.mcp.json globalmente ou .mcp.json no nível do projeto.", mcpZCodeConfigPath: "ZCode: Configurações > Servidores MCP > Novo servidor MCP > Configuração completa; escolha o escopo Usuário ou Espaço de trabalho e cole a configuração JSON.", mcpTraeConfigPath: "TRAE: Configurações > MCP > Adicionar > Adicionar manualmente; depois cole a configuração JSON.", + mcpQoderConfigPath: "Qoder: Configurações > MCP > Adicionar manualmente; depois cole a configuração JSON.", mcpCherryStudioConfigPath: "Cherry Studio: Configurações > Servidores MCP > Adicionar servidor > Importar JSON; depois cole a configuração.", mcpVsCodeConfigPath: "O VS Code/Copilot pode usar .vscode/mcp.json no workspace ou mcp.json no perfil do usuário.", mcpWindsurfConfigPath: "O Windsurf pode usar ~/.codeium/windsurf/mcp_config.json.", diff --git a/apps/desktop/src/i18n/locales/tr.ts b/apps/desktop/src/i18n/locales/tr.ts index 3907847cfc..0ac7a4f700 100644 --- a/apps/desktop/src/i18n/locales/tr.ts +++ b/apps/desktop/src/i18n/locales/tr.ts @@ -7138,6 +7138,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code, genel olarak ~/.codebuddy/.mcp.json ya da projede .mcp.json kullanabilir.", mcpZCodeConfigPath: "ZCode: Ayarlar > MCP Sunucuları > Yeni MCP Sunucusu > Tam yapılandırma; Kullanıcı ya da Çalışma Alanı kapsamını seçip JSON yapılandırmasını yapıştırın.", mcpTraeConfigPath: "TRAE: Ayarlar > MCP > Ekle > Elle Ekle, ardından JSON yapılandırmasını yapıştırın.", + mcpQoderConfigPath: "Qoder: Ayarlar > MCP > Elle Ekle, ardından JSON yapılandırmasını yapıştırın.", mcpCherryStudioConfigPath: "Cherry Studio: Ayarlar > MCP Sunucuları > Sunucu Ekle > JSON İçe Aktar, ardından yapılandırmayı yapıştırın.", mcpVsCodeConfigPath: "VS Code/Copilot, çalışma alanında .vscode/mcp.json ya da kullanıcı profilinde mcp.json kullanabilir.", mcpWindsurfConfigPath: "Windsurf, ~/.codeium/windsurf/mcp_config.json kullanabilir.", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index da3c21eff9..c68b52da73 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -7135,6 +7135,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code 可使用全局 ~/.codebuddy/.mcp.json 或项目级 .mcp.json。", mcpZCodeConfigPath: "ZCode:设置 > MCP 服务器 > 新建 MCP 服务器 > 完整配置,选择用户或工作区作用域后粘贴 JSON 配置。", mcpTraeConfigPath: "TRAE:设置 > MCP > 添加 > 手动添加,然后粘贴 JSON 配置。", + mcpQoderConfigPath: "Qoder:设置 > MCP > 手动添加,然后粘贴 JSON 配置。", mcpCherryStudioConfigPath: "Cherry Studio:设置 > MCP 服务器 > 添加服务器 > 导入 JSON,然后粘贴配置。", mcpVsCodeConfigPath: "VS Code/Copilot 可放在工作区 .vscode/mcp.json 或用户配置文件 mcp.json。", mcpWindsurfConfigPath: "Windsurf 可放在 ~/.codeium/windsurf/mcp_config.json。", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index 7939c44831..0e00cec547 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -6099,6 +6099,7 @@ export default withEnglishFallback({ mcpCodeBuddyConfigPath: "CodeBuddy Code 可使用全域 ~/.codebuddy/.mcp.json 或專案級 .mcp.json。", mcpZCodeConfigPath: "ZCode:設定 > MCP 伺服器 > 新增 MCP 伺服器 > 完整設定,選擇使用者或工作區範圍後貼上 JSON 設定。", mcpTraeConfigPath: "TRAE:設定 > MCP > 新增 > 手動新增,然後貼上 JSON 設定。", + mcpQoderConfigPath: "Qoder:設定 > MCP > 手動新增,然後貼上 JSON 設定。", mcpCherryStudioConfigPath: "Cherry Studio:設定 > MCP 伺服器 > 新增伺服器 > 匯入 JSON,然後貼上設定。", mcpVsCodeConfigPath: "VS Code/Copilot 可放在工作區 .vscode/mcp.json 或使用者設定檔 mcp.json。", mcpWindsurfConfigPath: "Windsurf 可放在 ~/.codeium/windsurf/mcp_config.json。", diff --git a/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts b/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts index 3a7e8bc28d..f970cf52af 100644 --- a/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts +++ b/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpDeepSeekHarnessConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl } from "@/lib/mcp/mcpConfigTemplates"; +import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpDeepSeekHarnessConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, buildMcpQoderConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl } from "@/lib/mcp/mcpConfigTemplates"; describe("MCP config templates", () => { it("builds the standard mcpServers JSON used by Claude, Cursor, TRAE, and Windsurf", () => { @@ -66,6 +66,19 @@ describe("MCP config templates", () => { }); }); + it("builds the Qoder config with the same launch shape as TRAE", () => { + const launch = { + command: "C:\\Program Files\\nodejs\\node.exe", + args: ["C:\\dbx\\mcp\\dist\\index.js"], + env: { DBX_DATA_DIR: "D:\\DBX Data" }, + }; + const nativeBinPath = "C:\\Users\\supervisor\\AppData\\Roaming\\npm\\node_modules\\@dbx-app\\mcp-win32-x64\\bin\\dbx-mcp.exe"; + + expect(JSON.parse(buildMcpQoderConfig(launch, nativeBinPath))).toEqual({ + mcpServers: { dbx: { command: nativeBinPath, env: launch.env } }, + }); + }); + it("includes Web runtime settings without restoring permission environment variables", () => { const launch = { command: "dbx-mcp-server", diff --git a/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts b/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts index 5aecb8b431..207c5c3f15 100644 --- a/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts +++ b/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts @@ -123,10 +123,11 @@ describe("MCP policy settings state", () => { expect(tabsSource).toContain("overscroll-x-contain"); expect(tabsSource).not.toContain("flex-wrap"); expect(tabsSource).not.toContain("grid-cols-"); - expect(tabsSource.match(/flex-none shrink-0/g)).toHaveLength(12); + expect(tabsSource.match(/flex-none shrink-0/g)).toHaveLength(13); expect(tabsSource).toContain(' { expect(zCodeSource).toContain("settings.mcpZCodeConfigPath"); expect(zCodeSource).toContain("mcpJsonRecommendedConfig"); expect(zCodeSource).toContain("copyMcpText('zcode-config', mcpJsonRecommendedConfig)"); + + const qoderStart = settingsDialogSource.indexOf('", qoderStart); + const qoderSource = settingsDialogSource.slice(qoderStart, qoderEnd); + + expect(qoderStart).toBeGreaterThan(tabsEnd); + expect(qoderEnd).toBeGreaterThan(qoderStart); + expect(qoderSource).toContain("settings.mcpQoderConfigPath"); + expect(qoderSource).toContain("mcpQoderRecommendedConfig"); + expect(qoderSource).toContain("copyMcpText('qoder-config', mcpQoderRecommendedConfig)"); }); }); diff --git a/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts b/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts index d92c9bc6e9..236ea4b396 100644 --- a/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts +++ b/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts @@ -44,6 +44,10 @@ export function buildMcpTraeConfig(config?: McpLaunchConfig, nativeBinPath?: str return buildMcpJsonConfig(nativeBinPath ? { command: nativeBinPath, env: config?.env } : config); } +export function buildMcpQoderConfig(config?: McpLaunchConfig, nativeBinPath?: string): string { + return buildMcpTraeConfig(config, nativeBinPath); +} + export function buildMcpVsCodeConfig(config?: McpLaunchConfig): string { const dbx: Record = { type: "stdio",