Skip to content

Concepts

A catalog has a caller-supplied revision and a set of operations. Each operation has a unique dotted path, an input schema, and optional description, capability notes, instructions, and output schema. Forage validates the catalog, orders its operations deterministically, and prepares descriptions once when the catalog is created. To change the catalog, create a new revision instead of mutating the existing one.

search ranks matching operations. describe returns a bounded TypeScript description for one operation or a namespace. stamp() returns a stable identity for the sorted catalog metadata, including schema projections, capability notes and instructions.

forage.list({limit?, cursor?, namespace?}) (or catalog.list directly) enumerates every registered operation exactly once. Ordering is by namespace (the first path segment), then full operation path, compared by UTF-16 code units, not locale. Registration order never changes it. Equivalent operations are not merged into peers, unlike search.

Each page has results, total, catalogStamp and nextCursor. Results use the same summary schema as search (path, description, sample and capability notes). Score is zero because listing does not rank matches. The default and maximum limit is 50. The minimum is 1. Follow nextCursor until it is null. Total counts all operations in the exact namespace filter, not just this page. An absent namespace means every namespace. An unknown namespace returns an empty page with total zero.

Cursors are opaque to callers and belong to one catalog stamp and namespace filter. Reusing a cursor after either changes fails explicitly. Begin a fresh listing instead. A host that narrows a guest’s bound operations filters the existing summaries and uses the same listOperations owner before paging. It does not introduce another registry or leak unbound paths. Search and describe keep their existing contracts.