Skip to content

Drop ToolHive registry format support#724

Merged
rdimitrov merged 3 commits intomainfrom
drop-toolhive-format
Apr 20, 2026
Merged

Drop ToolHive registry format support#724
rdimitrov merged 3 commits intomainfrom
drop-toolhive-format

Conversation

@rdimitrov
Copy link
Copy Markdown
Member

Summary

  • Remove the format field and ToolHive format code path entirely — with only the upstream MCP registry format remaining, the field carried no information and added unnecessary complexity
  • Hard-drop the format column from the source DB table via migration 000021
  • Delete the toolhive-core/registry/converters dependency and all toolhive parsing/validation code
  • Remove format from all configs, Helm values, docs, API types, and test infrastructure

What changed

Database: Migration 000021 drops the format column and registry_format_check constraint from the source table. All SQL queries in source.sql updated (8 queries).

Go types removed: SourceFormatToolHive/SourceFormatUpstream constants, Format field from SourceConfig, SourceCreateRequest, SourceInfo, FetchResult, and sourceRow. ProcessInlineSourceData signature simplified from 4 args to 3.

Code paths removed: validateToolhiveFormatAndParse, ValidateInlineDataWithFormat, toolhive branch in ValidateData, format validation in config/service layers, format dispatch in source handlers.

Tests: Deleted testutils_toolhive.go (216 lines) and its test file (347 lines). Replaced toolhive-format test fixtures with upstream equivalents across ~20 test files.

Configs/docs: Removed format: from all example configs, Helm chart values, CI values, and documentation. Regenerated swagger docs.

Net: +267 / -1,601 lines across 68 files.

Backward compatibility

  • YAML configs with a stale format: field are silently ignored (standard Viper behavior)
  • API clients sending "format" in JSON have the field silently dropped (standard Go JSON decoder)
  • format field no longer appears in API responses (SourceInfo)
  • Existing DB sources pointing at toolhive-format external data will fail on next sync with a clear upstream validation error

Test plan

  • task lint-fix — 0 issues
  • task test — all tests pass
  • task build — binary builds
  • Docker compose smoke test: migration 21 applies cleanly, 12 servers sync from upstream file, all API endpoints work
  • DB validation: format column gone, no format constraints, source data correct
  • API response verified: no format field in source responses
  • Sending "format": "toolhive" in API request is silently ignored (201 success)

Fixes #723

🤖 Generated with Claude Code

Remove the `format` field and ToolHive format code path entirely. With
only the upstream MCP registry format remaining, the field carried no
information and added unnecessary complexity.

Database: migration 000021 drops the `format` column and
`registry_format_check` constraint from the `source` table. All SQL
queries updated to remove format references.

Go code: delete `SourceFormatToolHive`/`SourceFormatUpstream` constants,
`Format` field from `SourceConfig`, `SourceCreateRequest`, `SourceInfo`,
and `FetchResult`. Remove the `validateToolhiveFormatAndParse` function,
`ValidateInlineDataWithFormat`, toolhive branch in `ValidateData`, and
`converters` dependency. Simplify `ProcessInlineSourceData` signature.

Tests: delete `testutils_toolhive.go` and its tests, replace
toolhive-format test fixtures with upstream equivalents, update all mock
expectations and struct literals.

Configs/docs: remove `format:` from all example configs, Helm values,
and documentation. Regenerate swagger docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rdimitrov
Copy link
Copy Markdown
Member Author

Implementation Plan

This is the plan that was used to implement this PR.

Context

The registry server supports two data formats: toolhive (legacy) and upstream (standard MCP registry format). The ToolHive format is being deprecated. All data is already stored internally as upstream format (conversion happens at ingest), so the toolhive code path is dead weight.

Approach: Hard-drop format entirely. Remove the format DB column, remove from all API surfaces, config structs, and Go code. With only one format, there's no decision to make. If a second format is ever needed, adding a column back is a trivial migration, and you'd likely want a fresh design anyway.

Phase 1: Database Migration

Create database/migrations/000021_drop_format_column.{up,down}.sql.

Up migration:

ALTER TABLE source DROP CONSTRAINT registry_format_check;
ALTER TABLE source DROP COLUMN format;

Note: Constraint is still named registry_format_check (never renamed in migration 000015).

Down migration:

ALTER TABLE source ADD COLUMN format TEXT;
ALTER TABLE source ADD CONSTRAINT registry_format_check
    CHECK (format IS NULL OR format IN ('toolhive', 'upstream'));

Phase 2: SQL Queries

Remove format from every query in database/queries/source.sql (8 queries: ListSources, GetSource, GetSourceByName, UpsertSource, BulkUpsertConfigSources, InsertSource, UpdateSource, GetAPISourcesByNames).

After editing, run task gen to regenerate sqlc — this automatically removes Format/Formats fields from all generated param/row structs.

Phase 3: Remove Format from Go Types

Area File Changes
Config internal/config/config.go Delete SourceFormatToolHive/SourceFormatUpstream constants, Format field from SourceConfig, format param from validateAPIConfig
API request internal/service/source_types.go Delete Format from SourceCreateRequest
API response internal/service/service.go Delete Format from SourceInfo
Validation internal/service/validation.go Delete format validation block, ValidateInlineDataWithFormat, toolhive fallback logic
Data validator internal/sources/types.go Remove format param from ValidateData, delete validateToolhiveFormatAndParse, remove converters import
Service DB internal/service/db/impl_source.go Delete format from sourceRow, CreateSource, UpdateSource, all buildSourceInfo* helpers, simplify ProcessInlineSourceData signature
Sync state internal/sync/state/db.go Delete formats slice from bulk upsert, remove format from loadSourceConfigFromDB
Source handlers api.go, file.go, git.go, api_upstream.go Remove format checks, remove Format from FetchResult, update NewFetchResult to 2 args
Tags internal/registry/tags.go Update comments removing toolhive references
Doc comments internal/sources/doc.go, internal/registry/doc.go Remove toolhive handler/format references

Phase 4: Remove ToolHive Test Utilities

  • Delete internal/registry/testutils_toolhive.go and testutils_toolhive_test.go
  • Rewrite tags_test.go to use upstream-format test data instead of converters

Phase 5: Update Tests

Remove Format from struct literals across ~20 test files. Remove toolhive-specific test cases from types_test.go, validation_test.go. Replace toolhive-format inline JSON fixtures with valid upstream-format JSON. Update mock expectations (ValidateData 1 arg, NewFetchResult 2 args, ProcessInlineSourceData 3 args). Replace registry.NewTestToolHiveRegistry calls with registry.NewTestUpstreamRegistry in sync tests.

Phase 6: Update Configs, Charts, and Docs

Remove format: lines from all example configs (15 files), Helm chart values and CI values, and documentation (configuration.md, deployment-*.md, README.md, examples/README.md).

Phase 7: Dependency Cleanup and Verification

  • Remove converters imports, go mod tidy
  • task gentask docstask lint-fixtask testtask build

Backward Compatibility

  • YAML configs with format: field: Viper silently ignores unknown fields
  • API clients sending "format" in JSON: Go's json.Decoder silently ignores unknown fields
  • API responses: format field disappears from responses
  • Existing DB sources pointing at toolhive-format external data: next sync fails with a clear upstream validation error
  • Helm chart users with format: in custom values: silently ignored

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 40.90909% with 13 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@faf30bc). Learn more about missing BASE report.

Files with missing lines Patch % Lines
internal/service/mocks/mock_service.go 0.00% 4 Missing ⚠️
internal/sources/mocks/mock_registry_handler.go 0.00% 4 Missing ⚠️
internal/config/config.go 0.00% 2 Missing ⚠️
internal/service/db/impl_source.go 0.00% 2 Missing ⚠️
internal/sync/state/db.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #724   +/-   ##
=======================================
  Coverage        ?   60.28%           
=======================================
  Files           ?      106           
  Lines           ?    10244           
  Branches        ?        0           
=======================================
  Hits            ?     6176           
  Misses          ?     3527           
  Partials        ?      541           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

rdimitrov added a commit that referenced this pull request Apr 17, 2026
The `examples/config-docker-with-managed.yaml` example was added with a
`format: upstream` field that is being removed by #724 (drop ToolHive
registry format support). Drop the field here to avoid a merge conflict
with that branch — regardless of merge order.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdimitrov rdimitrov merged commit 127c8c8 into main Apr 20, 2026
15 checks passed
@rdimitrov rdimitrov deleted the drop-toolhive-format branch April 20, 2026 11:59
rdimitrov added a commit that referenced this pull request Apr 20, 2026
Three test fixtures still declared their inline file data in the old
ToolHive format (`{"servers":{}}` at root), which has been unsupported
since #724. They now emit the upstream format
(`{"meta":{...},"data":{"servers":[...]}}`) and include a placeholder
server entry because the validator rejects empty server lists.

Fixes the `TestAuthzIntegration_SourceCRUD` integration failure and the
`admin_claims_test.go` suite — both were failing with "meta is required"
/ "data is required" before, and then "upstream registry must contain
at least one server" once the envelope was added.
rdimitrov added a commit that referenced this pull request Apr 20, 2026
Three test fixtures still declared their inline file data in the old
ToolHive format (`{"servers":{}}` at root), which has been unsupported
since #724. They now emit the upstream format
(`{"meta":{...},"data":{"servers":[...]}}`) and include a placeholder
server entry because the validator rejects empty server lists.

Fixes the `TestAuthzIntegration_SourceCRUD` integration failure and the
`admin_claims_test.go` suite — both were failing with "meta is required"
/ "data is required" before, and then "upstream registry must contain
at least one server" once the envelope was added.
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.

As a developer, I want to remove ToolHive format support so that the codebase has a single data format path

3 participants