The ToolHive Platform common libraries and specifications.
toolhive-core provides stable, well-tested Go utilities with explicit API guarantees for the ToolHive ecosystem. Projects like toolhive, dockyard, toolhive-registry, and toolhive-registry-server depend on this library for shared functionality.
The ToolHive ecosystem spans multiple Go repositories, and several of these projects need to share common utilities. Rather than having projects import internal packages from toolhive (which have no stability guarantees), toolhive-core provides:
- Stability guarantees: Packages follow semantic versioning with explicit API commitments
- Clear maturity levels: Each package is marked as Stable, Beta, or Alpha
- Tested and documented: All packages meet minimum quality standards before inclusion
- Independent versioning: Evolves on its own release cadence, decoupled from
toolhivereleases
| Package | Stability | Description |
|---|---|---|
cel |
Alpha | Generic CEL expression compilation and evaluation |
env |
Stable | Environment variable abstraction with Reader interface |
httperr |
Stable | Wrap errors with HTTP status codes |
logging |
Alpha | Pre-configured *slog.Logger factory with consistent ToolHive defaults |
telemetry/metrics |
Alpha | Shared OTel histogram bucket presets, label-key constants, and emitter-ownership vocabulary |
telemetry/reconcile |
Alpha | Unified operator reconcile metric emitter |
oci/skills |
Alpha | OCI artifact types, media types, and registry operations for skills |
oci/plugins |
Alpha | OCI artifact types, media types, and registry operations for plugins |
authn |
Alpha | Inbound OIDC/JWT bearer-token validation for resource servers |
networking |
Alpha | Outbound HTTP client construction with SSRF egress policy: private-IP/link-local dial blocking, redirect policy, body-capped JSON fetch, endpoint/issuer URL + private-IP validation helpers, and port allocation/validation utilities |
postgres |
Alpha | PostgreSQL connection pool with optional cloud IAM dynamic auth |
redisconn |
Alpha | Lean Redis/Valkey client construction for standalone, cluster, and Sentinel deployments |
redisconn/aws |
Alpha | AWS ElastiCache/MemoryDB IAM credentials for redisconn |
redisconn/azure |
Alpha | Azure Entra ID credentials for redisconn |
redisconn/gcp |
Alpha | GCP Memorystore IAM credentials for redisconn |
redis |
Deprecated | Source-compatible facade; migrate to redisconn and a provider child module |
recovery |
Beta | HTTP panic recovery middleware |
validation/http |
Stable | RFC 7230/8707 compliant HTTP header and URI validation |
validation/group |
Stable | Group name validation |
Each package is marked with a stability level:
| Level | Meaning | API Guarantees |
|---|---|---|
| Stable | Production-ready, fully supported | No breaking changes without major version bump |
| Beta | Feature-complete, may have minor changes | Breaking changes possible with deprecation notice |
| Alpha | Experimental, subject to significant changes | No stability guarantees |
Packages in toolhive-core must meet formal criteria before inclusion. This ensures that shared packages are genuinely reusable, well-tested, and not tied to the internal workings of any specific project.
Packages must provide genuinely reusable value and be designed as reusable from the start. A package that requires knowledge of toolhive internals to use correctly is not a good candidate for graduation.
For small, focused packages with minimal dependencies (e.g., env, errors, validation):
| Criterion | Requirement |
|---|---|
| Production usage | Deployed in production for ≥1 month |
| No internal dependencies | Cannot depend on non-graduated internal packages |
| No global state | No singletons, global variables for state, or init() side effects |
| Test coverage | ≥70% line coverage |
| Documentation | Package-level godoc |
| Approval | GitHub issue approved by one maintainer |
For packages with external dependencies, multiple types, or broader API surface:
| Criterion | Requirement |
|---|---|
| Production usage | Deployed in production for ≥2 months without breaking changes |
| API stability | No breaking changes in the last 2 minor releases |
| Interface design | Uses Go interfaces for dependency injection and testability |
| Error handling | Returns typed errors; no panics except for programming bugs |
| No global state | No singletons, global variables for state, or init() side effects |
| Test coverage | ≥70% line coverage with meaningful assertions |
| Documentation | Package-level godoc with usage examples |
| Linting | Passes golangci-lint with project configuration |
| Minimal dependencies | Only essential external dependencies |
| No circular imports | Must not create import cycles when extracted |
| No internal dependencies | Cannot depend on non-graduated internal packages |
| Stable external deps | External dependencies must be v1.0+ or widely adopted |
| Sponsorship | At least one maintainer sponsors the graduation |
| Approval | RFC or detailed GitHub issue reviewed and approved |
- Proposal: Open a GitHub issue identifying the graduation candidate and proposed track (fast/standard)
- Track determination: Maintainers confirm which track applies based on package complexity
- Evaluation: Assess against the relevant track's criteria
- Approval: Fast track requires one maintainer approval; standard track requires RFC or detailed issue review
- Extraction: Move package to
toolhive-corewith necessary adaptations - Release: Tag a new semver release of
toolhive-core - Migration: Update consuming projects to import from
toolhive-core
toolhive-core follows Semantic Versioning 2.0.0:
- Major (vX.0.0): Breaking API changes
- Minor (v0.X.0): New features, backward-compatible
- Patch (v0.0.X): Bug fixes, backward-compatible
Before creating or pushing a release tag, check out the exact commit to be tagged and run:
./scripts/validate-release.sh <intended-tag>The intended tag must use the module's tag prefix (for example, v1.2.3, redisconn/v1.2.3, or redisconn/aws/v1.2.3). Every required sibling module version must already have an exact module-prefixed release tag available in the local clone; fetch the required previous tags before running the check. The script only inspects local Git state and makes no network calls.
For an auditable preflight result, manually dispatch the Release workflow with the same intended tag and the full 40-character lowercase commit SHA that will receive it. The workflow rejects branch names, tag names, abbreviated SHAs, and uppercase SHAs, verifies that the input resolves to a commit, and checks out that exact commit. Create and push the tag only after the local check and, when used, the manual preflight pass against that SHA.
The tag-triggered Release workflow repeats validation after a tag is pushed. This post-tag check is defense in depth; it detects an invalid release but is not the pre-tag control.
Repository workflows cannot prevent an authorized user from directly pushing a tag without performing the preflight. Access controls and release-operator procedure must enforce the required pre-tag check; the post-tag workflow can only report failure after the tag exists.
Apache-2.0 - See LICENSE for details.