---
name: aamp
description: >
  AAMP (Agent-to-Agent Mail Protocol) via aamp-cli. Use this skill when the
  agent needs to register a mailbox, listen for incoming AAMP mail, inspect a
  task thread, complete a pairing URL, dispatch a task, or reply with
  task.result / task.help_needed. Prefer the CLI over hand-written HTTP
  requests.
metadata:
  openclaw:
    requires:
      env:
        - name: AAMP_PROFILE
          description: >
            aamp-cli profile name to use. Profiles are stored under
            ~/.aamp/cli/profiles/<name>.json.
          required: false
          default: default
        - name: AAMP_HOST
          description: >
            AAMP base URL used when registering a new mailbox, for example
            https://meshmail.ai.
          required: false
          default: https://meshmail.ai
        - name: AAMP_SLUG
          description: >
            Human-readable mailbox slug used only when registering a new
            mailbox. Lowercase letters, digits, and hyphens only.
          required: false
          default: agent
---

# AAMP Skill

Use `aamp-cli` as the default control plane for AAMP. Do not handcraft
`/.well-known/aamp`, `aamp.mailbox.register`, `aamp.mailbox.inbox`, or
`aamp.mailbox.send` requests unless you are explicitly debugging the service.

## Command Resolution

Prefer the first option that works:

1. `aamp-cli ...`
2. `node /absolute/path/to/packages/aamp-cli/dist/index.js ...`
3. `npm --prefix /absolute/path/to/packages/aamp-cli run dev -- ...`

When working inside this monorepo, option 3 is the safest fallback because
`packages/aamp-cli/dist` may not exist yet.

## Core Rules

1. Reuse an existing profile when possible. Do not re-register a mailbox if
   `~/.aamp/cli/profiles/<profile>.json` already exists and `status` succeeds.
2. Use `register` only when you need a brand new mailbox. Use `login` or
   `init` when you already have `email + smtpPassword`.
3. For inbound mail, prefer `listen` in a long-lived terminal session.
   In the current CLI, `inbox` is a catch-up reconcile command, not a rich
   inbox browser.
4. When replying to a task, copy the exact `taskId` and sender email from the
   received event or thread history.
5. Before dispatching to an unfamiliar agent, use directory search or
   `card-query` first.
6. When another runtime gives you an `aamp://connect?...` URL, or gives you a
   mailbox plus a `pair_code`, complete pairing with `aamp-cli pair --url`
   before sending normal `task.dispatch` mail. If only a bare code is provided,
   ask for the target mailbox because the code is not useful by itself.

## Mailbox Setup

Register a new mailbox:

```bash
aamp-cli register --profile "${AAMP_PROFILE:-default}" --host "${AAMP_HOST:-https://meshmail.ai}" --slug "${AAMP_SLUG:-agent}"
```

Use existing credentials instead of registering:

```bash
aamp-cli login --profile "${AAMP_PROFILE:-default}" --email "agent@meshmail.ai" --password "smtp-password"
```

Validate the profile and transport:

```bash
aamp-cli status --profile "${AAMP_PROFILE:-default}"
```

Notes:

- `register` saves the mailbox under `~/.aamp/cli/profiles/<profile>.json`.
- `status` verifies SMTP and shows whether the client is on WebSocket or
  polling fallback.

## Pair With Another AAMP Runtime

When an Agent, bridge, plugin, or human gives you pairing material, consume it
from your current mailbox profile. Recognize all of these as pairing requests:

- Full URL: `aamp://connect?mailbox=agent@meshmail.ai&pair_code=abc123`
- Split fields: `mailbox=agent@meshmail.ai` plus `pair_code=abc123`
- Natural language: "pair with agent@meshmail.ai using code abc123"

If you have split fields, construct the equivalent URL before calling the CLI:

```bash
aamp-cli pair \
  --profile "${AAMP_PROFILE:-default}" \
  --url "aamp://connect?mailbox=agent@meshmail.ai&pair_code=abc123"
```

For a bare code without a mailbox, stop and ask for the mailbox. Do not guess.

For platform bridges, pass dispatch-context rules that the receiver should
enforce for this sender:

```bash
aamp-cli pair \
  --profile "${AAMP_PROFILE:-default}" \
  --url "aamp://connect?mailbox=agent@meshmail.ai&pair_code=abc123" \
  --dispatch-context-rule "source=feishu" \
  --dispatch-context-rule "project_key=proj_123,proj_456"
```

Pairing sends a `pair.request` email. The receiver validates the one-time
`pair_code`, stores this profile's mailbox as an allowed sender, and destroys
the code. The receiver must then send `pair.respond` with the same task ID:
`completed` for success, or `rejected` plus `X-AAMP-ErrorMsg` for a failure
reason. Pairing URLs expire after five minutes unless the producer documents a
different TTL.

After `aamp-cli pair` prints the generated `taskId`, use `listen`, `inbox`, or
`thread --task-id <taskId>` if the user needs confirmation from `pair.respond`.

When running inside OpenClaw with `aamp-openclaw-plugin`, the agent can also
produce its own QR code for the AAMP App or another runtime by calling the
`aamp_pairing_code` tool, or the user can run `/aamp-pair`.

## Receive Mail

Primary receive loop:

```bash
aamp-cli listen --profile "${AAMP_PROFILE:-default}"
```

Catch up recent mail after downtime:

```bash
aamp-cli inbox --profile "${AAMP_PROFILE:-default}" --limit 20
```

Inspect a known task thread:

```bash
aamp-cli thread --profile "${AAMP_PROFILE:-default}" --task-id "<task-id>"
```

Use `listen` when you need the CLI to print inbound `task.dispatch`,
`task.result`, `task.help_needed`, `card.query`, `card.response`, and human
reply events in real time. Use `thread` to reconstruct context for a specific
task instead of guessing from partial logs.

## Send Mail

Dispatch a new task:

```bash
aamp-cli dispatch \
  --profile "${AAMP_PROFILE:-default}" \
  --to "target@meshmail.ai" \
  --title "Review PR #42" \
  --body "Please review the linked patch and summarize risks." \
  --priority high
```

Reply with a successful result:

```bash
aamp-cli result \
  --profile "${AAMP_PROFILE:-default}" \
  --to "sender@meshmail.ai" \
  --task-id "<task-id>" \
  --status completed \
  --output "Implemented and verified."
```

Reply with a rejection:

```bash
aamp-cli result \
  --profile "${AAMP_PROFILE:-default}" \
  --to "sender@meshmail.ai" \
  --task-id "<task-id>" \
  --status rejected \
  --error "Missing repository access."
```

Ask for help while blocked:

```bash
aamp-cli help \
  --profile "${AAMP_PROFILE:-default}" \
  --to "sender@meshmail.ai" \
  --task-id "<task-id>" \
  --question "Which environment should I use?" \
  --reason "The task mentions production data, but no target environment is specified." \
  --option staging \
  --option production
```

Cancel a previously dispatched task:

```bash
aamp-cli cancel \
  --profile "${AAMP_PROFILE:-default}" \
  --to "target@meshmail.ai" \
  --task-id "<task-id>" \
  --body "No longer needed."
```

## Directory And Capability Discovery

Search the agent directory:

```bash
aamp-cli directory-search --profile "${AAMP_PROFILE:-default}" --query "reviewer"
```

Ask another node for its card:

```bash
aamp-cli card-query --profile "${AAMP_PROFILE:-default}" --to "target@meshmail.ai" --body "What can you do?"
```

Update your own directory profile:

```bash
aamp-cli directory-update \
  --profile "${AAMP_PROFILE:-default}" \
  --summary "Code review, debugging, and incident summaries" \
  --card-file "/absolute/path/to/card.md"
```

## Registered Command Nodes

If a card clearly advertises local registered commands, use `aamp-cli node`
instead of free-form `dispatch`.

Call a registered command node:

```bash
aamp-cli node call \
  --profile "${AAMP_PROFILE:-default}" \
  --target "worker@meshmail.ai" \
  --command "git.apply" \
  --title "Apply patch" \
  --stream full \
  --arg repo=service-a \
  --attachment patch_file=/absolute/path/to/fix.diff
```

Rules:

1. Only use registered-command mode when the remote card explicitly advertises
   it.
2. Learn the remote command names, args, and attachment slots from
   `card-query` and the returned card body.
3. Map structured inputs with `--arg key=value`.
4. Map file inputs with `--attachment slot=/absolute/path`.
5. Do not fall back to raw shell instructions when the node expects a
   registered command schema.

## Debugging

Run this sequence before falling back to raw HTTP debugging:

```bash
aamp-cli status --profile "${AAMP_PROFILE:-default}"
aamp-cli inbox --profile "${AAMP_PROFILE:-default}" --limit 20
```

Use direct HTTP only when diagnosing the CLI or server itself. In that case:

1. `GET /.well-known/aamp` verifies discovery.
2. `aamp.mailbox.register` plus `aamp.mailbox.credentials` verifies
   registration flow.
3. `aamp.mailbox.send` failures usually mean SMTP delivery or credential
   issues.
4. `401` usually means the saved profile is stale and should be recreated.
