MCP self-service prompt for OAuth Client ID creation

Organization administrators can create a public PKCE OAuth Client ID for their application through the ezeep MCP server — no curl, no support ticket. The MCP exposes a register_oauth_client tool that reuses an existing client if the requested redirect URIs are already covered and otherwise creates a new one, all inside a conversation with your MCP-aware client (Claude Desktop, Claude Code, GitHub Copilot, Cursor).

This page walks through the prompt an org admin can paste, what to have on hand before running it, and what to do with the returned Client ID. It is complementary to Managing OAuth clients — that page documents the underlying REST endpoint for admins who prefer to call the API directly, or who need a confidential client (which the MCP self-service flow does not create).

Before you start

You will need:

  • An organization-admin ezeep account connected to your MCP client. The tool requires the connection to hold accounts scope; the server rejects non-admin connections with a message telling you to reconnect.
  • A decision on your redirect URI(s). Exact-match URLs where ezeep sends the user back after they sign in — for example https://your-app.example.com/oauth/callback. HTTPS only, except http://localhost is allowed. No wildcards, no fragments. You can register multiple (dev + prod) in one call. The MCP tool is stricter than the raw REST endpoint here — if you need a native-scheme redirect (e.g. com.example.app://cb) for a mobile or desktop app, use Managing OAuth clients directly instead.
  • A decision on tenancy. single (default) restricts sign-in to users of your own ezeep organization; multi allows users from any ezeep organization to sign in. This is immutable after creation — get it right the first time.
  • A decision on scopes (optional). If omitted, the tool defaults to printing.print printing.documents.upload printing.printers.readonly openid profile, which covers a standard “user prints from my app” integration.

If you have not connected the MCP yet, see ezeep MCP Server for the one-minute setup.

Step 1 — Connect the MCP with an org-admin account

Follow the OAuth setup for your MCP client on the ezeep MCP Server page, and sign in with an ezeep account that has organization-admin role. The MCP session will then hold the accounts scope that register_oauth_client requires.

To verify, ask your MCP client:

Check my ezeep account — what roles and scopes does this MCP connection have?

The assistant will call get_token_info (which returns the current MCP connection’s scopes, roles, and expiry from the JWT claims) and report them. If accounts scope is not present, disconnect the MCP and reconnect with an admin account before continuing.

Step 2 — Paste the prompt

Send this to your MCP-aware client, filling in the four bracketed values:

I’m the ezeep org admin. Please register a new public PKCE OAuth client for my application by calling the register_oauth_client tool with:

  • name: [your app name, e.g. Acme Print Portal]
  • redirect_urls: [list every callback URL — dev and prod — e.g. https://app.acme.example/oauth/callback, http://localhost:3000/oauth/callback]
  • tenant_mode: [single for users of my org only, or multi for users of any ezeep org]
  • external_description: [one short sentence shown on the consent screen]

Use the default allowed_scopes unless the redirect URLs I gave you obviously need more. If a public PKCE client already exists in my org whose redirect URLs cover all of the above, reuse it and tell me its client_id — don’t create a duplicate.

Step 3 — What the tool returns

The MCP responds with a JSON object containing your client_id and a reused flag:

{
    "client_id": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789AbCd",
    "redirect_urls": ["https://app.acme.example/oauth/callback"],
    "tenant_mode": "single",
    "reused": false,
    "note": "Created a new public PKCE client. NO client_secret — PKCE protects it. The client_id is public (safe to store in app config); only refresh tokens are secret. tenant_mode is IMMUTABLE after creation."
}
  • reused: true means the tool found an existing public PKCE client in your organization whose redirect_urls cover everything you asked for and returned that instead of creating a new one. This is intentional: a fresh client_id on every build would invalidate every existing user’s refresh tokens and eat into the per-organization client cap.
  • There is no client_secret. Public PKCE clients are protected by PKCE at exchange time, not by a shared secret. The client_id is safe to embed in your app’s frontend or CLI.

Step 4 — Use the Client ID in your app

Wire the returned client_id into your Authorization Code + PKCE flow as documented in Authorization Code Flow with PKCE. The token exchange goes to https://account.ezeep.com/oauth/access_token/ with the client_id in an Authorization: Basic base64("<client_id>:") header (trailing colon, no secret).

Clients created via register_oauth_client have refresh-token rotation enabled by default: each refresh_token is single-use, and the exchange returns a new one that must replace the stored value. Store per-user tokens in a writable database row, overwrite each row on rotation, and do not commit tokens to a repository or hold them in shared platform secrets. Rotation is a per-client setting — the sandbox client (demo and ad hoc scripting only) has rotation disabled and follows different storage rules; see the API Token Generator.

Failure modes and what they mean

Response from the MCP Meaning
“This MCP connection doesn’t have accounts scope…” You are not signed in as an org admin. Disconnect the MCP and reconnect with an admin account.
“The connected account isn’t an org admin (or lacks accounts scope)…” Same as above — your account either isn’t admin or the scope wasn’t granted at consent.
“The OAuth-client management API is not enabled in this ezeep environment…” The OAuth-client management API is enabled deployment-wide on ezeep production, so this message is a generic fallback. If you see it, email ezeep support at support@ezeep.com.
“Per-org client cap reached.” Your organization has hit its OAuth-client limit. Reuse an existing client_id or delete an unused client — see Managing OAuth clients.
redirect_url … contains a fragment / wildcard / must be HTTPS Fix the offending URL and retry. Only HTTPS URLs and http://localhost are accepted; no #, no *.

When to use the REST endpoint instead

Use Managing OAuth clients directly (rather than this MCP prompt) when:

  • You need a confidential client — one that carries a client_secret for server-to-server flows. The MCP self-service prompt only creates public PKCE clients.
  • You want to script client creation as part of an automated onboarding pipeline.
  • You need to update, list, or delete existing clients (the MCP tool only registers or reuses).