Desktop Cowork: RemotePluginManager removes 3rd-party GitHub marketplace plugins on every sync

Status Fixed / completed
Reported on v2.1.81
Maintainer reply None cached
Activity 8 comments · opened Mar 24, 2026 · closed Apr 2, 2026

Summary

Claude Desktop (Cowork mode) removes all plugins from third-party GitHub-sourced marketplaces after every restart. The RemotePluginManager.syncPlugins() cleanup marks them as NOT_AVAILABLE because it only protects source: "manual" marketplaces, not source: "github" ones.

Reproduction

  1. Add a third-party GitHub marketplace in Claude Desktop (e.g., cogni-work/insight-wave with 14 plugins)
  2. Install plugins from that marketplace in Cowork mode
  3. Restart Claude Desktop
  4. All plugins from the marketplace are gone from the UI

Log evidence (~/Library/Logs/Claude/main.log)

20:58:27-49  [CustomPlugins] installPlugin: remote API install succeeded for plugin cogni-*@insight-wave (source=remote, mode=ccd)
             ... all 14 plugins installed successfully ...
20:59:11     [remoteMarketplaceMigration] marketplace_migration.invoked
20:59:12     [RemotePluginManager] Starting remote plugins sync
20:59:12     [PluginsFetcher] fetchAutoInstalledPlugins: 0 plugins
20:59:14     [RemotePluginManager] Removed 14 user-installed plugins set to NOT_AVAILABLE
20:59:15     [RemotePluginManager] Removed 14 user-installed plugins set to NOT_AVAILABLE

Root cause

In RemotePluginManager._syncPlugins(), user-installed plugins are checked against Anthropic's remote catalog. Plugins not found in the catalog are removed unless they belong to a source: "manual" marketplace:

// Protection set only includes "manual" marketplaces
const j = featureFlag("720735283")
  ? new Set(serverMarketplaces.filter(z => z.source === "manual").map(z => z.name))
  : new Set;

// Plugins from "github" marketplaces are NOT protected → deleted
const W = userPlugins.filter(V =>
    !remoteCatalog.has(V.id) &&
    !remoteCatalogByKey.has(key(V)) &&
    !(V.marketplaceName && j.has(V.marketplaceName))  // "github" !== "manual"
);

Third-party marketplaces added via source: "github" (the standard way to add a marketplace) are not included in the protection set j, so their plugins are always removed during sync.

State after removal

  • ~/Library/.../cowork_plugins/installed_plugins.json: { "plugins": {} } — emptied by removal
  • ~/Library/.../cowork_plugins/cache/insight-wave/: All 14 plugin caches still exist (files not cleaned)
  • ~/Library/.../cowork_settings.json: enabledPlugins still has all 14 entries (stale)

Expected behavior

Plugins from any user-added marketplace (source: "github", source: "manual", etc.) should be protected from the NOT_AVAILABLE cleanup. Only plugins that were pushed from Anthropic's server and are no longer available should be removed.

Workaround

Use Claude Code CLI (claude plugin install <name>@<marketplace>) instead of the Desktop Cowork GUI. CLI-installed plugins use the global ~/.claude/plugins/installed_plugins.json and are not subject to RemotePluginManager sync.

Environment

  • Claude Desktop: latest (March 2026)
  • Claude Code CLI: 2.1.81
  • macOS (Darwin 25.3.0)
  • Affected marketplace: cogni-work/insight-wave (14 plugins), but likely affects all GitHub-sourced third-party marketplaces

View original on GitHub ↗

8 Comments

sdh07 · 5 months ago

Update: CLI workaround does not make plugins visible in Desktop

The suggested workaround ("use Claude Code CLI to install plugins") does not bridge plugins into Claude Desktop Cowork mode. CLI and Desktop use completely separate plugin stores:

| | CLI | Desktop |
|---|---|---|
| Installed plugins | ~/.claude/plugins/installed_plugins.json | ~/Library/Application Support/Claude/local-agent-mode-sessions/<account>/<org>/cowork_plugins/installed_plugins.json |
| Plugin reader | Reads ~/.claude/plugins/ directly | LocalPluginsReader — separate path |
| Marketplace sync | None — local only | RemotePluginManager — syncs with Anthropic backend |

Additional log evidence (2026-03-25)

After installing all 14 plugins via CLI and restarting Desktop:

08:04:32 [LocalPluginsReader] Found 0 local plugins
08:04:42 [NativeMarketplaceReader] Found 1 marketplace(s)
08:04:46 [CustomPlugins] Merged 14 local + 18 remote = 32 total plugins
08:04:53 [remoteMarketplaceOps] removeMarketplaceViaRemote name=insight-wave backendId=marketplace_01H6rvW76AV9iqbLDay4Kd7R
08:04:53 [LocalPluginsReader] Found 0 local plugins

Desktop actively removes the marketplace via removeMarketplaceViaRemote on every startup, regardless of CLI installation state.

Workaround status

  • CLI: Plugins work correctly (confirmed with 14 insight-wave plugins)
  • Desktop Cowork: No known workaround — source: "github" marketplaces are deleted on sync, and CLI-installed plugins are not visible to Desktop's LocalPluginsReader

Attempted alternatives

  • source: "manual" — rejected by settings.json schema validation (not a valid source type)
  • source: "settings" (inline manifest) and source: "directory" (local path) — available in schema but untested; unlikely to help since the Desktop RemotePluginManager sync logic checks z.source === "manual" which is an internal categorization, not the extraKnownMarketplaces source type
sdh07 · 5 months ago

Marketplace-Side Audit: Confirmed Not a Configuration Issue

I ran a comprehensive automated audit of the cogni-work/insight-wave marketplace to rule out any configuration defects on our side. Result: zero issues found. This confirms the bug is in Claude Code's RemotePluginManager._syncPlugins() logic.

What Was Checked

| Check | Result |
|-------|--------|
| marketplace.json schema compliance ($schema, required fields) | PASS |
| 12 plugins registered, 0 duplicates | PASS |
| All source paths (./cogni-{name}) resolve to existing directories | PASS |
| All 12 directories contain valid .claude-plugin/plugin.json | PASS |
| Plugin name consistent across marketplace.json, plugin.json, and directory name | PASS |
| All 12 versions are valid semver (range: 0.1.3 – 1.8.4) | PASS |
| No broken cross-references or missing fields | PASS |
| MCP config correctly scoped (only cogni-visual/.mcp.json for Excalidraw) | PASS |
| Non-plugin directory (cogni-portfolio-evals) correctly excluded | PASS |
| GitHub repo structure (public, main branch, .github/ workflows) | PASS |

Methodology

  • Programmatic JSON validation across all 12 plugin.json files + marketplace.json
  • Cross-referenced names, paths, and versions automatically
  • Verified every source path resolves and contains the expected .claude-plugin/plugin.json
  • Checked for duplicates, schema violations, and broken references

Conclusion

There is no marketplace-side change that can mitigate this. The _syncPlugins() method needs to protect source: "github" marketplaces the same way it protects source: "manual" ones.

tmargolis · 5 months ago

Confirming this on macOS 15, Claude Desktop 1.1.9134 (87a63a, 2026-03-26), with a single-plugin GitHub marketplace (tmargolis/career-navigator).

What the logs show

~/Library/Logs/Claude/main.log shows the install reporting success immediately before the removal:

[CustomPlugins] installPlugin: remote API install succeeded for plugin career-navigator@career-navigator
...
[NativeMarketplaceReader] Uninstalling plugin (native): career-navigator@career-navigator
[NativeMarketplaceReader] No install path found for "career-navigator@career-navigator"; metadata already absent

Session VM never receives the plugin

Even when the install log says succeeded, ~/Library/Logs/Claude/cowork_vm_node.log shows sessions spawning without the plugin mounted. The mounts= list and --plugin-dir flag contain no reference to the plugin:

mounts=9 (career, .claude, .claude/skills, .local-plugins,
.local-plugins/cache/knowledge-work-plugins/cowork-plugin-management/0.2.2/.mcpb-cache,
.cowork-lib, .cowork-perm-req, .cowork-perm-resp, uploads)

Compare to a session from before the regression (same plugin, installed via zip upload) which had 11 mounts including
.local-plugins/marketplaces/local-desktop-app-uploads/career-navigator/.mcpb-cache. So even in the window between
"install succeeded" and the removeMarketplaceViaRemote call, the session VM is already spawning without it.

Workaround confirmed

Zip upload via Desktop app → Plugin Manager works correctly and produces the expected local cache entry. GitHub marketplace sync does not.

Impact on community sharing

The GitHub marketplace path (/plugin marketplace add owner/repo) is the documented, zero-friction way for plugin authors to share with the community — no zip, no manual steps. This bug makes that path completely non-functional in Desktop Cowork. Anyone following the official docs to distribute a plugin is silently broken: installs appear to succeed in the UI, but skills never load. The only working alternative is asking users to download and upload a zip manually, which is a significant barrier for community adoption.

DominicStewart · 5 months ago

Confirmed for me too. Exactly the same issue

jrenaldi79 · 5 months ago

Cross-reference: Detailed filesystem tracing + confirmed workaround

We did extensive filesystem tracing of the install/restart cycle for a third-party GitHub marketplace plugin (jrenaldi79/plugin-marketplace) and confirmed the root cause described here — RemotePluginManager only protects source: "manual" marketplaces, not source: "github".

Full analysis with filesystem traces, directory structures, and 5 failed workaround attempts: https://github.com/anthropics/claude-code/issues/40600#issuecomment-4159901483

Confirmed workaround (new finding): While RemotePluginManager wipes the rpm/ path on every restart, the cowork_plugins/ path managed by LocalPluginsReader is not subject to the same wipe. Manually populating these four locations makes a third-party marketplace plugin persist across restarts:

  1. cowork_plugins/cache/<marketplace>/<plugin>/<version>/ — plugin files
  2. cowork_plugins/.install-manifests/<plugin>@<marketplace>.json — SHA256 file hashes
  3. cowork_plugins/installed_plugins.json — version, installPath, gitCommitSha (same schema as official plugins)
  4. cowork_settings.json enabledPlugins entry

This mirrors exactly how knowledge-work-plugins (Anthropic official marketplace) persists. Tested across multiple restarts — survives every time.

The real fix is still needed in the sync logic to protect source: "github" marketplaces, but this workaround unblocks third-party plugin authors in the meantime.

jrenaldi79 · 5 months ago

For anyone hitting this: I built an install script that works around the RemotePluginManager wipe by writing directly to cowork_plugins/ (the LocalPluginsReader path that persists). It also sets up a daily auto-update scheduled task.

Full writeup and script: https://github.com/anthropics/claude-code/issues/40600#issuecomment-4161143697
Repo: https://github.com/jrenaldi79/plugin-marketplace

sdh07 · 5 months ago

The issue seems to be closed from my perspective (there is a different one now with synchronizing to updated versions).

github-actions[bot] · 4 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.