Skip to main content

Overview

Genesis exposes a hosted remote MCP endpoint for Claude Code and other MCP clients:
For customer deployments, use this hosted endpoint. Do not ask coworkers to configure stdio MCP, device-grant login, local token files, or local Python paths. Genesis also exposes https://<your-genesis-host>/mcp/v2/ as the explicit versioned v2 URL and keeps https://<your-genesis-host>/mcp/v1/ for the legacy gateway flow. This page is the admin setup for a hosted deployment. To connect a client (Claude Code, Claude Desktop, Cursor or Cortex Code), including on the Snowflake Native App, see Connect coding agents over MCP. The deployed Config → Agent Gateways page also provides the Genesis Cortex Code skill download; its install commands are in that client guide.

Prerequisites

  • Genesis is reachable through a public or VPN-accessible HTTPS hostname.
  • Genesis authentication is enabled with Auth0 or another OIDC provider.
  • The same issuer and audience used by Genesis are accepted by the MCP endpoint.
  • Coworkers can open the Genesis hostname from their laptops.
  • The OAuth app/client allows one redirect URI. Which one depends on GENESIS_OAUTH_PROXY_ENABLED — see OAuth Callback Setup below.

Turn on sign-in

A Genesis started with sign-in off (AUTH_ENABLED=false, the local default) already serves MCP: Config > Agent Gateways reports it as Local only, and claude mcp add --transport http genesis-local http://127.0.0.1:<port>/mcp connects from the same machine without a credential. Coworkers and remote clients need sign-in. Sign-in works with any OpenID Connect identity provider, including Okta, Microsoft Entra ID, Google, Keycloak and Auth0. The settings are deployment configuration, not an in-app page: set them in the Genesis server’s environment (Helm: under config.extraEnv) and restart Genesis.
  1. In your identity provider, register an application for Genesis and note its issuer URL, signing-keys (JWKS) URL, client ID, and the audience its access tokens carry.
  2. Add https://<your-genesis-host>/oauth/callback to that application’s allowed redirect URIs. It is the only callback to register.
  3. Set:
  1. Restart Genesis and reload Config > Agent Gateways: each client tab now shows the sign-in commands to give coworkers.
The GENESIS__AUTH__* form overrides any value stored in Genesis configuration; the older AUTH_ISSUER, AUTH_AUDIENCE, AUTH_JWKS_URL and AUTH0_CLIENT_ID variables apply only while no value is stored.

OAuth Callback Setup

Claude Code uses a local loopback callback during browser OAuth. This does not require inbound internet access to the coworker’s laptop: after sign-in, the user’s browser redirects to localhost on the same machine where Claude Code is running. Genesis is the authorization server, and it completes the provider redirect itself. Register exactly one redirect URI on the OAuth app, for the whole deployment:
That is the only callback the provider ever sees. Genesis holds each client’s own callback, sends the provider its own callback and its own PKCE challenge, and hands the client a Genesis authorization code on the way back. No coworker’s laptop and no individual MCP client — Claude Code, Cursor, Claude Desktop — is ever added to the identity provider. Loopback callbacks are accepted on any port without configuration, which is what lets a client bind whichever port is free (RFC 8252 §7.3). The fixed callbacks of the major MCP clients that do not use loopback are also accepted without configuration, matched exactly: Any other client whose callback is not a loopback address — a hosted console, for example — must be listed verbatim in auth.mcp_client_redirect_uris, or /authorize refuses it. Matching is exact: no prefix, wildcard, case or trailing-slash tolerance. A callback on an app’s own URL scheme (RFC 8252 §7.1, such as myapp://callback) is accepted only when it is one of the known callbacks above or listed there verbatim; javascript:, data:, file: and vbscript: callbacks and any callback carrying a # fragment delimiter are always refused. Dynamic client registration (POST /register) checks callbacks for structure only: it accepts any well-formed https or loopback callback, and an app-scheme callback on the same exact-match terms as above. It decides nothing about where a code lands, so a registered https callback that is neither built in nor listed is still refused later, at /authorize.

With the OAuth proxy off (OPRM-style delegation)

/authorize, /oauth/callback and /oauth/token return 404; clients run their code flow directly against the upstream issuer, so the provider must allow each client’s own loopback redirect URI:
Then use the matching fixed callback port in the Claude Code command:
Provider notes (proxy off only — with the proxy on, register https://<your-genesis-host>/oauth/callback instead of any of these):
  • Azure / Microsoft Entra ID: add the Genesis web origin as a Single-page application redirect and add http://localhost:31318/callback as a Mobile and desktop applications redirect on the same app registration.
  • Auth0, Okta, and other strict OIDC providers: add the exact callback URI your Claude Code command uses. Keeping the documented 31318 port makes this deterministic for admins and coworkers.

Load Balancer / Ingress Checklist

  1. Terminate TLS at the load balancer, ingress, Nginx, Caddy, or equivalent edge layer.
  2. Forward traffic for /mcp/, /.well-known/* and /api/mcp/artifacts/* to the Genesis backend. /api/mcp/artifacts/<id>?token=… is the signed, single-use download link that tool results hand to an MCP client for a file they produced. Its token authenticates it, so it needs no other credential. With GENESIS_OAUTH_PROXY_ENABLED on, also forward /authorize, /register and /oauth/* (/oauth/callback, /oauth/token): the metadata advertises them at the host root. If the rest of the host sits behind a login gate such as oauth2-proxy (an nginx auth-url annotation), route every one of these paths through an ingress without that gate. An MCP client has no browser session yet, so a gated path answers with a login redirect instead of Genesis. /register is the one a gate most often misses. Without it, clients that use dynamic client registration cannot connect, while Claude Code still can, because it uses a client ID metadata document.
  3. Ensure static/frontend catch-all routing does not intercept /mcp/ or /.well-known/.
  4. Preserve forwarding headers:
  1. If using Helm values or environment variables for a public base URL, set it to the HTTPS hostname customers use.

Deployment environment variables

Browser OAuth consent must reach Genesis on a publicly resolvable hostname. An Anthropic MCP tunnel hostname alone is not sufficient for Console Connect sign-in; use your production Genesis URL, a named Cloudflare tunnel, or another public HTTPS origin, and set GENESIS_MCP_PUBLIC_URL (or preserve forwarding headers) so metadata does not fall back to localhost.

Verify Metadata

Verify these URLs from a laptop:
The /mcp/ request should return 401 Unauthorized with a WWW-Authenticate header that includes resource_metadata=. If you have repository access, you can run the packaged smoke checker:
For OIDC-only deployments, scopes_supported should be an array such as ["openid", "profile", "email", "offline_access"]. Genesis omits the MCP resource indicator in that mode so identity providers do not receive an incompatible resource/scope combination. When GENESIS_OAUTH_PROXY_ENABLED is truthy, authorization_servers and the authorization-server metadata issuer point at the Genesis public base URL, with authorization_endpoint at {base}/authorize and token_endpoint at {base}/oauth/token; {base}/oauth/callback is the deployment’s own callback and is the single redirect URI the identity provider needs. (It is unrelated to {base}/api/oauth/callback, which serves the in-app connection popup.) JWKS and userinfo still reference the upstream issuer (for example Auth0 or Microsoft Entra ID v2.0 endpoints when auth.issuer is login.microsoftonline.com).

Access tokens Genesis cannot verify (/userinfo fallback)

With auth.provider set to oidc or auth0, Genesis first verifies a bearer token as a signed JWT against auth.issuer, auth.audience and auth.jwks_url. When that fails for any reason — the token is opaque or encrypted (JWE), or its issuer, audience, signature or expiry does not check out — Genesis sends the token to your identity provider’s userinfo endpoint and, if the provider answers 200 with a sub, signs the request in as that user. This applies to the web API and to the hosted MCP endpoint; the WebSocket and the hosted and snowflake providers accept only a verified token. What this trusts:
  • Your identity provider’s userinfo endpoint is the whole check. Genesis cannot read an audience, client or expiry from an opaque token, so it checks none on this path. Any access token your provider’s userinfo endpoint accepts signs in its user — including one issued to another application in the same tenant. User admission (SCIM, when it is enabled) still applies. Use a tenant, or an Auth0 tenant, whose users are the people who may use this deployment.
  • The endpoint comes from configuration, never from the token: auth.userinfo_endpoint when set, else the userinfo_endpoint from OIDC discovery on auth.issuer, else <auth.issuer>/userinfo. A token from a different provider is sent to yours, which refuses it.
  • Answers are cached per token. A successful answer is reused for one hour without asking the provider again, so a revoked token keeps working until its entry expires; a 401 is remembered for 60 seconds. Each cache holds at most 4,096 entries and drops the oldest first.
Why it exists: Auth0 issues an opaque or encrypted access token to a client that requests no audience, which is what MCP clients do when GENESIS_OAUTH_PROXY_ENABLED is off, and what the web UI does when auth.audience is empty. With the proxy off, Microsoft Entra ID gives hosted MCP clients Microsoft Graph tokens, which Genesis cannot verify against your tenant’s keys. To keep your users on verified tokens, set auth.audience and turn on GENESIS_OAUTH_PROXY_ENABLED, which adds audience to every MCP sign-in. The fallback stays on for tokens that still cannot be verified.

MCP v2 threads and request context

The default /mcp/ v2 gateway creates durable Genesis threads with ids such as mcp_<32-char-hex>. Genesis tags these threads with mcp_origin and records the authenticated MCP caller as owner when OAuth resolves a real user. Reuse the returned genesis_thread_id on every subsequent thread_continue, thread_get, call_tool, and related v2 action. MCP clients may send optional header X-Genesis-Thread-Id on HTTP MCP requests for request-scoped gateway context (not applied to resources/list). When a v2 action cannot proceed (for example thread_create with an inaccessible agent_id), the genesis tool returns structured error content with MCP isError set so clients surface a failed tool call instead of a silent success.

Admin Setup

  1. Sign in to Genesis as an admin.
  2. Open Config > Agent Gateways.
  3. Find Genesis MCP Gateway.
  4. Confirm readiness checks.
  5. Open the collapsed Admin setup (once per deployment) section under any client tab and copy the OAuth redirect URI for admins into your OAuth app/client if it is not already registered.
  6. If your role includes Config Panel access, click Test metadata and Test auth challenge.
  7. If callers will omit agent_id, set Default MCP agent and choose the If default is unavailable policy.
  8. Copy the coworker invite text.
The same checks are available from a terminal with:
Current under Default MCP agent shows the agent hosted MCP actually uses, including one set by the deployment setting GENESIS_MCP_DEFAULT_AGENT_ID; an agent chosen on the page overrides that setting. When a configured default is unavailable to the caller, require_selection asks them to choose from accessible agents, while first_available lets Genesis assign their first accessible agent automatically.

Coworker Setup

Give coworkers the remote MCP URL and the OAuth client ID:
They add it as a remote MCP server in Claude Code, complete the browser OAuth sign-in, then run:
Coworkers whose coding agents need to message each other (Claude Code or Cursor sessions on different laptops) can use rooms over this same endpoint. Rooms need sign-in turned on. See MCP Rooms for Coding Agents.

Troubleshooting

Legacy stdio note

The older stdio MCP sidecar is for developer-only local testing. It is not the recommended customer setup for hosted deployments.