From d5f18034f91b27c235ecf84c5becd2571dea5e81 Mon Sep 17 00:00:00 2001 From: Domye <67504754+domye@users.noreply.github.com> Date: Sun, 16 Aug 2026 15:33:49 +0800 Subject: [PATCH] feat(mcp): add Pi client configuration --- .../editor/EditorSettingsDialog.vue | 21 +++++++++++++++++-- apps/desktop/src/i18n/locales/en.ts | 1 + apps/desktop/src/i18n/locales/zh-CN.ts | 1 + .../__tests__/mcp/mcpConfigTemplates.spec.ts | 13 +++++++++++- .../__tests__/mcp/mcpPolicySelection.spec.ts | 2 +- .../desktop/src/lib/mcp/mcpConfigTemplates.ts | 4 ++++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/components/editor/EditorSettingsDialog.vue b/apps/desktop/src/components/editor/EditorSettingsDialog.vue index e4208f4241..b5bd2f5e10 100644 --- a/apps/desktop/src/components/editor/EditorSettingsDialog.vue +++ b/apps/desktop/src/components/editor/EditorSettingsDialog.vue @@ -110,7 +110,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, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl, type McpLaunchConfig } from "@/lib/mcp/mcpConfigTemplates"; +import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, 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"; @@ -1740,7 +1740,7 @@ async function exportDebugLogs() { } // ---------- MCP Server ---------- -type McpConfigTab = "claude" | "cursor" | "trae" | "vscode" | "windsurf" | "codex" | "opencode" | "cherry-studio"; +type McpConfigTab = "claude" | "cursor" | "trae" | "vscode" | "windsurf" | "codex" | "opencode" | "pi" | "cherry-studio"; type McpCopyKind = "install" | "uninstall" | `${McpConfigTab}-config`; const mcpStatus = ref(null); @@ -1852,6 +1852,7 @@ const mcpCherryStudioRecommendedConfig = computed(() => buildMcpCherryStudioConf const mcpCodexRecommendedConfig = computed(() => buildMcpCodexConfig(mcpLaunchConfig.value)); const mcpOpenCodeRecommendedConfig = computed(() => buildMcpOpenCodeConfig(mcpLaunchConfig.value)); +const mcpPiRecommendedConfig = computed(() => buildMcpPiConfig(mcpLaunchConfig.value)); const mcpStatusTone = computed<"ok" | "warning" | "muted">(() => { if (!mcpStatus.value) return "muted"; @@ -6523,6 +6524,7 @@ onUnmounted(() => { Windsurf Codex OpenCode + Pi Cherry Studio @@ -6626,6 +6628,21 @@ onUnmounted(() => { + +
+
+ {{ t("settings.mcpPiConfigPath") }} +
+
+
{{ mcpPiRecommendedConfig }}
+ +
+
+
+
diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index f49c104b1d..105311ae3f 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -6253,6 +6253,7 @@ export default { 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.", mcpOpenCodeConfigPath: "~/.config/opencode/opencode.json globally, or opencode.json at the project level.", + mcpPiConfigPath: "First install the Pi MCP adapter plugin: pi install npm:pi-mcp-adapter. Then save to ~/.pi/agent/mcp.json (global) or .mcp.json (project), run /mcp to verify, and /reload to pick it up in Pi.", mcpExecutionMode: "MCP execution permission", mcpExecutionModeDescription: "Choose the permission level DBX enforces for every MCP client. Client-side read/write settings cannot change this level.", mcpExecutionModeReadOnly: "Read only", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index dad7f16db4..75bbab1359 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -6242,6 +6242,7 @@ export default withEnglishFallback({ mcpVsCodeConfigPath: "VS Code/Copilot 可放在工作区 .vscode/mcp.json 或用户配置文件 mcp.json。", mcpWindsurfConfigPath: "Windsurf 可放在 ~/.codeium/windsurf/mcp_config.json。", mcpOpenCodeConfigPath: "全局 ~/.config/opencode/opencode.json,项目级 opencode.json。", + mcpPiConfigPath: "先安装 Pi MCP 适配器插件:pi install npm:pi-mcp-adapter。然后保存到 ~/.pi/agent/mcp.json(全局)或 .mcp.json(项目),在 Pi 中运行 /mcp 确认、/reload 生效。", mcpExecutionMode: "MCP 执行权限", mcpExecutionModeDescription: "选择 DBX 对所有 MCP 客户端强制执行的权限级别。客户端的读写权限配置无法更改此级别。", mcpExecutionModeReadOnly: "只读", diff --git a/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts b/apps/desktop/src/lib/__tests__/mcp/mcpConfigTemplates.spec.ts index 5c0a3e38f6..8d8b703208 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, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl } from "@/lib/mcp/mcpConfigTemplates"; +import { buildMcpCherryStudioConfig, buildMcpCodexConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpPiConfig, buildMcpTraeConfig, buildMcpVsCodeConfig, mcpWebBackendUrl } from "@/lib/mcp/mcpConfigTemplates"; describe("MCP config templates", () => { it("builds the standard mcpServers JSON used by Claude, Cursor, TRAE, and Windsurf", () => { @@ -14,6 +14,17 @@ describe("MCP config templates", () => { }); }); + it("builds the standard mcpServers JSON used by the Pi agent", () => { + expect(JSON.parse(buildMcpPiConfig())).toEqual({ + mcpServers: { + dbx: { + command: "dbx-mcp-server", + }, + }, + }); + expect(buildMcpPiConfig({ command: "npx", args: ["-y", "@dbx-app/mcp-server"] })).toContain('"npx"'); + }); + it("builds standard JSON configs with a direct node launch command", () => { const config = JSON.parse(buildMcpJsonConfig({ command: "C:\\Program Files\\nodejs\\node.exe", args: ["C:\\Users\\zhiyo\\AppData\\Roaming\\npm\\node_modules\\@dbx-app\\mcp-server\\dist\\index.js"] })); diff --git a/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts b/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts index 15a8eddd1b..73fb7918ba 100644 --- a/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts +++ b/apps/desktop/src/lib/__tests__/mcp/mcpPolicySelection.spec.ts @@ -123,7 +123,7 @@ 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(8); + expect(tabsSource.match(/flex-none shrink-0/g)).toHaveLength(9); expect(tabsSource).not.toContain("min-w-0 px-"); }); }); diff --git a/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts b/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts index cade617aa5..28f85ef625 100644 --- a/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts +++ b/apps/desktop/src/lib/mcp/mcpConfigTemplates.ts @@ -98,3 +98,7 @@ export function buildMcpOpenCodeConfig(config?: McpLaunchConfig): string { return JSON.stringify({ mcp: { dbx } }, null, 2); } + +export function buildMcpPiConfig(config?: McpLaunchConfig): string { + return buildMcpJsonConfig(config); +}