-
Notifications
You must be signed in to change notification settings - Fork 132
fea: Registry API Data Source #2189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Daniele Martinoli <[email protected]>
Signed-off-by: Daniele Martinoli <[email protected]>
Signed-off-by: Daniele Martinoli <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main stacklok/toolhive#2189 +/- ##
==========================================
+ Coverage 53.45% 53.85% +0.39%
==========================================
Files 229 234 +5
Lines 29375 29739 +364
==========================================
+ Hits 15703 16015 +312
- Misses 12542 12575 +33
- Partials 1130 1149 +19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Signed-off-by: Daniele Martinoli <[email protected]>
@claude provide a review. During the review, you must take into account the existing flows of the operator and how it synchronizes its data sources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for fetching MCP registry data from API endpoints, enabling dynamic synchronization from remote registries via HTTP/HTTPS.
Key Changes:
- Added API source handler with automatic format detection (ToolHive vs Upstream MCP Registry)
- Implemented HTTP client for API operations with timeout and error handling
- Added comprehensive unit and integration tests for API source functionality
Reviewed Changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
cmd/thv-operator/api/v1alpha1/mcpregistry_types.go |
Added APISource type and RegistrySourceTypeAPI constant to support API-based registry sources |
cmd/thv-operator/pkg/sources/api.go |
Main API source handler with format detection and delegation logic |
cmd/thv-operator/pkg/sources/api_toolhive.go |
ToolHive-specific API handler for fetching and converting registry data |
cmd/thv-operator/pkg/sources/api_upstream.go |
Upstream MCP Registry API handler (validation only, Phase 2 not implemented) |
cmd/thv-operator/pkg/sources/api_types.go |
Type aliases for ToolHive Registry API response types |
cmd/thv-operator/pkg/httpclient/client.go |
HTTP client implementation with context support and standard headers |
cmd/thv-operator/pkg/httpclient/types.go |
HTTPError type for structured error handling |
cmd/thv-operator/pkg/sources/factory.go |
Factory updated to create API source handlers |
deploy/charts/operator-crds/crds/toolhive.stacklok.dev_mcpregistries.yaml |
CRD updated with API source configuration |
docs/operator/crd-api.md |
Documentation for API source configuration |
cmd/thv-operator/REGISTRY.md |
User guide for API source configuration |
examples/operator/mcp-registries/*.yaml |
Example configurations for API source usage |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Phase 1 (ToolHive API): | ||
- /v1/registry/servers - List all servers (single response, no pagination) | ||
- /v1/registry/servers/{name} - Get specific server (future) | ||
- /v1/registry/info - Get registry metadata (future) | ||
Phase 2 (Upstream MCP Registry API): | ||
- /v0/servers - List all servers with pagination |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CRD documentation references /v1/registry/*
paths for ToolHive API, but the implementation uses /v0/*
paths. Update to match the actual implementation.
Phase 1 (ToolHive API): | |
- /v1/registry/servers - List all servers (single response, no pagination) | |
- /v1/registry/servers/{name} - Get specific server (future) | |
- /v1/registry/info - Get registry metadata (future) | |
Phase 2 (Upstream MCP Registry API): | |
- /v0/servers - List all servers with pagination | |
Supported API endpoints: | |
- /v0/servers - List all servers (with pagination) |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generated code, will be committed as part of previous change
Claude encountered an error —— View job
I'll analyze this and get back to you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is great. We need a new version to bump the CRDs. Most of the review comments are just comments and most of them can be addressed as follow ups so we can keep moving.
|
||
const ( | ||
// DefaultTimeout is the default timeout for HTTP requests | ||
DefaultTimeout = 30 * time.Second |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems...a lot :-)
} | ||
|
||
// Read response body | ||
body, err := io.ReadAll(resp.Body) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use a LimitReader here to protect from too big responses that might DoS the client (Maybe 100MiB)
|
||
// Set headers | ||
req.Header.Set("User-Agent", UserAgent) | ||
req.Header.Set("Accept", "application/json") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think if there can be any issues if we later request the openapi.yaml (I know it's not implemented yet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for server validation purposes, you mean?
have you looked at how we identify the type of server in this code? e.g. querying /info fot toolhive or the /openapi.yaml for upstream
baseURL := mcpRegistry.Spec.Source.API.Endpoint | ||
|
||
// Remove trailing slash | ||
if len(baseURL) > 0 && baseURL[len(baseURL)-1] == '/' { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TrimSuffix ?
} | ||
|
||
// Fetch detailed information for each server | ||
for _, serverSummary := range response.Servers { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that since we won't keep the toolhive format around for more it doesn't make sense to parallelize this? Maybe worth adding a TODO?
if timeout == 0 { | ||
timeout = DefaultTimeout | ||
} | ||
return &DefaultClient{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the default client use TLS? There is a NewHttpClientBuilder
in the codebase that could be used for this..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw this could be a follow-up and I'll be happy to do it (I haven't contributed much to the registry effort lately..sorry..)
Signed-off-by: Daniele Martinoli <[email protected]>
Signed-off-by: Daniele Martinoli <[email protected]>
Fixes #2104
Changes
type: api
Postponed requirements