# auth.md: Pain in the Agent

Connect an agent to the remote MCP resource at https://painintheagent.com/mcp.
It rewrites and humanizes supplied drafts, compares versions, checks AI writing
signals and retrieves results by run ID. Every successful operation uses the
same account allowance; none proves authorship or detects private vendor watermarks.
Read https://painintheagent.com/privacy/ before sending text. This service cannot verify Claude
or Gemini's private watermark keys or guarantee acceptance by a detector.

## Discover

Read https://painintheagent.com/.well-known/oauth-protected-resource/mcp, then the listed
authorization server's metadata at https://painintheagent.com/.well-known/oauth-authorization-server.
Use the exact resource value from metadata in token requests.
The service supports rewrite:read and rewrite:write.

The root metadata at https://painintheagent.com/.well-known/oauth-protected-resource identifies
this same MCP service as https://painintheagent.com. The authorization server accepts that
domain identifier with or without a trailing slash and maps it to
https://painintheagent.com/mcp before issuing a token. Token audiences remain limited
to the MCP endpoint. The metadata at the path ending in /mcp uses that endpoint
as its resource identifier directly.

Interactive MCP clients can use Authorization Code with S256 PKCE at
https://painintheagent.com/oauth/authorize. The user signs in to the existing website account
and selects permissions. Use the published token endpoint for code exchange
and refresh. Access tokens expire after 15 minutes; refresh credentials and
the connection expire after 30 days. Client ID Metadata Documents are supported;
https://painintheagent.com/oauth/register also supports clients using Dynamic Client Registration.

## Agent registration

For the Auth.md claim flow, use the service's identity endpoint:

POST https://painintheagent.com/agent/identity
Content-Type: application/json

If the user has supplied an email, ask them to confirm the service and requested
permissions before sending it. Send this JSON body.

```json
{"type":"service_auth","login_hint":"user@example.com"}
```

The response contains registration_id, claim_token and a claim object with
verification_uri, user_code, expires_in and interval. No credential is issued
before the user confirms. This step does not send an email or create an account.
The user signs in through the existing website when opening the verification URL.

If no user identity is available, send {"type":"anonymous"}. The response
contains an identity_assertion and claim_token. A pre-claim token can discover
MCP capabilities; it cannot read account data or start rewrites. To begin a claim,
POST {"claim_token":"...","email":"user@example.com"} to
https://painintheagent.com/agent/identity/claim after obtaining the user's permission to send the email.
This endpoint returns the ceremony fields in claim_attempt.

Only anonymous and service_auth are supported. This service does not accept
provider-issued ID-JAG assertions or upstream identity events.

## Claim and collect the credential

Show the verification_uri and six-digit user_code to the user. The user must
sign in with the specified email, enter the code on the service-owned page and
select permissions. Do not enter the code or approve on the user's behalf.
The code expires in ten minutes and locks after five wrong attempts. Requesting
a new attempt at the claim endpoint invalidates the old link. A pending
registration cannot be rebound to a different email.

Poll https://painintheagent.com/oauth/token with an application/x-www-form-urlencoded body:

grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=...

Wait at least the advertised interval of five seconds between polls. Handle
authorization_pending by waiting, slow_down by increasing the interval, and
expired_token by requesting a fresh claim attempt. The outer claim token expires
after 24 hours. Keep it private and discard it after completing the ceremony.

After confirmation, the response contains access_token, token_type, expires_in,
scope, identity_assertion and assertion_expires. Preserve the actual granted
scope; the user may have declined write access. Store credentials only in the
client's protected credential store and do not put them in conversation text.

## Renew and use access

For this claim flow, renew an expired access token by POSTing to the token endpoint:

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=...&resource=https://painintheagent.com/mcp

The service-signed identity assertion lasts up to 24 hours and may be exchanged
again during that window. This flow does not issue refresh_token. After the
assertion expires, repeat registration and the claim ceremony. Pre-claim
assertions and access tokens stop working when ownership is confirmed.

Send the credential in Authorization: Bearer ... to https://painintheagent.com/mcp.
Initialize the MCP connection and read tools/list. get_limits reads the shared
account allowance. start_rewrite requires text and a caller-generated UUID run_id;
generate the ID once and reuse it for the same input after a lost response.
start_humanize creates a watermark-free AI rewrite. The optional watermark_removal
field remains accepted for compatibility, but watermark-free rewriting is always included. start_watermark_comparison
accepts source_text and candidate_text. start_ai_detection accepts at least 50 words
of English or Russian prose. All start tools require a caller-generated run_id
and rewrite:write permission. get_result (or the earlier get_rewrite name)
retrieves progress or the saved result with rewrite:read permission. Processing continues after
the MCP connection closes. An interrupted execution is reported instead of
automatically submitting the text to a model again.

Account API keys from https://painintheagent.com/integrations/ also work with remote MCP and the
REST API documented at https://painintheagent.com/openapi.json.

## Revoke

POST token=... to https://painintheagent.com/oauth/token/revoke as application/x-www-form-urlencoded
to revoke an individual access token. An unknown or already revoked token returns
HTTP 200. OAuth clients also authenticate using their registered client method.
Revoking one claim-flow token leaves the underlying identity assertion active.
The user can revoke the whole connection at https://painintheagent.com/integrations/; this blocks
its tokens and future exchanges immediately. A rewrite already processing may finish.
On invalid_token, stop using the credential and obtain new authorization from the user.
