The mental model
The important structural fact: each MCP gateway is its own OAuth authorization server. There is no single account-wide OAuth server that hands out tokens good everywhere. A connected app can be bound to one issuing authorization server. You pick it at registration; it is set once and cannot be changed afterwards. A token grant against a gateway verifies that the authorization server receiving the request is the one the client is bound to before it will mint anything, so a token cannot be carried from one gateway to another. That binding is separate from the app’s list of permitted audiences, which is a mutable allowlist. One answers “which server minted this credential”; the other answers “which resources may it name”. Both are checked.How an app gets registered
Dynamic client registration. A gateway in the default auth mode exposes/oauth/register. A client that supports OpenID Connect dynamic registration can register itself on first use, with no manual step.
Manually, in the Portal. Create the client under Settings → Connected Apps: a name, a client type, an issuing gateway, redirect URIs, allowed scopes, a token endpoint auth method.
What you configure
The scopes are
mcp and profile. There are no read / execute / manage / admin / offline_access scopes anywhere on Noorle — what a token may do comes from the principal behind it, not from a scope string.authorization_code and refresh_token; a confidential client gets those two plus client_credentials. Enforcement is fail-closed — a grant the client is not registered for is refused.
Status
Revoke is one-way. A revoked client cannot be reactivated — it is a kill switch, not a step in a suspend/resume cycle. Use suspend if you might want the app back.
Who can manage them
Owner, Admin, and Member can create, read, and update connected apps. Delete requires Delete authority, which a Member’s role does not grant. Restricted principals are excluded unless an explicit grant says otherwise.The authorization flow
The gateway performs all protocol validation — client identity, that the redirect URI is registered, PKCE, the resource indicator — before any human sees anything. Only then is the human handed to the Portal for consent, carrying an opaque handoff id and nothing else. The consent page has no ability to influence the protocol parameters, because it never receives them. After consent, the browser returns to your redirect URI with an authorization code, which your backend exchanges at the gateway’s token endpoint. Two details of that gateway endpoint worth knowing:- PKCE is S256 only.
plainis not offered. - The gateway advertises
authorization_response_iss_parameter_supported, so a client can confirm which authorization server answered.
Building against it
Register the redirect URI exactly. It is matched against the registered list; a trailing slash difference is a mismatch. The one exception is loopback: for alocalhost or 127.0.0.1 URI the port may differ from the one you registered, so a CLI that picks a free port does not have to register every one. Scheme, host, path, and query still have to match.
Use PKCE even for confidential clients. It is required for public clients and costs nothing for the rest.
Verify state on the way back. Noorle does not do CSRF protection on your behalf for your own redirect.
Keep a client secret server-side. If your app cannot, it is a public client — register it as one, with none as the token endpoint auth method and PKCE doing the work.
Handle 401 by re-authorizing, not by retrying. A revoked or suspended client will never succeed on retry.
Troubleshooting
Next: Roles and Permissions.