What OAuth is used for
OAuth here follows the standard authorization code grant with PKCE. A user signs in and approves your application once; your application then holds a short-lived access token (plus a longer-lived refresh token) that acts as that user for as long as they stay connected. Every request made with the resulting token is scoped to that one user’s permissions and organization, the same as if they were using the API directly.Getting a client
OAuth clients for MCP platforms register themselves automatically through dynamic client registration — most AI agents need no manual setup at all. Self-service creation of OAuth clients for general integrations is coming to the Contractors Cloud web app. Until then, contact Contractors Cloud support to have a client provisioned for your integration.The authorization flow
Request authorization
Redirect the user’s browser to the authorize endpoint:Hosted login and consent
- If the user isn’t signed in, they land on the Contractors Cloud login page, then continue on to consent after signing in.
- If they’re already signed in, they see a consent screen listing your application and the scopes it’s requesting, with Approve and Deny buttons.
- If they’ve previously approved this exact client and scope combination, the consent screen is skipped and they’re redirected straight back to your
redirect_uriwith a fresh authorization code.
The callback
On approval, the user’s browser is redirected to yourredirect_uri with a code and the state you sent:
error=access_denied. Verify the returned state matches what you sent before you do anything else with the code.
Exchange the code for tokens
Using the access token
Include the access token as a bearer token on every API request:Refreshing an access token
When the access token expires, exchange the refresh token for a new pair instead of asking the user to sign in again:Token lifetimes
Scopes
Request the minimal scopes you need — only ask for the
read, write, or mcp:use scopes your application actually uses.
PKCE for public clients
Public clients — those without a client secret — must use PKCE (RFC 7636) on every authorization request:- Generate a random
code_verifier: 43–128 characters fromA-Z,a-z,0-9,-,.,_,~. - Derive
code_challenge = base64url(sha256(code_verifier))and send it, along withcode_challenge_method=S256, on the authorization request. - Send the original
code_verifier(not the challenge) in the token exchange, in place of aclient_secret.
S256 is accepted — plain (or an omitted code_challenge_method) is rejected with an invalid_request error, as is an authorization request from a public client with no code_challenge at all.
Confidential clients (those with a secret) can use PKCE too, as defense in depth, but it’s optional for them.
Dynamic client registration
MCP clients that discover theregistration_endpoint from discovery can self-provision an OAuth client automatically, with no manual setup:
mcp:use scope. A client registered this way can connect an AI agent through MCP, but can’t request read or write access. redirect_uris must use callback addresses from approved platforms — contact support to add yours.
Native clients (such as Claude Code) that receive the OAuth callback on a loopback address use an ephemeral port chosen at connect time, so the exact port isn’t known when the client registers. A loopback redirect URI (http://localhost, http://127.0.0.1) matches regardless of port — register once, and connect using whichever port your client happens to bind that session.
Discovery
Both are unauthenticated and let a compliant client bootstrap the OAuth flow without any out-of-band configuration. An unauthenticated request to the MCP endpoint returns
401 with a WWW-Authenticate header pointing at the protected-resource metadata URL: