stacklok / stacklok/toolhive

[Epic] Plugin lifecycle management (RFC THV-0077)

Open
#5,525 0 comments 0 reactions 1 assignee View on GitHub

@JAORMX is already working on this.

Since Jun 15, 2026.

enhancement epic
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

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.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.

RFC: THV-0077 — under review as stacklok/toolhive-rfcs#77.

Cross-repo release gates (the bottleneck)

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 both toolhive 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 #819).

Gate ordering

P0 → GATE-C1 → P1 → GATE-C2 → P2 → P3 → P4
P5a → GATE-C3 → P5b / P5d        (P5c parallel, no core dep)

Serialized spine: P0 → C1 → P1 → C2 → P2 → P3.

Phase checklist

  • Phase 0 — extract artifact-agnostic OCI primitives (oci/artifact) — stacklok/toolhive-core#130 (implementation complete; PR incoming)
  • Phase 1 — oci/plugins package — stacklok/toolhive-core#131
  • Phase 2 — pkg/plugins + pluginsvc build/push/validate + storage migration — stacklok/toolhive#5526
  • Phase 3 — install/list/info/uninstall + MaterializationAdapter (Claude Code + Codex) + groups — stacklok/toolhive#5527
  • Phase 4 — REST API + thv plugin CLI + content preview — stacklok/toolhive#5528
  • Phase 5a — registry/types.Plugin — stacklok/toolhive-core#132
  • Phase 5b — registry provider methods + /v0.1/x/dev.toolhive/plugins routes + PluginsClient — stacklok/toolhive#5529
  • Phase 5c — marketplace generate + signing (cosign/Referrers) — stacklok/toolhive#5530 (parallel, no core dep)
  • Phase 5d — serve plugin catalog surfacing types.Plugin — stacklok/toolhive-registry-server#819

Gaps found in review (2026-07-29)

Items the phase issues originally missed — now folded into #5529 / #819 or listed here for tracking:

  1. PluginLookup is dead code. pluginsvc.WithPluginLookup is never wired in pkg/api/server.go (createDefaultPluginManager), so thv ai-plugin install <plain-name> always 404s. Needs a lazyPluginLookup mirroring lazySkillLookup — covered in #5529.
  2. types.Registry has no Plugins field. The remote provider's side-effect discovery can't see plugins; either extend core (UpstreamRegistry.Plugins — mini GATE-C4) or fetch via PluginsClient like the cached provider does for skills. Decision recorded in #5529.
  3. Registry-server go.mod is behind (toolhive-core v0.0.26, predates types.Plugin) — bump is a prerequisite, covered in #819.
  4. No follow-up tracking for post-v1 scope (needs issues/RFCs, not blocking v1):
    • Managed bundled-MCP execution via dev.toolhive.plugins.requires — deferred to "a follow-up RFC" that doesn't exist yet.
    • Cursor/Copilot/Gemini materialization adapters behind the MaterializationAdapter seam.
    • Kubernetes operator / vMCP story for plugins — Phases 2–4 are local-mode only.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.