Known limits and troubleshooting

  • Administration persists backend/tool-group configuration and write approvals with their audit history. There is still no metrics endpoint, persistent MCP catalog, cross-instance subscription state, or high-availability coordination; each process owns its backend connections, catalogs, and token views.
  • This release does not provide stdio backends, a standalone legacy GET SSE endpoint, native TLS, dynamic tenants, opaque-token introspection, Tasks, MCP Apps, or custom MCP extensions. The local connect command provides stdio access to the HTTP gateway. TLS and external rate limiting belong at the reverse proxy.
  • Personal credentials currently cover remote MCP endpoints; HTTP tool groups, dynamic cloud/database credentials and provider-specific SaaS OAuth adapters are outside this release.
  • The aggregator advertises and implements only tools, prompts, resources (including subscriptions), and completions. Other backend capabilities do not automatically become gateway capabilities. Invalid names, URI templates, and SDK-rejected metadata are omitted.
  • A disconnected backend keeps its last-known-good catalog, but calls require a live connection. A required backend makes /readyz return 503; an optional backend does not block overall readiness.
  • server.refresh_interval is the maximum refresh period; a shorter backend TTL refreshes sooner. There is no forced-refresh API.
  • SIGHUP does not reread the orchestration layer's Docker --env-file; placeholders use the current process environment. Restart for secret changes or fields that cannot be reloaded.

Common symptoms:

  1. validate reports environment variable ... is not set: inject the selected example's variables into the actual service process; see the base example or remote deployment. required: false does not skip backend variable validation.
  2. /readyz returns 503: inspect auth_verifier_ready and required_ready in the JSON, then check OIDC discovery/JWKS and required backend URLs.
  3. MCP returns 401 with a resource_metadata challenge: check the Bearer token, signature, issuer, and audience.
  4. MCP returns 403 insufficient_scope: add every scope named in the challenge for that backend.
  5. /mcp returns 404: ensure the request path exactly matches the path in public_url; public_url cannot be the domain root.

Common configuration mistakes:

Symptom Check and action
YAML edits do not change the service list After managed-store initialization, edit through UI/API; do not delete the database.
SSO/Vault still uses ${...} despite exports These fields do not expand; use literal settings and *_env names for secrets.
Admin console exists but no user portal Enable client_authorization separately and register ordinary-user clients.
Published tools remain hidden or cannot execute Check original names, effect, token/grant scopes and user policies; validation does not check actual tool existence.
SQLite appears empty Check the YAML location and resolved database_path; avoid opening a new path unintentionally.

Capabilities and boundaries

  • Connects to multiple backends over MCP Streamable HTTP; backend catalogs are paginated, and the tools, prompts, resources, and resource-template lists are discovered in parallel and refreshed on backend notifications or the configured refresh schedule.
  • Aggregates tools, prompts, resources, resource templates, and completion; forwards tool/prompt/resource calls, resource subscribe/unsubscribe, progress notifications, and resource-update notifications.
  • Streams backend SSE responses through unchanged while inspecting progress notifications; at most 1 MiB of each event is buffered for inspection, and an oversized event is forwarded unchanged without progress inspection.
  • Normalizes missing 2026-07-28 metadata on notifications/cancelled from official Go MCP SDK v1.7.0 clients on both Hub ingress and backend egress, so the same logical MCP session remains reusable after cancellation or unsubscribe; this is an interoperability shim, not a custom extension.
  • Namespaces capabilities with backend.id and rewrites resource URIs to avoid same-name capability and URI collisions between backends.
  • Verifies Bearer JWTs with OIDC discovery and JWKS, then filters catalogs and calls by each backend's required_scopes.
  • Includes the separate mcpbridge program for built-in, LDAP or OIDC browser login, Agent device authorization and a local stdio-to-HTTP connector with credential refresh.
  • Requires explicit tool publication, resource-argument restrictions and independent approval for write/unclassified tools; supports reviewer quorum, local TOTP or verified OIDC step-up, configuration review and signed audit delivery.
  • Manages SSO user/group/department permissions and per-client scopes through the personal consent portal and local Broker. setup emits credential-free MCP configuration; doctor diagnoses access without executing tools.
  • Applies backend-local tool_rules to original tool names with Go path.Match; matching rules union and deduplicate required scopes, use all-of authorization, and hide unauthorized tools from tools/list.
  • Supports static backend request headers or OAuth 2.0 client_credentials; neither mode may provide a static Authorization header together with OAuth.
  • The administration UI groups pages under overview, connections, access control, and governance/audit. It supports persistent Chinese/English selection, role-aware navigation and narrow screens. Groups can publish hand-authored HTTP tools and multiple OpenAPI 3.0/3.1 imports through /mcp; group Base URL, headers, OAuth, scopes, and timeout are shared, and no raw HTTP proxy is exposed.
  • Supports remote browser/CLI administration with built-in accounts or optional LDAP/OIDC sign-in and encrypted SQLite or PostgreSQL configuration storage for one gateway instance.
  • Configures per-endpoint request rates, burst capacity and concurrency through the UI/API; limits are disabled by default and shared by callers.
  • Provides health, readiness, and RFC 9728 Protected Resource Metadata endpoints, plus SIGHUP configuration reload.

When a backend connection fails, MCPHub retries and retains its last-known catalog. The catalog may remain listable while calls fail until the connection recovers. Startup does not exit just because a required backend is temporarily unavailable, so /readyz remains 503; a runtime created by SIGHUP requires its required backends to connect successfully on the initial attempt. Backend-authored JSON-RPC errors are returned unchanged. Network or transport failures are exposed only as backend <id> unavailable, so internal backend URLs, query strings, and credentials do not cross the Hub boundary. On reconnect, every tracked resource subscription must be restored successfully before the backend is marked ready; a restore failure keeps it unavailable and triggers another reconnect attempt.