catalog

package
v0.22.140 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package catalog ships clawtool's built-in source catalog.

Per ADR-008, the catalog is the fast path for `clawtool source add <name>`. Each entry knows the canonical package, runtime, required env vars, and auth flow hint for one well-known MCP source server. The catalog is a single TOML file embedded in the binary — no network calls during a `source add`, no first-run download, fully offline-capable.

External catalog federation (Docker MCP Catalog, MCP Registry, Smithery) is a planned extension; this package currently exposes only the built-in.

Index

Constants

View Source
const DefaultRegistryURL = "https://registry.modelcontextprotocol.io"

DefaultRegistryURL is the official MCP Registry base URL (https://registry.modelcontextprotocol.io). This endpoint replaced the third-party server list previously curated in modelcontextprotocol/servers (PR #3950, 2026-04-14): the registry is now the canonical discovery surface for MCP servers across the ecosystem.

The clawtool catalog still ships an embedded `builtin.toml` for offline / hot-path source-add — the registry is a federated overlay, NOT a replacement. ProbeRegistry below is the foundation for future ticks that surface registry-only entries via `clawtool source registry` or fall back to the registry when a bare name misses the builtin catalog.

View Source
const DefaultSmitheryRegistryURL = "https://registry.smithery.ai"

DefaultSmitheryRegistryURL is the Smithery MCP catalog base URL (https://registry.smithery.ai). Smithery is a third-party catalog that complements the official MCP Registry — it ships hundreds of MCP servers (often ahead of the official registry's curation cadence) including remote-only entries hosted by Smithery itself. Probing both gives the operator a more complete view of the MCP ecosystem.

Wire shape differs from the official registry:

  • endpoint: `/servers?page=1&pageSize=N` (cursor pagination, not limit-based)
  • response: `{servers: [{qualifiedName, displayName, description, ...}]}` — flat, no `_meta` envelope
  • no per-entry version field (server versions live one level deeper at the per-server detail endpoint, not in the list)

ProbeSmitheryRegistry projects Smithery's `qualifiedName` → RegistryServer.Name and `description` → RegistryServer.Description so callers can reuse the same RegistryResult shape across both registries.

Variables

This section is empty.

Functions

This section is empty.

Types

type Catalog

type Catalog struct {
	SchemaVersion int              `toml:"schema_version"`
	Entries       map[string]Entry `toml:"entries"`
}

Catalog is the in-memory representation of one catalog file.

func Builtin

func Builtin() (*Catalog, error)

Builtin parses the embedded catalog. Returns an error only when the embedded TOML itself is malformed — i.e., a build-time bug we want to surface loudly.

func (*Catalog) List

func (c *Catalog) List() []NamedEntry

List returns all entries sorted by name. Drives `clawtool source list --available` (a future flag) and any introspection surface.

func (*Catalog) Lookup

func (c *Catalog) Lookup(name string) (Entry, bool)

Lookup resolves a bare name (e.g. "github") to its entry. Returns ok=false when the name is not in the catalog so callers can fall back to the long-form path or report a curated suggestion.

func (*Catalog) SuggestSimilar

func (c *Catalog) SuggestSimilar(name string, limit int) []string

SuggestSimilar returns up to `limit` candidate names that share a substring with `name` in either direction. Catches both partial input (`git` → `github`) and typos with extra characters (`github-typo` → `github`).

We don't reach for full Levenshtein here because catalog names are short and bidirectional substring matching covers the realistic typo patterns users hit at the CLI.

type Entry

type Entry struct {
	Description string   `toml:"description"`
	Runtime     string   `toml:"runtime"`
	Package     string   `toml:"package"`
	Args        []string `toml:"args,omitempty"`
	RequiredEnv []string `toml:"required_env,omitempty"`
	AuthHint    string   `toml:"auth_hint,omitempty"`
	Homepage    string   `toml:"homepage,omitempty"`
	Maintained  string   `toml:"maintained,omitempty"`
}

Entry is one source-server description.

func (Entry) EnvTemplate

func (e Entry) EnvTemplate() map[string]string

EnvTemplate returns a map keyed by required_env names with `${VAR}`-style values that secrets resolution will fill in at spawn time. Empty when no auth required.

func (Entry) ToSourceCommand

func (e Entry) ToSourceCommand() ([]string, error)

ToSourceCommand renders the runtime + package + args into the argv that would be exec'd to spawn this source. Used by CLI source-add to populate `[sources.<name>].command` in config.toml. Variable references like `${FILESYSTEM_ROOT}` are preserved verbatim — interpolation happens at spawn time against secrets + env, not now.

Mapping (per ADR-008):

npx     →  npx -y <package> [args...]
node    →  node node_modules/<package>/index.js [args...]
python  →  uvx <package> [args...]   (uvx is the modern uv-managed runner)
docker  →  docker run -i --rm <image> [args...]
binary  →  <package> [args...]       (PATH-resolved)

type NamedEntry

type NamedEntry struct {
	Name  string
	Entry Entry
}

NamedEntry pairs an entry with its catalog key (name) for sorted listing.

type RegistryResult added in v0.22.42

type RegistryResult struct {
	BaseURL string           `json:"base_url"`
	Count   int              `json:"count"`
	Servers []RegistryServer `json:"servers"`
}

RegistryResult is the parsed `ProbeRegistry` response: how many servers came back + their summary projections + the effective base URL used (echoes the resolved value back so callers writing diagnostics can show what was actually hit).

func ProbeRegistry added in v0.22.42

func ProbeRegistry(ctx context.Context, baseURL string, limit int) (*RegistryResult, error)

ProbeRegistry hits the MCP Registry's `/v0/servers` endpoint at `baseURL` and returns the first `limit` server entries.

`baseURL` defaults to DefaultRegistryURL when empty. Trailing slashes are tolerated. `limit` is clamped to the inclusive range [1, 50] — the upstream caps page size around 50, and callers asking for 0 or a negative number get the friendly default of 10.

The function is intentionally read-only and short-circuit- friendly: an unreachable endpoint, a non-200 response, or malformed JSON all surface as wrapped errors so the caller (a CLI verb or a future catalog-fallback path) can decide whether to fall back to the embedded builtin catalog or propagate the failure.

HTTP timeout is 8 seconds — long enough for sane network conditions, short enough that an offline operator gets a clear failure rather than a 30+ second hang.

func ProbeSmitheryRegistry added in v0.22.47

func ProbeSmitheryRegistry(ctx context.Context, baseURL string, limit int) (*RegistryResult, error)

ProbeSmitheryRegistry hits Smithery's `/servers?page=1&pageSize=N` endpoint and projects the response into the same RegistryResult shape ProbeRegistry returns. Lets callers (CLI verb / MCP tool / catalog fallback path) treat the two registries as interchangeable read-only data sources.

Same defensive defaults as ProbeRegistry: empty baseURL falls to DefaultSmitheryRegistryURL, trailing slash tolerated, limit clamped to [1, 50] (Smithery's pageSize accepts up to 50).

Smithery's flat envelope means the inner unwrap step ProbeRegistry needs (`{servers: [{server: {...}}]}`) collapses to a direct slice decode here.

type RegistryServer added in v0.22.42

type RegistryServer struct {
	// Name is the canonical server identifier in the registry,
	// e.g. "ac.inference.sh/mcp" or "io.github.octocat/server".
	// Always present.
	Name string `json:"name"`

	// Description is the one-line registry description. May be
	// empty when the server author didn't supply one.
	Description string `json:"description,omitempty"`

	// Version is the upstream's declared semver. Different
	// versions of the same server appear as separate entries
	// in the registry (server vendors publish each release).
	Version string `json:"version,omitempty"`
}

RegistryServer is the projection of one MCP Registry server entry that clawtool actually uses. The upstream payload is richer (remotes, packages, repository, _meta) — we capture only the fields useful for catalog probing + listing. Future migrations can extend this struct without breaking existing callers since JSON unmarshalling tolerates unknown fields by default.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL