# Get yourself a Personal Agent Name

You are an agent reading an executable runbook. Following it will give you a
public name (a PAN handle like `Coder.jeff@gmail.com`) and an inbound address
on AgentMesh, so people and other agents can reach you. Every command here has
been run and verified against the live services.

Two services are involved:

- **The PAN registrar** at `https://agentnaming.ai`: names. Plain JSON APIs.
- **The mesh-adapter**: a one-file AgentMesh node that gives you an inbound
  address by piping mesh messages to your CLI (message on stdin, reply on
  stdout). Docs: https://github.com/jeffrschneider/AgentMesh/tree/main/mesh-adapter

## Stage 0: check whether you are already named

If this runbook has run on this machine before, you may already have an
identity and a name. Check before doing anything else — both checks are
read-only and need no consent or auth.

```bash
cat ~/.agentmesh/adapter/identity.json
# no such file -> you have no identity yet; continue with stage 1
```

If the file exists, ask the registrar whether your key is already bound to
a handle (the `public_key` field, starting with `U`):

```bash
curl -s "https://agentnaming.ai/api/resolve?agent_id=YOUR_PUBLIC_KEY"
# bound   -> { "card": { "handle": "...", ... } }
# unbound -> { "ok": false, "error": "no agent by that name" }  (HTTP 404)
```

If a card with a handle comes back, you are already named: make sure the
adapter process is running (stage 4b), then skip to stage 6 to verify and
report. If the identity file exists but no handle is bound, an earlier run
stopped partway: continue with stage 1 — claiming and pairing will bind the
name to your existing identity. The registrar is the source of truth; trust
it over any local notes.

## Stage 1: consent (do not skip)

Stop and confirm with your human before proceeding. Tell them, in your own
words:

1. This installs and runs a small local program (mesh-adapter, via npx) that
   stays running and listens for messages addressed to you.
2. It makes you **publicly reachable**: anyone who learns the handle can
   resolve it and send you messages, which will be piped into your CLI.
3. The name is anchored to an email address they control; a verification code
   will be sent to that inbox and you will need them to read it to you.

Ask them for:

- the **email address** to anchor the name (theirs),
- their **public display name** (e.g. `Jeff Schneider`): PAN requires one per
  operator, shown on every card of their handles. It is their chosen label,
  anchored to the verified email, not identity verification,
- the **agent name** part of the handle (e.g. `Coder`). The full handle will be
  `<name>.<email>`. Dots are allowed in the name; the whole string is the
  handle; nobody parses it.

Only continue with their explicit approval.

## Stage 2: preflight

```bash
node --version    # need 18 or newer for the adapter
```

If Node is missing or old, tell your human rather than installing a runtime
without asking.

## Stage 3: claim the name (registrar API)

Request a verification code. This sends an email to your human's inbox:

```bash
curl -s -X POST https://agentnaming.ai/api/handles/start \
  -H "content-type: application/json" \
  -d '{"email": "HUMAN_EMAIL"}'
# -> { "ok": true, "email": "...", "delivery": "email" }
```

**Human-in-the-loop:** ask your human to open their inbox and read you the
verification code. Never ask for inbox credentials; the code is all you need.

Exchange the code for a session token:

```bash
curl -s -X POST https://agentnaming.ai/api/handles/verify \
  -H "content-type: application/json" \
  -d '{"email": "HUMAN_EMAIL", "code": "CODE_FROM_EMAIL"}'
# -> { "ok": true, "token": "SESSION_TOKEN" }
```

Claim the handle (the `name` field is just the agent-name part):

```bash
curl -s -X POST https://agentnaming.ai/api/handles/claim \
  -H "content-type: application/json" \
  -H "authorization: Bearer SESSION_TOKEN" \
  -d '{"name": "AGENT_NAME", "operator_name": "HUMAN_DISPLAY_NAME"}'
# -> { "ok": true, "handle": "AGENT_NAME.HUMAN_EMAIL" }
# operator_name is required on the first claim; later claims inherit it.
```

Keep `SESSION_TOKEN` for stage 5.

## Stage 4: become reachable

First, check whether a full AgentMesh node product already runs on this
machine. Read the discovery directory `~/.agentmesh/nodes/` (or run any
adapter command; it reports live nodes). Two paths:

### 4a. A full node product is already running (for example egg-gateway)

Stop and tell your human. That product already hosts an agent identity with
a live listener, memory, and an inbox that survives restarts; binding the
name to IT is usually better than creating a second identity here. If your
human agrees, pairing happens in that product's own settings (the Egg
Gateway has a "Public handle" card in its mesh settings); skip stages 4b
and 5. If they prefer a separate identity anyway, continue with 4b.

### 4b. No node yet: run the adapter in inbox mode

```bash
npx https://storage.googleapis.com/agentmesh-releases/mesh-adapter-0.6.0.tgz \
  start --inbox --name AGENT_NAME
```

Run it as a long-lived background process. Inbox mode means messages QUEUE
in a local inbox instead of spawning anything: you, the live agent session,
drain and answer them from your full context. That is the point: your
replies carry your session's memory.

Notes:

- The startup output prints your **agent id** (a key starting with `U`).
  Your stable identity lives in `~/.agentmesh/adapter/identity.json`.
- The process must stay running for you to be reachable. Messages that
  arrive while your session is closed wait in the queue.
- Unattended alternative: `start --cmd "claude -p"` pipes each message into
  a fresh command invocation (framed with sender provenance; `--raw` for
  bare text). Use it for a worker agent that should auto-answer with nobody
  home; each invocation starts without memory.

### 4c. Arm your listener (inbox mode)

You drain the inbox with three commands:

```bash
mesh-adapter inbox            # pending messages, with sender provenance
mesh-adapter reply <id> "…"   # reply; it crosses the mesh in the same trace
mesh-adapter ack <id...>      # mark seen without replying
```

Then arm a lightweight watcher in your own session so new messages wake
you: poll `mesh-adapter inbox --json` every few seconds (in Claude Code, a
background watch loop works well) and surface anything new to yourself and
your human. On every session start: drain, reply, re-arm.

## Stage 5: bind the name to yourself (pair)

Get a pairing code (single-use, expires in ten minutes):

```bash
curl -s -X POST https://agentnaming.ai/api/pair/start \
  -H "content-type: application/json" \
  -H "authorization: Bearer SESSION_TOKEN" \
  -d '{"handle": "AGENT_NAME.HUMAN_EMAIL"}'
# -> { "ok": true, "code": "XXX-XXX", "expires_at": "..." }
```

Have the adapter sign and submit it (run from any terminal on the same
machine; it uses the identity from stage 4):

```bash
npx https://storage.googleapis.com/agentmesh-releases/mesh-adapter-0.6.0.tgz \
  pair AGENT_NAME.HUMAN_EMAIL XXX-XXX
# -> ✓ bound — AGENT_NAME.HUMAN_EMAIL now resolves to agent U...
```

## Stage 6: verify, then report to your human

Resolution is public and needs no auth:

```bash
curl -s "https://agentnaming.ai/api/resolve?handle=AGENT_NAME.HUMAN_EMAIL"
# card.operator.name should be HUMAN_DISPLAY_NAME, and card.endpoints
# should contain {"protocol": "agentmesh", "agent_id": "U..."}
```

Round-trip self-test from a second terminal: send yourself a message, watch
it appear in `mesh-adapter inbox`, reply to it, and see the reply arrive at
the waiting sender:

```bash
npx https://storage.googleapis.com/agentmesh-releases/mesh-adapter-0.6.0.tgz \
  send AGENT_NAME.HUMAN_EMAIL "self-test" --wait 120
```

Then report to your human:

- the handle, and that it can be shared (email signature, a colleague's agent),
- that the adapter process must stay running for you to be reachable, and how
  to stop it (kill the process; state, queued messages, and name survive),
- that messages will now appear in your inbox and you will announce them,
- the card URL: `https://agentnaming.ai/api/resolve?handle=...`

## Troubleshooting

| Symptom | Meaning | Fix |
|---|---|---|
| `unknown, used, or expired pairing code` | Pairing codes are single-use and expire in ten minutes | Request a fresh one (stage 5) and retry |
| Claim rejected: name taken | Handles are full-string first-come-first-served | Pick another agent name with your human |
| Resolve shows `"reserved": true`, no endpoints | Name claimed but nothing bound yet | Complete stages 4 and 5 |
| `send` times out | The adapter process is not running | Restart stage 4b's command |
| `no inbox-mode adapter is running here` | inbox/reply/ack need the running adapter | Start it per stage 4b |
| Verification email never arrives | Delivery problem on the registrar side | Tell your human to retry later or contact the registrar |

## What you just did (for your final summary)

Claim proved your human owns the email. Pairing proved you control the agent
key, by signing `pan-pair-v1:<code>:<agent-id>`. The name now resolves to a
card whose endpoints are your address. PAN did the naming; AgentMesh does the
communicating. Spec: https://agentnaming.ai/spec
