backends
At least one backend is required in YAML-only mode. Admin mode may start empty so the first backend can be registered in the UI. Each id must match [A-Za-z0-9_-]{1,32} and be unique case-insensitively; uppercase letters are allowed.
| Field | Default | Description |
|---|---|---|
id |
none | External namespace and configured ID for tool/prompt names; dots are not allowed. Uppercase letters are retained in those names, while resource/template URI authorities use the lowercase ID. |
url |
none | Required absolute URL. HTTPS is required by default; HTTP is accepted only when allow_insecure_http: true and the host is localhost or an IPv4/IPv6 loopback. Fragments are rejected. |
required |
false |
Required backends affect /readyz. A runtime disconnect makes readiness 503 while the reconnect loop continues. |
require_client_grant |
false |
Enforces client grants for this endpoint; requires the user portal. Personal Vault accounts must explicitly set it to true. |
credentials |
none | Vault shared / personal source; requires global vault, and excludes service oauth and conflicting static auth headers on this backend. See Vault. |
required_scopes |
[] |
JWT scopes required for this backend, checked with all-of semantics; scope entries cannot contain whitespace or duplicates. |
published_tools |
[] |
Exact, case-sensitive original tool names approved for use; no wildcards. Empty publishes no tools. |
tool_rules |
[] |
Optional backend-local tool policies. Each rule has a match glob and at least one of effect, approval, required_scopes, or resource_rules. effect: read permits direct execution; write or an omitted classification requires approval. Matching uses Go path.Match against the original backend tool name, full-string and case-sensitive. |
request_timeout |
inherits server.request_timeout |
Timeout for this backend's connection, discovery, refresh, and calls; must be positive. |
rate_limit |
{} |
Shared endpoint rate, burst and concurrency limits; unlimited by default. |
allow_insecure_http |
false |
Loopback-only local HTTP switch. It does not relax HTTPS requirements for server.public_url or any issuer. |
headers |
{} |
Static headers added to every backend MCP HTTP request. Values support environment expansion, may not contain CR/LF, and names are case-insensitively unique. Accept, Content-Type, any Mcp-* header, and transport-managed headers such as Host, Content-Length, Connection, Proxy-Authorization, and Proxy-Authenticate are rejected. |
oauth |
none | Backend OAuth configuration. The only accepted type is client_credentials, and it cannot be combined with a static Authorization header. |
oauth fields:
| Field | Description |
|---|---|
type |
Must be client_credentials. |
issuer |
Required absolute HTTPS OAuth issuer; its metadata issuer must match exactly. |
client_id / client_secret |
Required; preferably supplied only through ${...} environment variables. |
scopes |
Scopes requested from the backend OAuth token endpoint. These are independent of required_scopes, which gate the JWT presented to MCPHub. |
Backend OAuth discovery and token requests do not receive the backend's static headers; data-plane requests do and automatically reuse/refresh the client-credentials token. Discovery probes RFC 8414/OIDC metadata for an exact issuer and token_endpoint only; it does not require interactive authorization or PKCE metadata. OAuth metadata responses are capped at 1 MiB. Backend and OIDC HTTP clients do not follow redirects.
Optional service-account OAuth fragment, excluded from the base template: add this entry under backends only when connecting such a service and set all 4 variables for it. required: false only changes connection-failure handling. Tools still require review and explicit publication.
- id: crm
url: ${MCPHUB_CRM_BACKEND_URL}
required: false
required_scopes: [mcp:crm.read]
published_tools: []
oauth:
type: client_credentials
issuer: ${MCPHUB_CRM_OAUTH_ISSUER}
client_id: ${MCPHUB_CRM_CLIENT_ID}
client_secret: ${MCPHUB_CRM_CLIENT_SECRET}
scopes: [crm.read]