Skip to content

feat(backend): manage global MCP servers through the pi mcp implementation - #417

Merged
bubbleptr merged 3 commits into
mainfrom
feat/mcp-settings-backend
Oct 1, 2026
Merged

bubbleptr merged 3 commits into
mainfrom
feat/mcp-settings-backend

Conversation

@bubbleptr

@bubbleptr bubbleptr commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

No linked issue: implements the MCP Settings direction recorded in .scratch/mcp-settings/PRD.md (resolves .scratch/mcp-extension-ui/HANDOFF.md). Session-level MCP notices are deferred to #416.

Summary

  • 新增 backend MCP 服务 workspace/mcp-servers.ts:列表/探测、OAuth 登录登出、启用禁用、exposure、添加(stdio / HTTP)与删除。
  • 不另写 MCP 客户端:直接调用 Pi 自带的 runMcpCommand、loadMcpConfig、updateMcpServerConfig,与会话里的内置 MCP 扩展共用配置解析、OAuth 判定和 mcp-auth.json 凭据位置。
  • 这几个模块不在 Pi 包的 exports 里,按文件路径别名引入并打进安装包(electron.vite.config.ts、vite.config.ts、tsconfig.json),绑定当前固定的 Pi 版本。
  • 契约类型放在 packages/core/src/mcp-servers.ts,renderer 不依赖 Pi 内部类型。
  • Gateway 方法:get_mcp_config、probe_mcp_servers、login_mcp_server、logout_mcp_server、set_mcp_server_enabled、set_mcp_server_exposure、add_mcp_server、remove_mcp_server。
  • OAuth 打开浏览器复用平台现有逻辑(抽到 workspace/open-url.ts)。
  • 配置项带 hasStoredCredentials:用 Pi 自己的 McpOAuthCredentialStore 查 mcp-auth.json(按 URL 为键),UI 据此只在真有凭据时提供 Sign out。
  • 第一版只管全局 mcp.json;项目级 .pi/mcp.json 和项目信任后续再做。

Test plan

  • 针对真实 Pi 包的契约测试:mcp.json 结构、CLI 参数、list --json 输出一变即失败(PI_CODING_AGENT_DIR 指向临时目录,不碰真实 home)
  • 零依赖 MCP 测试服务器 workspace/fixtures/mcp-test-server.mjs:真实握手探测 stdio 已连接、HTTP 已连接、HTTP 401 → needs-auth(参数指向不存在文件时测试会失败,非空验证)
  • 预置 mcp-auth.json 时 hasStoredCredentials 为 true,logout 后回到 false
  • service.test.ts 覆盖 Gateway 方法
  • bun run typecheck / bun run lint / bun run test / bun run build 全绿
  • 打包运行时测试 3/3 通过(确认 runMcpCommand 已打进安装包)

…ation

Settings needs MCP status and sign-in, but the built-in MCP extension keeps its state inside its closure. Reuse runMcpCommand and loadMcpConfig (bundled by path, contract-tested against the pinned Pi) instead of writing a Pace MCP client.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment on lines +123 to +130
const exitCode = await runMcpCommand(args, {
...commandBase,
// Passing openUrl also makes `login` non-interactive (no stdin prompt);
// other subcommands ignore it.
openUrl: openExternal,
log: (line) => out.push(line),
error: (line) => err.push(line),
});

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.

🟡 OAuth credentials use the wrong directory

When agentDir differs from PI_CODING_AGENT_DIR, runMcpCommand reads and writes OAuth credentials in Pi's default directory. Sessions using agentDir cannot use those credentials, and logout targets the wrong store.

Learn more

The service accepts an explicit agent directory and uses it when loading and updating the global MCP configuration. Pi's CLI command resolves its credential store through getAgentDir(), which reads the process environment instead of the supplied agentDir; the contract test setup sets that environment variable to match the test directory. If the values differ, OAuth login and logout operate on a different mcp-auth.json from the sessions configured for this service.

Example: With agentDir set to /tmp/profile-b and PI_CODING_AGENT_DIR unset, adding a server writes /tmp/profile-b/mcp.json, but logging in saves credentials under ~/.pi/agent. A session using /tmp/profile-b remains unauthenticated.

Recommended fix: Make the Pi CLI credential store use the same agent directory for the duration of each command, without globally changing process.env across concurrent requests. If the CLI cannot accept a credential-store path, use Pi's lower-level credential API or restrict the service contract and explicitly enforce the process agent directory.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@bubbleptr
bubbleptr merged commit fc1bfae into main Oct 1, 2026
1 check passed
@bubbleptr
bubbleptr deleted the feat/mcp-settings-backend branch October 1, 2026 11:43
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