# Authenticating an AI agent with Peetchr

Peetchr protects its MCP server (`https://app.peetchr.com/api/mcp`) with OAuth 2.1. An agent obtains a bearer token through the authorization-code flow with PKCE and dynamic client registration, then calls tools scoped to the recruiter organization that granted access. The discovery documents below follow the WorkOS `auth.md` conventions.

## Discover

Read the protected-resource metadata (RFC 9728) at `https://app.peetchr.com/.well-known/oauth-protected-resource/api/mcp`. It returns the `resource` (the MCP URL) and `authorization_servers` (`https://app.peetchr.com`). Calling the MCP endpoint without a token returns `401` with `WWW-Authenticate: Bearer resource_metadata="https://app.peetchr.com/.well-known/oauth-protected-resource/api/mcp"`, so one request is enough to learn the auth requirements. Fetch the authorization-server metadata (RFC 8414) at `https://app.peetchr.com/.well-known/oauth-authorization-server` for the issuer, endpoints, scopes, and PKCE support; register a client at the `register_uri` in the Register section below. peetchr.com also republishes this metadata with an `agent_auth` convenience block at https://peetchr.com/.well-known/oauth-authorization-server.

## Pick a method

Peetchr uses interactive, user-consented OAuth: the resulting token represents a real recruiter and their organization. Peetchr does **not** issue anonymous tokens, and it does not currently accept a pre-issued `identity_assertion` (for example an `urn:ietf:params:oauth:token-type:id-jag` / id-jag assertion) in place of the consent step. If your platform relies on id-jag identity assertions, contact hello@peetchr.ai.

## Register

Dynamically register an OAuth client (RFC 7591) by POSTing to the `register_uri`: `https://app.peetchr.com/api/auth/mcp/register`. Provide your `redirect_uris` (only https and loopback schemes are accepted). You receive a `client_id` and, for confidential clients, a `client_secret`. Token-endpoint auth methods: client_secret_basic, client_secret_post.

## Claim

Direct the recruiter to the authorization endpoint `https://app.peetchr.com/api/auth/mcp/authorize` with `response_type=code`, your `client_id`, `redirect_uri`, a PKCE `code_challenge` (`method=S256`), and the `scope` you need. The recruiter reviews and approves the consent screen - this is where a human "claims" the credential on the agent's behalf.

## Use the credential

Exchange the returned `code` at the token endpoint `https://app.peetchr.com/api/auth/mcp/token` (with your PKCE `code_verifier`) for an `access_token`. Send it as `Authorization: Bearer <access_token>` to `https://app.peetchr.com/api/mcp`. Request the least-privilege scope: `peetchr:recruiter` for read-only, `peetchr:recruiter:write` for actions that change data. With `offline_access` you also receive a refresh token.

## Errors

- `401 Unauthorized` with `WWW-Authenticate: Bearer` - missing, invalid, or expired token. Re-run discovery and re-authorize.
- `403 Forbidden` - the token lacks the scope for the requested tool; request the write or admin scope.
- `400 Bad Request` - malformed request; the body is JSON with an error code and message.
All error responses are JSON so an agent can parse the code and act without scraping HTML.

## Revocation

A recruiter can revoke an agent connection at any time from the Peetchr app integrations settings; revoked tokens stop working immediately. Refresh tokens rotate on use, and disconnecting the client invalidates its tokens. Store credentials securely and drop them on revocation.

