Skip to content

MCP Registry and Discovery

See also: MCP Servers, MCP Client Setup, Observability and Request Logs, MCP Invocations, Request Logs, Data Relationships, Admin API Contract Workflow, ADR: External MCP Registry and Discovery Boundary

The external MCP registry is the control-plane record of MCP servers that Oceans LLM can discover and expose through the MCP gateway. It stores user-added server records in the database, keeps recommended server suggestions in a checked-in static catalog, discovers tool metadata through Streamable HTTP, and powers the admin diagnostics page at /admin/mcp/servers.

This page is maintainer and admin documentation for registry diagnostics. User-facing server setup lives in MCP Servers, and client setup lives in MCP Client Setup.

Tool grants, toolsets, OAuth token exchange runtime, and stdio MCP servers are out of scope for this slice.

Admin API

The platform-admin API surface is:

  • GET /api/v1/admin/mcp/recommended-servers
  • GET /api/v1/admin/mcp/servers
  • POST /api/v1/admin/mcp/servers
  • PATCH /api/v1/admin/mcp/servers/{server_id}
  • POST /api/v1/admin/mcp/servers/{server_id}/disable
  • GET /api/v1/admin/mcp/servers/{server_id}/tools
  • POST /api/v1/admin/mcp/servers/{server_id}/discovery-refresh

All endpoints require an active platform-admin session. The admin contract is generated from gateway handler annotations; regenerate it with mise run admin-contract-generate after route or DTO changes.

Admin UI

The admin UI route is:

text
/admin/mcp/servers

The page shows:

  • registered servers, active/disabled state, discovery status, tool count, and bounded last error
  • selected server diagnostics, URL, auth mode, timeout, and discovery timestamps
  • discovered tools with active state, schema hash, schema version, and first/last discovered timestamps
  • recommended catalog import
  • custom server creation
  • edit, disable, and discovery refresh actions

Keep this page separate from /admin/observability/mcp-invocations. The registry page describes configured upstream servers and discovery status; the invocation page describes request-linked tool calls.

Recommended servers live in crates/gateway-service/data/recommended_mcp_servers.json.

The catalog is read-only runtime data:

  • it is never auto-seeded into the database
  • it is never treated as DB identity
  • admins must explicitly register/import a catalog entry before discovery
  • catalog keys are suggestions, not durable registry ids

When an admin creates a server with recommended_catalog_key, catalog values provide defaults for omitted fields. Overrides in the request body win. The resulting database row gets its own stable mcp_server_id.

Database Registry

User-added MCP servers are stored in:

  • external_mcp_servers: durable server identity, display data, auth declaration, discovery summary, and soft-disable state
  • external_mcp_tools: latest known tools, normalized schemas, stable tool ids, schema hashes, schema versions, and active/inactive state
  • external_mcp_discovery_runs: immutable discovery attempt diagnostics

Delete semantics are disable/archive semantics. There is no hard delete endpoint. Disabled servers are omitted from normal list views unless include_disabled=true is requested.

Rediscovery marks previously active tools inactive before upserting the newly discovered set. Existing tools keep their stable mcp_tool_id when the upstream tool name is unchanged. A changed input schema increments schema_version; unchanged schemas keep their current version.

Gateway Data Plane

The public data-plane route is:

text
GET /mcp/{server_key}
POST /mcp/{server_key}
DELETE /mcp/{server_key}

It proxies Streamable HTTP requests to the active registered server URL. Runtime policy:

  • authenticate inbound callers with Oceans API keys
  • hide disabled and unknown servers as not found
  • allow active servers with none, gateway_static_header, or gateway_bearer_token
  • return 403 mcp_upstream_auth_required for user_passthrough and oauth_obo
  • strip inbound Authorization and x-oceans-api-key before proxying upstream
  • forward only protocol/runtime-safe MCP headers and configured gateway-managed upstream auth

Inbound credential contract details live in Identity and Access.

Discovery Transport

Phase 2 supports Streamable HTTP only.

Discovery initializes the configured server URL over Streamable HTTP, sends the MCP protocol version header, and accepts JSON or text/event-stream JSON-RPC responses. Tool input schemas are normalized into canonical JSON before hashing. Non-object input schemas are rejected and recorded as discovery failures.

Discovery status is the server health signal for this slice. Do not add a separate ping health check or discovery-run history UI until the product needs those distinct diagnostics.

Stdio MCP servers, legacy SSE transport, tool federation, and grants/toolsets are intentionally not implemented here.

Auth Modes

Stored auth modes are declarations:

  • none
  • gateway_static_header
  • gateway_bearer_token
  • user_passthrough
  • oauth_obo

Discovery and proxying can use only none or gateway-managed secret references. Gateway-managed credentials require an HTTPS server_url and use auth_config.secret_ref with the env/OCEANS_MCP_DISCOVERY_* form. gateway_static_header also requires auth_config.header_name.

user_passthrough and oauth_obo are recorded so future execution and grants can require user-owned credentials. Discovery records auth_required, and proxying returns mcp_upstream_auth_required, rather than attempting to persist or forward a user token.

Never store raw tokens in:

  • discovery runs
  • tool metadata
  • request logs
  • MCP invocation logs
  • admin API responses

Discovery diagnostics store bounded summaries and client error categories. HTTP failure summaries include the upstream status code, but not upstream response bodies.

Metrics and Traces

Discovery refresh emits metrics:

  • gateway.mcp.discovery.refreshes
  • gateway.mcp.discovery.refresh.duration

Metric labels are bounded to server_id, result, and status. Do not add labels for URLs, header values, secrets, or raw upstream errors.

Discovery refresh and MCP proxy attempts run under tracing spans with redacted fields. Safe fields include server id, server key, upstream auth mode, caller owner kind, and status code.

Failure Remediation

Use the registry page first:

  • auth_required: change the server to none or a gateway-managed auth mode, or wait for user-scoped OAuth grants.
  • failed: inspect last_error_summary, validate URL reachability, timeout, protocol support, and secret environment variables.
  • disabled server: re-create or update the desired server record; disabled servers are hidden from data-plane clients.
  • zero tools after success: confirm the upstream server exposes tools over Streamable HTTP and returns object input schemas.

Relationship to Observability

MCP invocation logs already have nullable server_id and tool_id fields. Registry-backed execution can later populate those fields from external_mcp_servers and external_mcp_tools so request-log MCP cardinality can use stable registry identities.

Until execution is implemented, registry discovery only records server and tool metadata. It does not expose tools to model requests.

Validation

Run:

bash
mise run admin-contract-generate
mise run admin-contract-check
mise run lint

If docs tooling is available in the environment, also run the docs check before handoff.