MCP catalog

Package: agentrouter.mcp.v1 Service: MCPCatalogService

Endpoints

Create or update an MCP catalog server

Changed in v0.9.0 (new features): The MCP catalog operations accept a platform MCP role, so a platform admin can manage the catalog without full admin rights. A customer's admins can list the enabled catalog servers. Deleting or disabling a server can now be refused while profiles or projects still use it.

Changed in v0.8.0 (bug fixes): Changes to an MCP catalog server now reach data planes that host no project gateway, so a re-pointed server stops serving its old URL and a disabled or deleted one stops being reachable at /mcp/s/<server>. Archiving a project through the tenancy API now also clears the project's gateway setup, as deleting it already did.

Changed in v0.1.5 (bug fixes): Editing, disabling, or deleting a shared MCP catalog server now refreshes the MCP profiles that route it within a worker poll. Previously only the per-gateway catalog directory was refreshed, so a profile serving that server kept the old address and tool set until the next periodic full sync, up to ~30 minutes. Both the catalog API and the operator dashboard now fan the change out to every affected profile owner.

What it does: Creates or replaces a catalog entry. Idempotent on id. Operator-only.

Request fields:

FieldRequiredDescription
idyesRequired: stable catalog entry id (e.g. "github").
nameyesRequired: display name.
descriptionnoOptional description.
urlyesRequired: customer-facing URL. The flag is renamed to --catalog-url to avoid colliding with the root command's persistent --base-url override.
icon_urlnoOptional icon URL.
categoriesnoOptional category tags.
notenoOptional free-form note.
authenticationnoOptional authentication kind label.
requires_authnoWhether this catalog entry requires a credential.
requires_profilenoWhether the user must register a profile before using this entry.

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) UpsertCatalogServer(ctx context.Context, req *mcpv1.UpsertCatalogServerRequest) (*mcpv1.MCPCatalogServer, error)","python":"upsert_catalog_server(req: mcp_pb2.UpsertCatalogServerRequest) -\u003e MCPCatalogServer","typescript":"upsertCatalogServer(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.UpsertCatalogServerRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","cli":"tare api mcp catalog upsert --id $ID --name $NAME --url $URL","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"id\": \"...\",\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.UpsertCatalogServerRequest{}\n\n\tresp, err := client.MCPCatalog().UpsertCatalogServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/upsertcatalogserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.UpsertCatalogServerRequest()\ntry:\n    result = client.mcp_catalog.upsert_catalog_server(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.upsertCatalogServer(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog upsert --id $ID --name $NAME --url $URL","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"id\": \"...\",\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/v1/mcp/catalog/servers","slug":"create-or-update-an-mcp-catalog-server"}

Create an MCP catalog server

Changed in v0.11.0 (new features): CreateCatalogServer adds an MCP catalog server and returns ALREADY_EXISTS for an id in use. UpdateCatalogServer edits one and returns NOT_FOUND for an id that does not exist, so an edit never brings back a deleted server. UpsertCatalogServer is unchanged.

What it does: Adds a server to the MCP catalog, enabled. It never changes an existing one: when a server with this id exists it returns ALREADY_EXISTS and writes nothing. Use UpdateCatalogServer to edit one. It is not idempotent: a client that retries after a lost response and gets ALREADY_EXISTS should read the server with GetCatalogServer.

Request fields:

FieldRequiredDescription
idyesRequired: stable catalog entry id (e.g. "github"). Unique.
nameyesRequired: display name.
descriptionnoOptional description.
urlyesRequired: customer-facing URL. The flag is renamed to --catalog-url to avoid colliding with the root command's persistent --base-url override.
icon_urlnoOptional icon URL.
categoriesnoOptional category tags.
notenoOptional free-form note.
authenticationnoOptional authentication kind label.
requires_authnoWhether this catalog entry requires a credential.
requires_profilenoWhether the user must register a profile before using this entry.

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) CreateCatalogServer(ctx context.Context, req *mcpv1.CreateCatalogServerRequest) (*mcpv1.MCPCatalogServer, error)","python":"create_catalog_server(req: mcp_pb2.CreateCatalogServerRequest) -\u003e MCPCatalogServer","typescript":"createCatalogServer(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.CreateCatalogServerRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","cli":"tare api mcp catalog create --id $ID --name $NAME --url $URL","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers:create\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"id\": \"...\",\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.CreateCatalogServerRequest{}\n\n\tresp, err := client.MCPCatalog().CreateCatalogServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/createcatalogserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.CreateCatalogServerRequest()\ntry:\n    result = client.mcp_catalog.create_catalog_server(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.createCatalogServer(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog create --id $ID --name $NAME --url $URL","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers:create\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"id\": \"...\",\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/v1/mcp/catalog/servers:create","slug":"create-an-mcp-catalog-server"}

Update an MCP catalog server

Changed in v0.11.0 (new features): CreateCatalogServer adds an MCP catalog server and returns ALREADY_EXISTS for an id in use. UpdateCatalogServer edits one and returns NOT_FOUND for an id that does not exist, so an edit never brings back a deleted server. UpsertCatalogServer is unchanged.

What it does: Replaces the content fields of an existing catalog server. It keeps the tools, the enabled state and the grants. A server that does not exist is NOT_FOUND, so an edit never brings back a server someone deleted. Every project that grants the server, and every owner of a profile that uses it, gets its routes regenerated.

Request fields:

FieldRequiredDescription
idyesRequired: id of the catalog entry to update.
nameyesRequired: display name.
descriptionnoOptional description.
urlyesRequired: customer-facing URL. The flag is renamed to --catalog-url to avoid colliding with the root command's persistent --base-url override.
icon_urlnoOptional icon URL.
categoriesnoOptional category tags.
notenoOptional free-form note.
authenticationnoOptional authentication kind label.
requires_authnoWhether this catalog entry requires a credential.
requires_profilenoWhether the user must register a profile before using this entry.

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) UpdateCatalogServer(ctx context.Context, req *mcpv1.UpdateCatalogServerRequest) (*mcpv1.MCPCatalogServer, error)","python":"update_catalog_server(req: mcp_pb2.UpdateCatalogServerRequest) -\u003e MCPCatalogServer","typescript":"updateCatalogServer(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.UpdateCatalogServerRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.UpdateCatalogServerRequest{}\n\n\tresp, err := client.MCPCatalog().UpdateCatalogServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/updatecatalogserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.UpdateCatalogServerRequest()\ntry:\n    result = client.mcp_catalog.update_catalog_server(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.updateCatalogServer(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"...\",\n    \"description\": \"...\",\n    \"url\": \"...\",\n    \"icon_url\": \"...\",\n    \"categories\": [],\n    \"note\": \"...\",\n    \"authentication\": \"...\",\n    \"requires_auth\": false,\n    \"requires_profile\": false\n  }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/v1/mcp/catalog/servers/{id}","slug":"update-an-mcp-catalog-server"}

Get an MCP catalog server

Changed in v0.11.0 (new features): MCP catalog servers now return their tools, last tool fetch time and error, install examples and metadata, and SetCatalogServerTools saves a server's tools. The list organization admins see leaves out metadata and the fetch error.

Changed in v0.9.0 (new features): The MCP catalog operations accept a platform MCP role, so a platform admin can manage the catalog without full admin rights. A customer's admins can list the enabled catalog servers. Deleting or disabling a server can now be refused while profiles or projects still use it.

What it does: Returns a single catalog entry by id.

Request fields:

FieldRequiredDescription
idyesRequired: stable catalog entry id (e.g. "github").

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) GetCatalogServer(ctx context.Context, req *mcpv1.GetCatalogServerRequest) (*mcpv1.MCPCatalogServer, error)","python":"get_catalog_server(req: mcp_pb2.GetCatalogServerRequest) -\u003e MCPCatalogServer","typescript":"getCatalogServer(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.GetCatalogServerRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","cli":"tare api mcp catalog get \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.GetCatalogServerRequest{}\n\n\tresp, err := client.MCPCatalog().GetCatalogServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/getcatalogserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.GetCatalogServerRequest()\ntry:\n    result = client.mcp_catalog.get_catalog_server(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.getCatalogServer(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog get \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/v1/mcp/catalog/servers/{id}","slug":"get-an-mcp-catalog-server"}

List MCP catalog servers

Changed in v0.11.0 (new features): MCP catalog servers now return their tools, last tool fetch time and error, install examples and metadata, and SetCatalogServerTools saves a server's tools. The list organization admins see leaves out metadata and the fetch error.

What it does: Returns every catalog entry, including disabled rows so operators can re-enable them. The dashboard's read-only view filters to is_enabled=true.

Request fields:

FieldRequiredDescription
include_disablednoWhen true, include is_enabled=false entries. The dashboard sets this false; the operator CLI defaults to true so disabled servers are visible.
pagenoCursor-pagination inputs (page size + continuation token).

Response fields:

FieldRequiredDescription
serversnoCatalog entries for this page (disabled rows included per request).
pagenoCursor-pagination outputs (next-page token).
{"signatures":{"go":"func (x *MCPCatalogClient) ListCatalogServers(ctx context.Context, req *mcpv1.ListCatalogServersRequest) (*mcpv1.ListCatalogServersResponse, error)","python":"list_catalog_servers(req: mcp_pb2.ListCatalogServersRequest) -\u003e ListCatalogServersResponse","typescript":"listCatalogServers(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.ListCatalogServersRequestSchema\u003e): Promise\u003cListCatalogServersResponse\u003e","cli":"tare api mcp catalog list","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.ListCatalogServersRequest{}\n\n\tresp, err := client.MCPCatalog().ListCatalogServers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/listcatalogservers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.ListCatalogServersRequest()\ntry:\n    result = client.mcp_catalog.list_catalog_servers(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.listCatalogServers(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog list","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/v1/mcp/catalog/servers","slug":"list-mcp-catalog-servers"}

Toggle MCP catalog server visibility

Changed in v0.9.0 (new features): The MCP catalog operations accept a platform MCP role, so a platform admin can manage the catalog without full admin rights. A customer's admins can list the enabled catalog servers. Deleting or disabling a server can now be refused while profiles or projects still use it.

Changed in v0.8.0 (bug fixes): Changes to an MCP catalog server now reach data planes that host no project gateway, so a re-pointed server stops serving its old URL and a disabled or deleted one stops being reachable at /mcp/s/<server>. Archiving a project through the tenancy API now also clears the project's gateway setup, as deleting it already did.

Changed in v0.1.5 (bug fixes): Editing, disabling, or deleting a shared MCP catalog server now refreshes the MCP profiles that route it within a worker poll. Previously only the per-gateway catalog directory was refreshed, so a profile serving that server kept the old address and tool set until the next periodic full sync, up to ~30 minutes. Both the catalog API and the operator dashboard now fan the change out to every affected profile owner.

What it does: Flips the operator visibility toggle on a catalog entry. Split from UpsertCatalogServer so a re-upsert that refreshes content fields (display_name, url, ...) cannot silently re-enable a previously-disabled row through the proto bool zero value.

Request fields:

FieldRequiredDescription
idyesStable catalog entry id, e.g. "github".
enabledyesTarget visibility. true -> entry is visible to the customer-facing list; false -> hidden (row kept, is_enabled set to false).
typed_errorsnoWhen true, disabling a server a live MCP profile attaches fails with FAILED_PRECONDITION naming the reason. Unset keeps the old answer (INTERNAL, from the database's guard).

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) SetCatalogServerEnabled(ctx context.Context, req *mcpv1.SetCatalogServerEnabledRequest) (*mcpv1.MCPCatalogServer, error)","python":"set_catalog_server_enabled(req: mcp_pb2.SetCatalogServerEnabledRequest) -\u003e MCPCatalogServer","typescript":"setCatalogServerEnabled(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.SetCatalogServerEnabledRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","cli":"tare api mcp catalog set-enabled --id $ID --enabled $ENABLED","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H.../enabled\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"enabled\": false,\n    \"typed_errors\": false\n  }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.SetCatalogServerEnabledRequest{}\n\n\tresp, err := client.MCPCatalog().SetCatalogServerEnabled(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/setcatalogserverenabled\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.SetCatalogServerEnabledRequest()\ntry:\n    result = client.mcp_catalog.set_catalog_server_enabled(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.setCatalogServerEnabled(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog set-enabled --id $ID --enabled $ENABLED","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H.../enabled\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"enabled\": false,\n    \"typed_errors\": false\n  }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/v1/mcp/catalog/servers/{id}/enabled","slug":"toggle-mcp-catalog-server-visibility"}

Save an MCP catalog server's tools

Changed in v0.11.0 (new features): MCP catalog servers now return their tools, last tool fetch time and error, install examples and metadata, and SetCatalogServerTools saves a server's tools. The list organization admins see leaves out metadata and the fetch error.

What it does: Saves the tools a catalog server offers, which the caller fetched from the server, or why that fetch failed. With tools, it replaces the list, stamps tools_fetched_at and clears tools_last_error. With only last_error, it keeps the tools and records the error. A server that does not exist is NOT_FOUND. Profiles pick from these tools; saving them changes no route, so it sends no data-plane event.

Request fields:

FieldRequiredDescription
idyesStable catalog entry id, e.g. "github".
toolsnoThe tools the server offers. Replaces the saved list. Ignored when last_error is set.
last_errornoWhy fetching the tools failed. When set, the saved tools are kept and only this error is recorded.

Response fields:

FieldRequiredDescription
idyesStable string id (e.g. "github", "jira"). Required on upsert.
nameyesDisplay name shown in the dashboard catalog.
descriptionnoDescription text shown in the dashboard catalog.
urlyesCustomer-facing MCP server URL.
icon_urlnoOptional icon URL displayed in the dashboard catalog.
categoriesnoCategory tags ("git", "issue-tracker", ...). Empty list permitted.
notenoOptional free-form note shown alongside the catalog entry.
authenticationnoAuthentication kind label ("oauth", "api_key", "none"). Free-form string -- the catalog renderer interprets it.
requires_authnoTrue when this catalog entry requires a credential from the user (used by the dashboard "Add" flow to pre-populate credential UI).
requires_profilenoTrue when the user must register a profile before using this catalog entry (rather than just adding a backend selector).
is_enablednoOperator-controlled visibility toggle. Disabled servers stay in the table but are hidden from the customer-facing list.
toolsoutput-onlyThe tools the server offers, as last saved with SetCatalogServerTools. Profiles pick from these. Output-only.
tools_fetched_atoutput-onlyWhen the tools were last saved. Unset when they never were. Output-only.
tools_last_erroroutput-onlyWhy the last tool fetch failed, as saved with SetCatalogServerTools. Empty after a successful save. Output-only.
install_examplesoutput-onlyHow to install the server, keyed by client (for example "claude", "cursor"). Output-only.
metadataoutput-onlyFree-form catalog metadata. Output-only.
created_atoutput-onlyRow creation time. Output-only.
updated_atoutput-onlyLast mutation time. Output-only.
{"signatures":{"go":"func (x *MCPCatalogClient) SetCatalogServerTools(ctx context.Context, req *mcpv1.SetCatalogServerToolsRequest) (*mcpv1.MCPCatalogServer, error)","python":"set_catalog_server_tools(req: mcp_pb2.SetCatalogServerToolsRequest) -\u003e MCPCatalogServer","typescript":"setCatalogServerTools(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.SetCatalogServerToolsRequestSchema\u003e): Promise\u003cMCPCatalogServer\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H.../tools\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"tools\": [],\n    \"last_error\": \"...\"\n  }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.SetCatalogServerToolsRequest{}\n\n\tresp, err := client.MCPCatalog().SetCatalogServerTools(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/setcatalogservertools\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.SetCatalogServerToolsRequest()\ntry:\n    result = client.mcp_catalog.set_catalog_server_tools(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.setCatalogServerTools(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H.../tools\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"tools\": [],\n    \"last_error\": \"...\"\n  }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/v1/mcp/catalog/servers/{id}/tools","slug":"save-an-mcp-catalog-servers-tools"}

Delete an MCP catalog server

Changed in v0.9.0 (new features): The MCP catalog operations accept a platform MCP role, so a platform admin can manage the catalog without full admin rights. A customer's admins can list the enabled catalog servers. Deleting or disabling a server can now be refused while profiles or projects still use it.

Changed in v0.8.0 (bug fixes): Changes to an MCP catalog server now reach data planes that host no project gateway, so a re-pointed server stops serving its old URL and a disabled or deleted one stops being reachable at /mcp/s/<server>. Archiving a project through the tenancy API now also clears the project's gateway setup, as deleting it already did.

Changed in v0.1.5 (bug fixes): Editing, disabling, or deleting a shared MCP catalog server now refreshes the MCP profiles that route it within a worker poll. Previously only the per-gateway catalog directory was refreshed, so a profile serving that server kept the old address and tool set until the next periodic full sync, up to ~30 minutes. Both the catalog API and the operator dashboard now fan the change out to every affected profile owner.

Changed in v0.1.5 (bug fixes): Deleting an MCP catalog server now succeeds when projects have granted that server. The delete removes the grant rows and the server in one transaction, then refreshes each granting project and each affected profile owner. Such a delete previously failed with a 500 error that exposed the database constraint name.

What it does: Removes a catalog entry by id. Operator-only.

Request fields:

FieldRequiredDescription
idyesRequired: stable id of the catalog entry to delete (e.g. "github").
refuse_if_attachednoWhen true, refuse with FAILED_PRECONDITION while a live MCP profile attaches the server. Unset keeps the old behaviour (the delete goes ahead and the attachments stay).
refuse_if_grantednoWhen true, refuse with FAILED_PRECONDITION while a project grants the server. Unset keeps the old behaviour (the grants are removed with it).
{"signatures":{"go":"func (x *MCPCatalogClient) DeleteCatalogServer(ctx context.Context, req *mcpv1.DeleteCatalogServerRequest) error","python":"delete_catalog_server(req: mcp_pb2.DeleteCatalogServerRequest) -\u003e None","typescript":"deleteCatalogServer(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.DeleteCatalogServerRequestSchema\u003e): Promise\u003cvoid\u003e","cli":"tare api mcp catalog delete \u003cid\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.DeleteCatalogServerRequest{}\n\n\tif err := client.MCPCatalog().DeleteCatalogServer(ctx, req); err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Println(\"ok\")\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/deletecatalogserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.DeleteCatalogServerRequest()\ntry:\n    result = client.mcp_catalog.delete_catalog_server(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.deleteCatalogServer(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog delete \u003cid\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/v1/mcp/catalog/servers/01H...\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/v1/mcp/catalog/servers/{id}","slug":"delete-an-mcp-catalog-server"}

Get the OAuth client for an MCP catalog server

Changed in v0.9.0 (new features): A new operation returns the OAuth client that signs a project in to an MCP catalog server: the project's own client, or else the shared one from the Admin Console. It never returns the client secret.

What it does: Returns the OAuth client that serves a catalog server in one project, as sign-in picks it: the project's own client, else the deployment's shared one. Never another project's, and never the client secret. NOT_FOUND when no active client serves the server. The Admin Console calls it before it starts an OAuth sign-in or fetches a server's tools, so it needs mcp edit.

Request fields:

FieldRequiredDescription
customer_idyesundocumented
project_idyesundocumented
idyesRequired: the catalog server id (e.g. "github").

Response fields:

FieldRequiredDescription
idoutput-onlyundocumented
customer_idoutput-onlyundocumented
project_idoutput-onlyundocumented
provideryesundocumented
provider_nameyesundocumented
client_idyesundocumented
authorization_urlyesundocumented
token_urlyesundocumented
scopesnoundocumented
redirect_urisnoundocumented
metadatanoundocumented
server_idsnoundocumented
statusnoundocumented
created_atoutput-onlyundocumented
updated_atoutput-onlyundocumented
metadata_jsonnoundocumented
{"signatures":{"go":"func (x *MCPCatalogClient) GetCatalogServerOAuthClient(ctx context.Context, req *mcpv1.GetCatalogServerOAuthClientRequest) (*mcpv1.McpOAuthClient, error)","python":"get_catalog_server_oauth_client(req: mcp_pb2.GetCatalogServerOAuthClientRequest) -\u003e McpOAuthClient","typescript":"getCatalogServerOAuthClient(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.GetCatalogServerOAuthClientRequestSchema\u003e): Promise\u003cMcpOAuthClient\u003e","cli":"tare api mcp catalog oauth-client --customer-id $CUSTOMER_ID --project-id $PROJECT_ID \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../mcp/catalog/servers/01H.../oauth-client\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.GetCatalogServerOAuthClientRequest{}\n\n\tresp, err := client.MCPCatalog().GetCatalogServerOAuthClient(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/getcatalogserveroauthclient\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.GetCatalogServerOAuthClientRequest()\ntry:\n    result = client.mcp_catalog.get_catalog_server_oauth_client(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.getCatalogServerOAuthClient(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog oauth-client --customer-id $CUSTOMER_ID --project-id $PROJECT_ID \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../mcp/catalog/servers/01H.../oauth-client\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/mcp/catalog/servers/{id}/oauth-client","slug":"get-the-oauth-client-for-an-mcp-catalog-server"}

List the MCP catalog servers available to a customer

Changed in v0.11.0 (new features): MCP catalog servers now return their tools, last tool fetch time and error, install examples and metadata, and SetCatalogServerTools saves a server's tools. The list organization admins see leaves out metadata and the fetch error.

Changed in v0.9.0 (new features): The MCP catalog operations accept a platform MCP role, so a platform admin can manage the catalog without full admin rights. A customer's admins can list the enabled catalog servers. Deleting or disabling a server can now be refused while profiles or projects still use it.

What it does: Lists the enabled catalog servers to the admins of one customer, for the Admin Console's MCP Servers page. It is the tenant read of the global catalogue: operator fields (note, metadata, tools_last_error) are left empty, and disabled servers are not listed.

Request fields:

FieldRequiredDescription
customer_idyesRequired: the customer whose admins list the catalogue. The catalogue is small and curated, so the whole enabled list comes back in one response.

Response fields:

FieldRequiredDescription
serversnoCatalog entries for this page (disabled rows included per request).
pagenoCursor-pagination outputs (next-page token).
{"signatures":{"go":"func (x *MCPCatalogClient) ListCustomerCatalogServers(ctx context.Context, req *mcpv1.ListCustomerCatalogServersRequest) (*mcpv1.ListCatalogServersResponse, error)","python":"list_customer_catalog_servers(req: mcp_pb2.ListCustomerCatalogServersRequest) -\u003e ListCatalogServersResponse","typescript":"listCustomerCatalogServers(req: MessageInitShape\u003ctypeof tars_mcp_v1_mcp_pb.ListCustomerCatalogServersRequestSchema\u003e): Promise\u003cListCatalogServersResponse\u003e","cli":"tare api mcp catalog list-available --customer-id $CUSTOMER_ID","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tmcpv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/mcp/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026mcpv1.ListCustomerCatalogServersRequest{}\n\n\tresp, err := client.MCPCatalog().ListCustomerCatalogServers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/mcpcatalog/listcustomercatalogservers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.mcp.v1 import mcp_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n    base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n    api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = mcp_pb2.ListCustomerCatalogServersRequest()\ntry:\n    result = client.mcp_catalog.list_customer_catalog_servers(req)\n    print(result)\nexcept Exception as err:\n    print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n#   agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n  baseUrl: process.env.AGENTROUTER_BASE_URL,\n  apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n  const result = await client.mcpCatalog.listCustomerCatalogServers(req)\n  console.log(result)\n} catch (err) {\n  console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n  \"name\": \"mcpcatalog\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"dependencies\": {\n    \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"typescript\": \"^5.4.0\"\n  }\n}\n"},{"name":"tsconfig.json","content":"{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true\n  }\n}\n"}]},"cli":"tare api mcp catalog list-available --customer-id $CUSTOMER_ID","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../mcp/catalog/servers\" \\\n  -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/v1/customers/{customer_id}/mcp/catalog/servers","slug":"list-the-mcp-catalog-servers-available-to-a-customer"}