feat(install): register Claude Code MCP server at user scope#270
feat(install): register Claude Code MCP server at user scope#270gbrlcustodio wants to merge 4 commits into
Conversation
`/pipefy:install` previously installed `pipefy_mcp_server` as a uv tool that the Claude Code plugin's bundled `.mcp.json` (uvx) never referenced, so a plugin user who ran it ended up materializing the server twice. Make the installer the single owner of the Claude Code server registration instead: `install.sh --client claude-code` now runs `claude mcp add pipefy --scope user -- pipefy-mcp-server`. By Claude Code's name precedence (local > project > user > plugin) the user-scope entry shadows the plugin's bundled entry, so only the installed binary spawns, on the same system Python the CLI uses. The committed `.mcp.json` (uvx) stays as the zero-config default for the marketplace one-liner. Shadowing means plugin auto-updates no longer reach the running server, so add a SessionStart hook (hooks/check-server-version.sh) that nudges the user to re-run `/pipefy:install` when the installed server version drifts from the plugin's. It no-ops for users on the pure plugin/uvx path. `/pipefy:install` switches from `--client none` to `--client claude-code`.
There was a problem hiding this comment.
Summary
Reviewed the install/plugin diff locally (sh -n, install.sh --dry-run --client claude-code). The user-scope registration cleanly fixes double materialization (uv tool + plugin uvx) and the hook’s “cheap checks first” ordering is sensible. One version-sync gap is worth addressing before this ships broadly (inline on the hook).
Also noted
- F2 — install ordering:
main()installs both uv tools beforerequire_claude, so a missingclaudeCLI leavespipefy/pipefy-mcp-serveron disk but exits beforeclaude mcp add. Since/pipefy:installnow passes--client claude-code, consider checking forclaudebeforeinstall_tool, or finishing with a clear warning instead oferrafter wheels are already installed.
…flicts Adopt the org rename (pipefy/ai-toolkit) and the install.sh-delegation form from the updated base, while keeping this branch's additions: the plugin.json SessionStart version-check hook and the install.sh --client claude-code (user-scope MCP registration) behavior.
The SessionStart hook (hooks/check-server-version.sh) raw-string compares the installed server's --version against plugin.json's version, but bump_version.py never wrote or verified that file. Releases left the manifest behind, so users on the current release got a drift nudge every session. Add .claude-plugin/ plugin.json to the write and verify paths and sync it to the package version.
…atterns Use numbered groups and re-emit the closing quote in the replacement, matching VERSION_ASSIGN_RE and ROOT_PROJECT_VERSION_RE in the same file, instead of the named-group prefix/value/suffix form. Verify reads the version via group(2).
|
Closing this; one piece is salvaged and the rest is deferred rather than dropped. Salvaged into #367: the Deferred (a design decision, not stale): the installer's user-scope registration ( This PR was stacked on #260, which is also being closed as superseded (PyPI publishing landed in #365). |
Summary
Stacked on #260. Removes the double materialization of the Pipefy MCP server on the Claude Code path and makes the installer the single owner of the Claude Code registration.
Previously
/pipefy:installinstalledpipefy_mcp_serveras a uv tool that the plugin's bundled.mcp.json(uvx) never referenced, so a plugin user who ran it ended up with two copies (the uvx-cached env plus an unused tool venv).What changed
install.sh: the--client claude-codebranch now registers the server viaclaude mcp add pipefy --scope user -- pipefy-mcp-server(idempotent: removes any prior user-scope entry first). By Claude Code's name precedence (local > project > user > plugin) the user-scope entry shadows the plugin's bundled entry, so only the installed binary spawns, on the same system Python the CLI is pinned to.require_claudeerrors cleanly if theclaudeCLI is absent.commands/install.md:/pipefy:installswitches from--client noneto--client claude-code, and the prose explains the override + required reload..claude-plugin/plugin.json+hooks/check-server-version.sh: aSessionStarthook that nudges the user to re-run/pipefy:installwhen the installed server version drifts from the plugin's. No-ops for users on the pure plugin/uvx path (no installed binary).Design notes
.mcp.json(uvx) is unchanged and remains the zero-config default, so/plugin install pipefy@pipefystill works with no prior step. The override only kicks in once a user runs/pipefy:install.plugin.json) before spawningpipefy-mcp-server --version, so the Python cold start only happens for users who actually have the override installed.load_session->keyring.get_password); the documented macOS-25244issue is a non-deterministic write duringpipefy auth login. So this is about consistency with the CLI's system-Python install, not a known server-side failure.Test plan
sh -n install.shandsh -n hooks/check-server-version.sh.claude-plugin/plugin.jsonparses as valid JSONinstall.sh --dry-run --client claude-codepreviews theclaude mcp addregistrationuv run pytest(2955 passed, 46 skipped)/pipefy:install+ reload, confirmclaude mcp listshows the user-scopepipefyand the plugin's uvx entry is suppressedRelease sequencing
Targets #260's branch to keep the stack; retarget to
mainonce #260 merges.