You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add plugin lifecycle management to ToolHive. A plugin is the "bundle of primitives" unit pioneered by Claude Code — a directory declared by a .claude-plugin/plugin.json manifest bundling slash commands, subagents, Agent Skills, hooks, MCP server configs, and LSP servers. ToolHive will let users build a plugin directory into a reproducible, content-addressable OCI artifact, push it to any OCI registry, install it (registry name, OCI reference, or git:// URL), and list/info/uninstall it — reusing the registry, OCI, groups, and storage infrastructure that already serves skills and MCP servers.
Two-layer split. The design splits cleanly into:
a client-agnostic distribution layer (build → OCI → push → catalog → pull → verify → inventory) — the bulk of the value, identical for every client; and
a per-client materialization layer (turning a verified, pulled bundle into something a specific client loads), behind a stable MaterializationAdapter seam.
v1 scope. Materialization is implemented for the two clients that consume the .claude-plugin/plugin.json family: Claude Code (in-place skills-directory install, full component set, no config mutation) and Codex (cache install + ~/.codex/config.toml mutation, reduced component set — warns on dropped commands/agents). Cursor/Copilot/Gemini adapters are future work behind the seam. Bundled MCP execution is deferred: v1 packages .mcp.json verbatim but does not run/proxy/rewrite it, records dev.toolhive.plugins.requires (resolves nothing), and reports declared MCP servers as "declared; NOT managed by ToolHive." The managed model via requires references is a follow-up RFC.
Every toolhive-core change is a separate Go module that must be merged → tagged → released before toolhive / toolhive-registry-server can bump go.mod and build against it. Three core release gates:
GATE-C1 — tag toolhive-core after shared OCI primitives (Phase 0); bump toolhive.
GATE-C2 — tag toolhive-core after oci/plugins (Phase 1); bump toolhive. Nothing in Phase 2 compiles before this.
GATE-C3 — tag toolhive-core after registry/types.Plugin (Phase 5a); bump bothtoolhive and toolhive-registry-server to the same tag. ✅ types.Plugin is in every core tag ≥ v0.0.28; toolhive is on v0.0.35, registry-server still needs its bump (tracked in chore(deps): update ghcr.io/stacklok/toolhive docker tag to v0.0.48 #819).
Overview
Add plugin lifecycle management to ToolHive. A plugin is the "bundle of primitives" unit pioneered by Claude Code — a directory declared by a
.claude-plugin/plugin.jsonmanifest bundling slash commands, subagents, Agent Skills, hooks, MCP server configs, and LSP servers. ToolHive will let users build a plugin directory into a reproducible, content-addressable OCI artifact, push it to any OCI registry, install it (registry name, OCI reference, orgit://URL), and list/info/uninstall it — reusing the registry, OCI, groups, and storage infrastructure that already serves skills and MCP servers.Two-layer split. The design splits cleanly into:
MaterializationAdapterseam.v1 scope. Materialization is implemented for the two clients that consume the
.claude-plugin/plugin.jsonfamily: Claude Code (in-place skills-directory install, full component set, no config mutation) and Codex (cache install +~/.codex/config.tomlmutation, reduced component set — warns on dropped commands/agents). Cursor/Copilot/Gemini adapters are future work behind the seam. Bundled MCP execution is deferred: v1 packages.mcp.jsonverbatim but does not run/proxy/rewrite it, recordsdev.toolhive.plugins.requires(resolves nothing), and reports declared MCP servers as "declared; NOT managed by ToolHive." The managed model viarequiresreferences is a follow-up RFC.RFC: THV-0077 — under review as stacklok/toolhive-rfcs#77.
Cross-repo release gates (the bottleneck)
Every
toolhive-corechange is a separate Go module that must be merged → tagged → released beforetoolhive/toolhive-registry-servercan bumpgo.modand build against it. Three core release gates:toolhive-coreafter shared OCI primitives (Phase 0); bumptoolhive.toolhive-coreafteroci/plugins(Phase 1); bumptoolhive. Nothing in Phase 2 compiles before this.toolhive-coreafterregistry/types.Plugin(Phase 5a); bump bothtoolhiveandtoolhive-registry-serverto the same tag. ✅types.Pluginis in every core tag ≥ v0.0.28; toolhive is on v0.0.35, registry-server still needs its bump (tracked in chore(deps): update ghcr.io/stacklok/toolhive docker tag to v0.0.48 #819).Gate ordering
Serialized spine: P0 → C1 → P1 → C2 → P2 → P3.
Phase checklist
oci/artifact) — [plugins] Phase 0: extract artifact-agnostic OCI primitives (THV-0077) toolhive-core#130 (implementation complete; PR incoming)oci/pluginspackage — [plugins] Phase 1: oci/plugins package (THV-0077) toolhive-core#131pkg/plugins+pluginsvcbuild/push/validate + storage migration — [plugins] Phase 2: pkg/plugins + pluginsvc build/push/validate + storage migration (THV-0077) #5526thv pluginCLI + content preview — [plugins] Phase 4: REST API + thv plugin CLI + content preview (THV-0077) #5528registry/types.Plugin— [plugins] Phase 5a: registry/types.Plugin (THV-0077) toolhive-core#132/v0.1/x/dev.toolhive/pluginsroutes + PluginsClient — [plugins] Phase 5b: registry provider methods + catalog routes + PluginsClient (THV-0077) #5529marketplace generate+ signing (cosign/Referrers) — [plugins] Phase 5c: marketplace generate + signing (THV-0077) #5530 (parallel, no core dep)types.Plugin— [plugins] Phase 5d: serve plugin catalog surfacing types.Plugin (THV-0077) toolhive-registry-server#819Gaps found in review (2026-07-29)
Items the phase issues originally missed — now folded into #5529 / #819 or listed here for tracking:
PluginLookupis dead code.pluginsvc.WithPluginLookupis never wired inpkg/api/server.go(createDefaultPluginManager), sothv ai-plugin install <plain-name>always 404s. Needs alazyPluginLookupmirroringlazySkillLookup— covered in [plugins] Phase 5b: registry provider methods + catalog routes + PluginsClient (THV-0077) #5529.types.Registryhas noPluginsfield. The remote provider's side-effect discovery can't see plugins; either extend core (UpstreamRegistry.Plugins— mini GATE-C4) or fetch viaPluginsClientlike the cached provider does for skills. Decision recorded in [plugins] Phase 5b: registry provider methods + catalog routes + PluginsClient (THV-0077) #5529.types.Plugin) — bump is a prerequisite, covered in chore(deps): update ghcr.io/stacklok/toolhive docker tag to v0.0.48 #819.dev.toolhive.plugins.requires— deferred to "a follow-up RFC" that doesn't exist yet.MaterializationAdapterseam.