For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at /guide/mcp/authentication.md.

MCPAI Connect

Authentication

How MCP clients authenticate with OAuth 2.1 and PKCE: discovery, consent, the scope vocabulary, token lifetimes and what each error means.

/mcp/partner authenticates with OAuth 2.1 + PKCE. Your client obtains its own bearer token through a browser sign-in; there is no key to copy into a config file.

This replaced X-API-KEY

Earlier releases authenticated MCP with the X-API-KEY header. The primary endpoint no longer accepts it. See Legacy key path if you have an integration still on the old header.

#What you need before connecting

Two things, both handled once:

  1. MCP enabled for your workspace

    An administrator has to switch MCP on for the company and choose which scopes it may ever grant. Until that happens every authorization attempt is refused, regardless of who signs in. Contact support@orangescrum.com or your account manager to have it enabled.

  2. An Orangescrum sign-in

    You authorize as yourself, with email and password or Google sign-in. The assistant then acts with your permissions inside the workspace you picked. It cannot see projects you cannot see.

#The flow

Most clients run all of this for you after you paste the URL. It is worth knowing what the steps are when one of them fails.

  1. Discovery

    The client fetches the two well-known documents to learn where to send people and what scopes exist:

    bash
    GET https://v4-api.orangescrum.com/.well-known/oauth-protected-resource
    GET https://v4-api.orangescrum.com/.well-known/oauth-authorization-server
    

    The second advertises authorization_endpoint, token_endpoint, registration_endpoint, scopes_supported, and PKCE support (S256).

  2. Dynamic client registration

    The client registers itself and receives a client_id: no client secret, because it is a public client protected by PKCE:

    bash
    POST https://v4-api.orangescrum.com/oauth/register
    

    This is RFC 7591. You never do it by hand, and there is nothing to pre-provision on the Orangescrum side.

  3. Sign in and consent

    The client opens /oauth/authorize in your browser. You sign in if you do not already have a session, then land on a consent screen that shows the connecting client, the scopes it is asking for, and the MCP-specific part: a workspace picker listing every workspace you belong to that has MCP enabled.

    Pick one and authorize. The grant is bound to that single workspace.

  4. Token exchange

    The client exchanges its authorization code at /oauth/token with the PKCE verifier and receives an access token plus a refresh token.

  5. Calls

    Every subsequent MCP request carries the token:

    makefile
    Authorization: Bearer <access-token>
    

#Token lifetimes

TokenLifetimeNotes
Access token1 hourShort on purpose, so revoking access takes effect quickly
Refresh token30 daysRotated on every exchange; keeps you from re-consenting daily

Clients refresh silently. You will only see the browser again if you go 30 days without using the connection, or if access is revoked.

#Scopes

Two things have to agree before a scope is usable: your workspace must allow it, and you must approve it on the consent screen. A client asking for more than the workspace allows is clamped down to the allowed set rather than refused.

mcp:use is the base gate. Every request needs it, and it is what a client falls back to when it does not know the granular vocabulary.

ScopeGrants
mcp:useConnect at all, for the selected workspace. Required by every request
mcp:projects.readRead projects and project metadata
mcp:projects.writeCreate and update projects
mcp:tasks.readRead tasks, task lists, statuses and types
mcp:tasks.writeCreate, update, assign and close tasks
mcp:epics.writeCreate epics, features, stories and subtasks
mcp:sprints.readRead sprints and sprint plans
mcp:sprints.writeCreate, update, start and complete sprints; assign tasks to them
mcp:timelogs.readRead time entries and timesheets
mcp:timelogs.writeCreate and update time entries
mcp:users.readRead workspace members and user profiles
mcp:tests.readRead test cases, scenarios, steps and defects
mcp:tests.writeCreate, update, link and archive test cases, scenarios, steps and defects
mcp:checklists.readRead checklists, checklist groups and templates
mcp:checklists.writeCreate, update, complete and delete checklist items, groups and templates
mcp:context.readRead saved project/company context ("memory")
mcp:context.writeSave project/company context ("memory")
mcp:documents.readSearch uploaded documents

Reserved scopes in the discovery document

scopes_supported also advertises scopes with no tools behind them yet, mcp:users.write, mcp:teams.*, mcp:wiki.*, mcp:tickets.*, mcp:reports.read and others. They are registered ahead of the features that will use them. Granting one today grants nothing, and they are deliberately not offered in the workspace scope picker.

Users stay read-only

There is no tool to invite, deactivate or re-role a member. mcp:users.write exists in the vocabulary but nothing dispatches on it. Changing who has access to your workspace stays in the admin UI deliberately.

#Errors

Every failure carries a WWW-Authenticate header alongside a JSON-RPC error body. Clients that follow the OAuth challenge restart the flow automatically on invalid_token.

StatuserrorWhat happenedFix
401invalid_requestNo bearer token was sentLet the client run the OAuth flow; check it is not still sending X-API-KEY
401invalid_tokenToken expired, revoked or signature invalidReconnect, normally automatic on refresh
401invalid_tokenNo consent recorded for this tokenRe-authorize; the workspace selection never completed
403insufficient_scopeToken lacks mcp:useRe-authorize and approve the base scope
403invalid_tokenAudience mismatchThe token was issued for a different resource. Reconnect against this URL
403invalid_tokenWorkspace entitlement disabled or revokedAsk an administrator to re-enable MCP for the workspace
403n/aTool called without its scopeRe-authorize with the scope named in the error
429n/aRate limitedSee rate limits

A per-tool scope failure names the scope it wanted, for example "requires the mcp:sprints.write scope". That is the signal to re-authorize with a wider grant, or to ask an administrator to widen what the workspace allows, if the scope is not on offer.

#Rate limits

120 requests per minute and 5,000 per day, returned as JSON-RPC error code -32500 with HTTP 429.

The MCP limit is counted per IP address

Unlike the REST limits, which are counted per API key, the MCP limiter keys on the calling IP, MCP clients do not always present a credential during the initialize handshake. Everyone connecting from the same office NAT or VPN egress shares one bucket, so a colleague's bulk run can rate-limit you.

#Protocol versions

The server negotiates these MCP spec revisions during initialize:

yaml
2025-11-25 · 2025-06-18 · 2025-03-26 · 2024-11-05

A client offering something newer will fail the handshake immediately after OAuth succeeds, which looks like an auth problem but is not. If you see that after a client update, say so when you report it.

#Legacy key path

A second endpoint still accepts the old header, for integrations mid-migration:

bash
POST https://v4-api.orangescrum.com/mcp/partner-legacy
X-API-KEY: YOUR_KEY

It serves the identical tool set. Two things to know before you reach for it:

  • It is feature-flagged and not guaranteed to stay available. OAuth is the supported path going forward.
  • A partner key has no scope vocabulary and no consent screen, so the per-tool safety boundary described above does not apply to it in the same way.

Do not build new integrations against it

If you are connecting a client today, use /mcp/partner and OAuth. Treat /mcp/partner-legacy as a migration aid with a limited life.

#Where next