Skip to content

fix(mcp): register marketplace and gate Claude Code plugin install on version#470

Draft
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-claude-code-plugin-install
Draft

fix(mcp): register marketplace and gate Claude Code plugin install on version#470
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-claude-code-plugin-install

Conversation

@posthog
Copy link
Copy Markdown

@posthog posthog Bot commented May 22, 2026

Problem

ClaudeCodeMCPClient.installPlugin() (src/steps/add-mcp-server-to-clients/clients/claude-code.ts:143) executed claude plugin install posthog unconditionally and routed every failure through captureException. Over the last 30 days the Claude Code plugin install failed exception fired for ~480 events / ~330 distinct users on the wizard's MCP setup flow:

  • ~325 users hit Plugin "posthog" not found in any configured marketplace — the wizard never registered the marketplace before the install. (Introduced when chore: plugin interface for claude and codex #428 swapped claude mcp add for claude plugin install without the prerequisite step.)
  • A smaller cluster on Claude Code < 1.0.88 hit either error: unknown command 'install' (binaries that predate the plugin subcommand) or Claude Code's own needs an update hard-stop.

All of these are predictable, recoverable outcomes, but they were polluting $exception and the user saw a generic "install failed" with no upgrade hint.

Changes

In src/steps/add-mcp-server-to-clients/clients/claude-code.ts:

  • Parse ${binary} --version and short-circuit with { success: false, unsupported: true } when Claude Code is below the 1.0.88 floor that introduced the plugin subcommand and marketplace flow. No captureException.
  • Before installing, run claude plugin marketplace add PostHog/ai-plugin (the same identifier the Codex client already uses). Tolerate the already added substring so reruns are idempotent.
  • In the plugin install catch block, treat the three known-unsupported substrings — unknown command, needs an update, and not found in any configured marketplace — as quiet { success: false, unsupported: true } returns. Genuine network / unknown failures still flow through captureException exactly as before.

In src/steps/add-mcp-server-to-clients/plugin-client.ts:

  • Add unsupported?: boolean to PluginInstallResult so callers can distinguish "client too old" from a real install failure without parsing strings. No call sites currently branch on it; the field is forward-looking for the TUI upgrade prompt called out in the report.

Test plan

  • pnpm test --testPathPattern=claude-code — 17 cases, including: marketplace registration ordering, already added tolerance, version too low (skips marketplace + install entirely), unparseable --version, each of the three known-unsupported error substrings, unexpected install / marketplace errors still capturing the exception, and the existing already-installed paths.
  • pnpm test --testPathPattern="mcp-installer|add-mcp-server" — 67 cases pass; the existing installPlugins contract and Codex client are unaffected.
  • pnpm build (incl. smoke test) and pnpm lint clean (no new warnings).

LLM context

Authored by an LLM agent acting on a signal report that quantified the failure mode (~325 users on missing marketplace, ~5 on outdated CLIs) and proposed the fix shape. Marketplace identifier PostHog/ai-plugin was verified by reading the live .claude-plugin/plugin.json in https://github.com/PostHog/ai-plugin (plugin name posthog, version 1.1.24) and cross-referenced against the existing Codex client which uses the same string.


Created with PostHog Code

… version

`ClaudeCodeMCPClient.installPlugin()` ran `claude plugin install posthog`
unconditionally and reported every failure through `captureException`. The
dominant failure (~325 distinct users / 30d) was `Plugin "posthog" not
found in any configured marketplace` — the wizard never registered the
marketplace. Secondary clusters hit `unknown command 'install'` (Claude
Code without the `plugin` subcommand) or the built-in `needs an update`
hard-stop on versions below 1.0.88.

This change:
- Parses `${binary} --version` and short-circuits with
  `{ success: false, unsupported: true }` when Claude Code is below the
  1.0.88 floor that introduced the `plugin` subcommand and marketplace
  flow.
- Runs `claude plugin marketplace add PostHog/ai-plugin` before the
  install (matching the identifier the Codex client already uses), and
  tolerates `already added` so reruns are idempotent.
- Treats `unknown command`, `needs an update`, and `not found in any
  configured marketplace` as known unsupported outcomes — quiet
  `{ success: false, unsupported: true }` returns, no `captureException`,
  so error tracking stops being flooded for users whose tooling is
  simply too old.
- Adds unit coverage for each branch (version too low / unparseable,
  marketplace already-added, all three known-unsupported error
  substrings, and unexpected failures that still report).

Net effect: the ~325-user marketplace-not-found cluster is fixed by the
new `plugin marketplace add` step, and the ~5 users on outdated CLIs no
longer pollute `$exception` with the predictable upgrade-required errors.

Generated-By: PostHog Code
Task-Id: 02b404c7-0819-419c-a596-fadc60958675
@github-actions
Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci basic-integration
  • /wizard-ci misc
  • /wizard-ci revenue

Test an individual app:

  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
Show more apps
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci misc/quack-quack
  • /wizard-ci revenue/stripe

Results will be posted here when complete.

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.

0 participants