Documentation
¶
Overview ¶
Package catalog provides the MCP server catalog behind `gridctl search` and `gridctl add`: a small embedded set of curated entries plus an on-demand, disk-cached consumer of the official MCP Registry API (registry.modelcontextprotocol.io, API v0.1). Entries map onto config.MCPServer blocks through Entry.Server; nothing in this package touches stack.yaml itself.
Index ¶
Constants ¶
const ( TierCurated = "curated" TierRegistry = "registry" )
Source tiers. Curated entries ship embedded in the binary and are vetted by hand; registry entries come from the official MCP Registry, which does no code scanning, and must not be presented as vetted.
const ( StatusActive = "active" StatusDeprecated = "deprecated" )
Entry statuses mirror the MCP Registry lifecycle. Deleted entries are filtered out before they reach callers, so only these two appear.
const ( InstallImage = "image" // container image (OCI) InstallCommand = "command" // local process (npx, uvx, ...) InstallURL = "url" // external remote server )
Install spec types.
Variables ¶
var ErrNotFound = errors.New("server not found in the MCP Registry")
ErrNotFound reports a server name the MCP Registry does not know.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client queries the MCP Registry with an on-disk response cache. The zero value is not usable; construct with NewClient.
func NewClient ¶
func NewClient() *Client
NewClient returns a registry client with the production base URL and the shared cache directory under ~/.gridctl/cache/catalog.
func (*Client) Get ¶
Get fetches the latest version of one server by its full registry name (e.g. "io.github.user/weather"). Returns ErrNotFound for unknown names and for deleted entries.
func (*Client) Search ¶
Search queries /v0.1/servers with the substring query, following cursors up to a small page cap. Results convert to entries with deleted servers filtered out. stale reports that the returned entries came from an expired cache after a network failure; the error is non-nil only when neither the network nor any cache could serve the query.
type Entry ¶
type Entry struct {
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description"`
// Tier is TierCurated or TierRegistry, assigned at load time.
Tier string `json:"tier,omitempty"`
// Namespace links a curated entry to its MCP Registry name so merged
// search results dedupe (the curated entry wins). Empty for registry
// entries, whose Name is already the registry name.
Namespace string `json:"namespace,omitempty"`
Homepage string `json:"homepage,omitempty"`
Repository string `json:"repository,omitempty"`
// Status is StatusActive or StatusDeprecated. Empty means active.
Status string `json:"status,omitempty"`
Install Install `json:"install"`
Inputs []Input `json:"inputs,omitempty"`
// Unsupported records the registry package type when no supported
// install shape could be derived (mcpb, nuget, cargo, templated URLs).
// Such entries still appear in search; Entry.Server rejects them with
// UnsupportedInstallError.
Unsupported string `json:"unsupported,omitempty"`
// Reserved metadata: parsed and preserved for later enforcement
// features (approval gates, trifecta policy, per-call costs), never
// acted on today.
Permissions *Permissions `json:"permissions,omitempty"`
RequiresApproval *bool `json:"requires_approval,omitempty"`
CostPerCall *float64 `json:"cost_per_call,omitempty"`
}
Entry is one installable catalog server. Curated entries use a short install name ("github"); registry entries use the full reverse-DNS registry name ("io.github.user/weather").
func Curated ¶
Curated returns the embedded curated entries, sorted by name. Callers must not mutate the returned slice.
func FilterCurated ¶
FilterCurated returns the curated entries matching query as a case-insensitive substring of the name, title, or description. An empty query returns everything.
func FindCurated ¶
FindCurated returns the curated entry with the given install name, matched case-insensitively.
func Merge ¶
Merge combines curated and registry results: curated entries first, then registry entries sorted by name, dropping registry entries a curated entry already covers (matched by the curated entry's Namespace).
func (Entry) InstallLabel ¶
InstallLabel describes how the entry runs, for plans and tables: "stdio via npx", "container image", "http url".
func (Entry) Server ¶
Server assembles the config.MCPServer block for this entry. name is the stack server name; values maps input names to their final strings, either literals or ${var:KEY} references (the caller resolves prompting and vault routing first). Optional inputs with empty values are omitted.
func (Entry) ServerName ¶
ServerName derives the stack server name for the entry: the part after the registry namespace slash, with characters outside [a-zA-Z0-9_-] collapsed to dashes.
type Input ¶
type Input struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Required bool `json:"required,omitempty"`
// Secret values are masked when prompted and routed into the variable
// store as ${var:KEY} references rather than written literally.
Secret bool `json:"secret,omitempty"`
// Arg inputs are appended to the install command as positional
// arguments instead of set in env.
Arg bool `json:"arg,omitempty"`
// Auth inputs feed the install's auth block (bearer token or header
// value) instead of env. Only meaningful on url installs.
Auth bool `json:"auth,omitempty"`
Default string `json:"default,omitempty"`
Placeholder string `json:"placeholder,omitempty"`
Choices []string `json:"choices,omitempty"`
// Format hints the value shape: "string", "number", "boolean", or
// "filepath" (the MCP Registry input vocabulary).
Format string `json:"format,omitempty"`
}
Input is one value the user supplies at install time. By default the resolved value lands in the server's env under Name; Arg and Auth inputs land in the command line and the auth block instead.
type Install ¶
type Install struct {
Type string `json:"type"`
// Transport is "stdio", "http", or "sse" (config.MCPServer vocabulary;
// the registry's "streamable-http" is normalized to "http" at load).
Transport string `json:"transport"`
// Container image (type: image).
Image string `json:"image,omitempty"`
Port int `json:"port,omitempty"`
// Local process (type: command). Positional inputs (Input.Arg) are
// appended to this base command in input order.
Command []string `json:"command,omitempty"`
// External remote (type: url).
URL string `json:"url,omitempty"`
// AuthType is "", "bearer", or "header". The value comes from the
// entry's Auth input at install time.
AuthType string `json:"auth_type,omitempty"`
AuthHeader string `json:"auth_header,omitempty"`
}
Install describes how the server runs. Type selects the shape; the other fields belong to exactly one type.
type Permissions ¶
type Permissions struct {
ReadPrivateData bool `json:"read_private_data,omitempty"`
ReadUntrustedPublicData bool `json:"read_untrusted_public_data,omitempty"`
WriteOperation bool `json:"write_operation,omitempty"`
}
Permissions is the reserved trifecta classification (roadmap item 17). Parsed and preserved; no enforcement reads it yet.
type UnsupportedInstallError ¶
type UnsupportedInstallError struct {
// Kind names what was unsupported, e.g. "mcpb", "nuget", "cargo", or
// "templated URL".
Kind string
}
UnsupportedInstallError is returned when an entry cannot be installed because its package type or shape has no stack.yaml mapping.
func (*UnsupportedInstallError) Error ¶
func (e *UnsupportedInstallError) Error() string