Skip to content

Commit ecc41f9

Browse files
feat(registries): adopt official MCP registry v0.1 protocol + standardize defaults
Implements the board-decided design for goal MCP-856: adopt the official Model Context Protocol registry protocol and standardize the shipped default registries. Resolves GH #566 (Pulse v0beta 410) and #567 (remotes-present misclassification) by design. - Official v0.1 parser (internal/registries/official.go): descend the wrapped { server, _meta } envelope; skip deleted/deprecated/non-latest by default; cursor pagination (bounded) with version=latest + search passthrough; versioned User-Agent (#566). Tolerates camelCase + snake_case wire fields. - Per-entry classification (the #567 root fix): packages[] => stdio (InstallCmd set, URL empty), remotes[] => remote (URL set), hybrid => prefer the package and keep the remote as ConnectURL. Never "remotes present => remote". - Curated built-in 'reference' source (reference.go): @modelcontextprotocol servers shipped in-binary so the basics stay discoverable offline (servers#3047). - Default-registry rewire (config.go): add Official (primary, no key) + Reference; keep Docker MCP catalog; demote Pulse + Smithery to opt-in RequiresKey; drop Azure-demo, mcp.run, mcpstore, Fleur, remote-mcp-servers. Remove their bespoke parsers and all constructServerURL URL synthesis. - Cross-surface consistency regression (server/consistency_official_test.go): packages-only => stdio, remotes-only => http identical across REST + CLI. TDD: golden fixture + parser/classification/pagination/reference unit tests. Local: build, gofmt, golangci-lint (0 issues), go test ./internal/... -race, and test-api-e2e.sh (65/65, validated against the live official registry) green. Related #566 Related #567 Co-Authored-By: Paperclip <noreply@paperclip.ing>
1 parent 33bb6e3 commit ecc41f9

13 files changed

Lines changed: 1053 additions & 799 deletions

internal/config/config.go

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -840,13 +840,22 @@ func DefaultDockerIsolationConfig() *DockerIsolationConfig {
840840
func DefaultRegistries() []RegistryEntry {
841841
return []RegistryEntry{
842842
{
843-
ID: "pulse",
844-
Name: "Pulse MCP",
845-
Description: "Browse and discover MCP use-cases, servers, clients, and news",
846-
URL: "https://www.pulsemcp.com/",
847-
ServersURL: "https://api.pulsemcp.com/v0beta/servers",
848-
Tags: []string{"verified"},
849-
Protocol: "custom/pulse",
843+
ID: "official",
844+
Name: "Official MCP Registry",
845+
Description: "The official Model Context Protocol server registry (zero-config, no key required)",
846+
URL: "https://registry.modelcontextprotocol.io/",
847+
ServersURL: "https://registry.modelcontextprotocol.io/v0.1/servers",
848+
Tags: []string{"verified", "official"},
849+
Protocol: "modelcontextprotocol/registry",
850+
},
851+
{
852+
ID: "reference",
853+
Name: "Reference Servers",
854+
Description: "Curated @modelcontextprotocol reference servers, shipped built-in for offline discovery",
855+
URL: "https://github.com/modelcontextprotocol/servers",
856+
ServersURL: "builtin://reference",
857+
Tags: []string{"verified", "official", "reference"},
858+
Protocol: "builtin/reference",
850859
},
851860
{
852861
ID: "docker-mcp-catalog",
@@ -858,31 +867,24 @@ func DefaultRegistries() []RegistryEntry {
858867
Protocol: "custom/docker",
859868
},
860869
{
861-
ID: "fleur",
862-
Name: "Fleur",
863-
Description: "Fleur is the app store for Claude",
864-
URL: "https://www.fleurmcp.com/",
865-
ServersURL: "https://raw.githubusercontent.com/fleuristes/app-registry/refs/heads/main/apps.json",
870+
ID: "pulse",
871+
Name: "Pulse MCP",
872+
Description: "Browse and discover MCP use-cases, servers, clients, and news (opt-in: requires an API key)",
873+
URL: "https://www.pulsemcp.com/",
874+
ServersURL: "https://api.pulsemcp.com/v0.1/servers",
866875
Tags: []string{"verified"},
867-
Protocol: "custom/fleur",
868-
},
869-
{
870-
ID: "azure-mcp-demo",
871-
Name: "Azure MCP Registry Demo",
872-
Description: "A reference implementation of MCP registry using Azure API Center",
873-
URL: "https://demo.registry.azure-mcp.net/",
874-
ServersURL: "https://demo.registry.azure-mcp.net/v0/servers",
875-
Tags: []string{"verified", "demo", "azure", "reference"},
876-
Protocol: "mcp/v0",
876+
Protocol: "custom/pulse",
877+
RequiresKey: true,
877878
},
878879
{
879-
ID: "remote-mcp-servers",
880-
Name: "Remote MCP Servers",
881-
Description: "Community-maintained list of remote Model Context Protocol servers",
882-
URL: "https://remote-mcp-servers.com/",
883-
ServersURL: "https://remote-mcp-servers.com/api/servers",
884-
Tags: []string{"verified", "community", "remote"},
885-
Protocol: "custom/remote",
880+
ID: "smithery",
881+
Name: "Smithery",
882+
Description: "Smithery MCP server registry (opt-in: requires an API key)",
883+
URL: "https://smithery.ai/",
884+
ServersURL: "https://api.smithery.ai/servers",
885+
Tags: []string{"verified"},
886+
Protocol: "modelcontextprotocol/registry",
887+
RequiresKey: true,
886888
},
887889
}
888890
}

internal/registries/integration_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func TestSearchServersIntegration(t *testing.T) {
131131

132132
// TestCompleteWorkflow demonstrates the intended usage pattern
133133
func TestCompleteWorkflow(t *testing.T) {
134-
// Set up default registries (as per user requirements: pulse, docker-mcp-catalog, fleur)
134+
// Set up default registries (official + reference, Docker, Pulse opt-in)
135135
cfg := config.DefaultConfig()
136136
SetRegistriesFromConfig(cfg)
137137

@@ -146,8 +146,9 @@ func TestCompleteWorkflow(t *testing.T) {
146146
t.Error("expected default registries, got none")
147147
}
148148

149-
// Verify we have the expected default registries (pulse, docker-mcp-catalog, fleur)
150-
expectedIDs := []string{"pulse", "docker-mcp-catalog", "fleur"}
149+
// Verify we have the expected default registries (official + reference
150+
// primary, Docker kept, Pulse opt-in) per MCP-865.
151+
expectedIDs := []string{"official", "reference", "docker-mcp-catalog", "pulse"}
151152
found := make(map[string]bool)
152153

153154
for _, reg := range registries {

internal/registries/new_parsers_test.go

Lines changed: 0 additions & 173 deletions
This file was deleted.

0 commit comments

Comments
 (0)