Once you put several MCP servers behind a gateway, you have two things to maintain: the routes themselves and the list of URLs handed to every client. The second one tends to end up in agent config files, an internal catalog, or a wiki that ages badly.
The Zuplo MCP Gateway now exposes that list through the MCP Server Registry API. It builds the registry from your live routes, so there is no catalog to populate or synchronize.
- You run multiple MCP servers through a Zuplo MCP Gateway
- You maintain endpoint lists for agents, clients, or an internal catalog
The registry is generated from your routes
The registry is enabled by default at /__zuplo/mcp-registry. For a gateway at
gateway.example.com, this request lists its MCP servers:
The response follows the frozen v0.1 API:
Zuplo reads the route configuration when it handles the request. Add a route and it appears in the next response. Remove the route and it disappears. There is no registry database to keep in sync with the gateway.
MCP Server Registry documentation
Endpoint details, query parameters, response fields, and configuration.
Which routes appear in the registry
The gateway creates an entry for each concrete route that serves MCP traffic:
- Gateway virtual servers: Routes that use MCP Gateway policies to proxy an upstream server such as Linear or Stripe.
- Standalone MCP servers: Routes that use
mcpServerHandleror a bareMcpProxyHandlerwithout the gateway policies.
Each entry uses a reverse-DNS name derived from the request host and includes
the gateway route as a streamable-http remote. The title, description,
version, website URL, and icons come from the route’s upstream connection
configuration.
Parameterized routes such as /mcp/{server} don’t appear because they aren’t
connectable until the path parameter has a value. Before returning an entry, the
gateway normalizes its metadata to match the registry API. It truncates long
names, limits descriptions to 100 code points, drops non-HTTPS icons, and
replaces invalid version ranges. A malformed field on one route doesn’t break
discovery for the rest of the gateway.
Public discovery does not bypass route authentication
The registry’s discovery endpoints are unauthenticated and allow cross-origin requests, as defined by the upstream registry API. They return route URLs and descriptive metadata. They don’t return upstream credentials, access tokens, or gateway policy configuration.
A public catalog doesn’t grant access to the servers behind it. A client connecting to one of the listed routes still passes through the route’s authentication and other inbound policies. Treat route titles and descriptions as public metadata.
Git remains the source of truth
Zuplo gateway configuration follows a GitOps workflow. To add, update, or remove an MCP server, change its route configuration and deploy it the same way you change any other gateway route. The registry reflects the deployed state on its next request.
Accepting writes through the registry API would create a second, mutable server catalog. A record published there could drift from the route configuration in Git, leaving clients with a catalog that doesn’t match what the gateway serves.
Keeping the registry read-only avoids that split. Clients get a standard
discovery API, while server changes remain version-controlled and go through
your existing deployment workflow. Requests to publish, update, or delete a
version return 501 Not Implemented. Status updates return 403 Forbidden.
Error bodies use the registry API’s {"error": "..."} format, so registry
clients can handle them without a Zuplo-specific error parser.
Change the registry path or turn it off
The default path is {basePath}/mcp-registry, which resolves to
/__zuplo/mcp-registry with the default MCP Gateway base path. Pass a registry
option to McpGatewayPlugin to use a different path:
Set registry.enabled to false if you don’t want to expose a registry. Zuplo
validates custom paths at startup and rejects paths that conflict with the MCP
Gateway’s OAuth or well-known endpoints.
The trade-offs of a route-derived registry
Generating the catalog from route configuration removes a synchronization
problem, but it also means the registry has no stored history. The
updated_since query parameter is accepted but doesn’t filter the results, so
every entry is treated as changed.
Server names also depend on the request host. If the same gateway is available through two hostnames, each hostname produces a different reverse-DNS name. Neither behavior prevents discovery, but both matter if you mirror this catalog into a system that expects stable identifiers or update timestamps.
To inspect a deployed gateway, send a GET request to its
/__zuplo/mcp-registry/v0.1/servers endpoint. The
MCP Server Registry documentation
covers every endpoint and query parameter, and the
McpGatewayPlugin reference
covers configuration. If you’re deciding how local discovery fits with the
global MCP registry, read
MCP registry vs. MCP gateway.