List catalog

Lists the MCP servers the public registries publish, as we hold them: our canonical copy of registry.modelcontextprotocol.io, plus what we decided about each entry.

GET /v1/tool/catalog

Addresshttps://api.hanzo.ai/v1/tool/catalog
MethodGET
Operationget_tool_catalog
AuthAuthorization: Bearer $HANZO_API_KEY

Lists the MCP servers the public registries publish, as we hold them: our canonical copy of registry.modelcontextprotocol.io, plus what we decided about each entry.

This is the SHELF an org picks from. A listing with a streamable-http endpoint can be enabled as-is — POST /v1/tool/mcp/servers with its id — and its tools then join the org's tool plane and the fleet's MCP server. A listing that only ships a stdio package needs a process to run it, which is why the transports are on every entry rather than implied.

Hidden entries are absent: they are the ones we took off the shelf. A platform SuperAdmin sees them, because the same query answers "what is on the shelf" and "what is in the catalog" and two queries would drift apart.

It is PAGED — 50 by default, 200 at most. The public registry publishes tens of thousands of servers, so an unbounded answer is a twenty-megabyte response and a storefront that renders in a minute. total is the whole match, not the page.

It needs no credential: the shelf is a copy of public registries, the same for every org, and a storefront shows it to a visitor before anyone signs in.

Request

5 fields.

FieldInTypeRequiredDescription
qquerystring—Q matches the name, title or description, case-insensitively.
featuredquerystring—Featured keeps only the listings we put on the front of the shelf, and only when it is exactly the string "true".
officialquerystring—Official keeps only the vendors' OWN servers — not third-party copies of them — and only when it is exactly the string "true".
limitqueryinteger—Limit bounds the page: default 50, maximum 200.
offsetqueryinteger—Offset skips that many listings.

Response

StatusBodyMeaning
200tool.mcpCatalogok
defaultproblem-detailsrefused

200 body — 28 fields.

FieldInTypeAlwaysDescription
catalogbodytool.MCPListing[]—Catalog is this page of listings, featured first, then by name.
catalog[].descriptionbodystring—Description is the publisher's one-line summary.
catalog[].featuredbodyboolean—Featured puts the listing on the front of the shelf.
catalog[].hiddenbodyboolean—Hidden keeps the listing out of the org-visible catalog.
catalog[].idbodystring—ID addresses the listing in a URL.
catalog[].logobodystring—Logo is the brand mark to render for the listing — the publisher's icon when the entry carries one, or the one an admin set.
catalog[].namebodystring—Name is the publisher's reverse-DNS name, e.g. "com.stripe/mcp".
catalog[].officialbodyboolean—Official is whether this is the vendor's OWN server rather than someone else's copy of it.
catalog[].packagesbodytool.MCPPackage[]—Packages are the runnable package forms — npm, pypi, oci — each with the runtime that launches it and the transport it then speaks.
catalog[].packages[].identifierbodystring—Identifier is the package name or download URL.
catalog[].packages[].registrybodystring—Registry is where the package is fetched from: npm, pypi, oci, nuget, mcpb.
catalog[].packages[].runtimebodystring—Runtime is the publisher's hint for what launches it: npx, uvx, docker.
catalog[].packages[].transportbodystring—Transport is what the launched process speaks: usually "stdio".
catalog[].packages[].versionbodystring—Version is the exact published package version.
catalog[].registrybodystring—Registry is the upstream this row was synced from.
catalog[].remotesbodytool.MCPRemote[]—Remotes are the hosted endpoints the publisher serves the server at.
catalog[].remotes[].transportbodystring—Transport is "streamable-http" or "sse".
catalog[].remotes[].urlbodystring—URL is the endpoint.
catalog[].repobodystring—Repo is the source repository URL, when the entry names one.
catalog[].sitebodystring—Site is the project's homepage, when the entry names one.
catalog[].syncedbodyinteger (int64)—Synced is when this row was last confirmed against upstream, Unix seconds.
catalog[].titlebodystring—Title is the human-readable display name, when the entry carries one.
catalog[].transportsbodystring[]—Transports are the distinct transports this server can be reached over, sorted: some of "stdio", "streamable-http", "sse".
catalog[].vendorbodystring—Vendor is the namespace half of Name — the publisher, e.g. "com.stripe".
catalog[].versionbodystring—Version is the published version of this listing.
limitbodyinteger (int64)—Limit is the page size that was actually applied — the default or the clamp, when the request asked for neither or for too much.
offsetbodyinteger (int64)—Offset is where this page started, so a caller pages from what the server did rather than from what it asked for.
totalbodyinteger (int64)—Total is how many listings the filter matched, which is more than this page holds whenever there is a next one.

Failure carries the platform error shape — see Errors.

Examples

hanzo tool catalog list
import { Configuration, ToolApi } from 'hanzoai';

const api = new ToolApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getToolCatalog();
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ToolApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ToolApi(client).get_tool_catalog()
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ToolAPI.GetToolCatalog(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, tool_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = tool_api::get_tool_catalog(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ToolApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ToolApi(client).getToolCatalog();
curl https://api.hanzo.ai/v1/tool/catalog \
  -H "Authorization: Bearer $HANZO_API_KEY"

Tool tool, op get_tool_catalog — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "tool",
         "arguments": {
           "op": "get_tool_catalog",
           "input": {}
         }
       }
     }'

Tool API · All Hanzo APIs · Interactive reference

Was this page useful?