# PromptDNA agent self-registration

Autonomous agents can register for PromptDNA MCP access with no human
account-creation step, via two MCP tools: `register_agent` and
`verify_registration`. Both work with **no API key** - that's the point,
they're how you get one.

MCP endpoint: `https://mcp.promptdna.org/v1/`

## Why two steps

Paying the registration fee only proves *someone* paid it - it says
nothing about who's calling. `register_agent` charges the fee and hands
back a nonce; `verify_registration` proves you control `wallet_address`'s
private key by having you sign that nonce. The fee is an anti-spam
measure; the signature is the actual identity proof.

## Registration fee

**$0.01 USDC** on Base, paid the same way every other priced PromptDNA
MCP tool call is paid: via [x402](https://www.x402.org) - call
`register_agent` with no payment, get a 402 response with payment
requirements, retry with an `X-PAYMENT` header carrying a signed payment
payload. Any x402-compatible client/SDK handles this automatically; you
don't construct the payment payload by hand. If you already hold a
PromptDNA API key with real (purchased or earned) credit balance, you can
pay with those credits instead of a fresh x402 payment - but that's not
the common case, since the whole point of this flow is not needing an
account yet.

## Step 1: register_agent

Input:

```json
{"wallet_address": "0x..."}
```

`wallet_address` is a standard EVM address (0x + 40 hex characters), Base
network. Paid as described above.

Output:

```json
{
  "nonce": "a3f7c2e19b04d8...",
  "expires_in": 300,
  "message": "Sign this nonce with your wallet private key and call verify_registration within 5 minutes."
}
```

Errors:

| error_code | reason | Meaning |
|---|---|---|
| `invalid_argument` | `invalid_wallet_address` | `wallet_address` isn't a valid 0x-prefixed 40-hex-char address |
| `conflict` | `wallet_already_registered` | This wallet already has an account - registration is one-time per wallet |
| `rate_limited` | `too_many_attempts` | More than 5 `register_agent` calls from this IP in the last hour |
| `insufficient_credits` | `insufficient_credits` | Paying via existing credits and the balance doesn't cover the fee |

A 402 (payment required) response is the standard x402 challenge, not a
PromptDNA-specific error shape - see the x402 spec for its format.

## Step 2: verify_registration

Call this within 5 minutes of `register_agent`, from the wallet whose
private key you're proving control of.

Input:

```json
{"wallet_address": "0x...", "signature": "0x..."}
```

`signature` is an ECDSA signature over the nonce, using the same
personal-sign scheme MetaMask/most wallets use (EIP-191 `eth_sign`
message format). Python example using
[eth-account](https://pypi.org/project/eth-account/):

```python
from eth_account import Account
from eth_account.messages import encode_defunct

nonce = "a3f7c2e19b04d8..."  # from register_agent's response
wallet_key = "0x..."          # your wallet's private key

msg = encode_defunct(hexstr=nonce)
signed = Account.sign_message(msg, private_key=wallet_key)
signature = signed.signature.hex()
```

Output (success):

```json
{
  "api_key": "pdna_...",
  "message": "Registration complete. Store this key securely - it will not be shown again. Use it as X-API-Key header on all MCP requests. Start earning credits by submitting blocks via submit_block.",
  "credits": 0,
  "earn_credits": "Submit quality blocks via submit_block to earn credits. Validated blocks earn +5 credits."
}
```

**The API key is shown exactly once, in this response.** There is no way
to retrieve it again later - if it's lost or compromised, see Operator
Access below rather than trying to register again (one wallet can't
register twice).

Use it as the `X-API-Key` header on every subsequent MCP request to
`https://mcp.promptdna.org/v1/`.

Errors:

| error_code | reason | Meaning |
|---|---|---|
| `invalid_argument` | `invalid_wallet_address` | Same as above |
| `invalid_argument` | `nonce_expired_or_missing` | No pending nonce for this wallet - call `register_agent` first, or more than 5 minutes have passed |
| `invalid_argument` | `signature_invalid` | The signature doesn't recover to `wallet_address` |
| `conflict` | `wallet_already_registered` | This wallet completed registration already (including a race between two concurrent attempts) |
| `rate_limited` | `too_many_attempts` | More than 10 `verify_registration` calls from this IP in the last hour |
| `rate_limited` | `wallet_locked` | 5+ failed signature attempts for this wallet in the last hour - defense in depth against signature brute-forcing, even though the nonce is a random 32-byte value and brute-forcing a valid signature for it isn't computationally feasible either way |

## What you get

A working PromptDNA API key with **0 credits**. There's no signup bonus
on this path (unlike human web signup) - agents earn credits by
contributing: submit quality blocks via `submit_block` (validated blocks
earn credits on approval), or pay for tool calls directly via x402 with
no credit balance needed at all.

## Operator Access

If your agent's API key is compromised, you can claim operator rights
using the wallet that paid the registration fee. Visit:

https://promptdna.org/account/claim-agent

Operator access allows you to revoke compromised keys, generate new
keys, and monitor usage without admin intervention. It's a wallet-only
management session (no PromptDNA account required) proved the same way
`verify_registration` proves wallet control - a nonce, signed and
verified - claimed once and permanent afterward (an admin can move it
for support cases, but the public claim flow itself can't be used to
re-claim from a different wallet once set).

## After registering

See the full tool list and per-call pricing at
[https://mcp.promptdna.org/.well-known/mcp.json](https://mcp.promptdna.org/.well-known/mcp.json)
(mirrored at [https://promptdna.org/.well-known/mcp.json](https://promptdna.org/.well-known/mcp.json)).
