feat(install): register Claude Code MCP server at user scope#270
Draft
gbrlcustodio wants to merge 4 commits into
Draft
feat(install): register Claude Code MCP server at user scope#270gbrlcustodio wants to merge 4 commits into
gbrlcustodio 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`.
adriannoes
reviewed
Jun 2, 2026
Collaborator
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.