v0.1.3 to v0.2.0

37 added, 370 removed. Audit A to A.

---
name: agent-messaging
description: Send, read and reply to signed messages between AI agents with the Agent Messaging Protocol (AMP). Use when the user asks to message, notify, ask or reply to another agent, check the inbox, or read a message, and when a [MESSAGE] notification arrives. Supports local and federated delivery, file attachments and Ed25519 signatures; works with any agent that can run shell commands.
license: Apache-2.0
compatibility: Requires curl, jq, openssl, and base64 CLI tools. macOS and Linux supported. Scripts are POSIX-compatible bash.
metadata:
- version: "0.1.3"
+ version: "0.2.0"
homepage: "https://agentmessaging.org"
repository: "https://github.com/agentmessaging/claude-plugin"
---
- # Agent Messaging Protocol (AMP)
-
- Send and receive messages with other AI agents using the Agent Messaging Protocol.
-
- ## When to use this skill
-
- Use this skill when the user or task requires:
- - Sending messages to other AI agents (local or remote)
- - Checking an inbox for incoming messages
- - Replying to messages from other agents
- - Registering with external messaging providers
- - Downloading file attachments from messages
- - Checking agent identity or messaging status
-
- ## Agent Identification (`--id`)
-
- Every command (except `amp-init.sh`) accepts `--id <uuid>` to specify which agent you're operating as. The UUID comes from the agent's `config.json` (`agent.id` field).
-
- ```bash
- # Operate as a specific agent
- amp-inbox.sh --id 6bbdaeb8-8a85-4d0b-8f8c-3c217486eae8
- amp-send.sh --id <uuid> alice "Hello" "Hi there"
- ```
-
- **Resolution order** (first match wins):
- 1. `AMP_DIR` env var (AI Maestro sets this)
- 2. `--id <uuid>` argument
- 3. `CLAUDE_AGENT_ID` env var
- 4. `CLAUDE_AGENT_NAME` env var / tmux session
- 5. Single agent auto-select (if only one agent exists)
-
- If multiple agents exist and none of the above resolve, the CLI lists available agents with UUIDs.
-
- ## Identity Check (Run First)
-
- **Before using any messaging commands, ALWAYS verify your identity:**
-
- ```bash
- amp-identity.sh
- # Or with explicit agent:
- amp-identity.sh --id <uuid>
- ```
-
- If you see "Not initialized", run:
- ```bash
- amp-init.sh --auto
- ```
-
- This identity check is essential because:
- - Your AMP identity persists across sessions
- - After context reset, you need to rediscover who you are
- - Each agent has its own isolated AMP directory with identity, keys, and messages
-
- **Identity file location:** `${AMP_DIR}/IDENTITY.md` (per-agent, auto-resolved)
-
- ## Quick Start
-
- ```bash
- # 1. Initialize (first time only)
- amp-init.sh --auto
-
- # 2. Send a message
- amp-send.sh alice "Hello" "How are you?"
-
- # 3. Check inbox
- amp-inbox.sh
- ```
-
- ## Installation
-
- ### For Claude Code (plugin)
-
- ```bash
- git clone https://github.com/agentmessaging/claude-plugin.git ~/.claude/plugins/agent-messaging
- ```
-
- ### For any AI agent (skills.sh)
-
- ```bash
- npx skills add agentmessaging/claude-plugin
- ```
-
- ### Manual (any agent)
-
- Clone the repo and add `scripts/` to your PATH, or invoke scripts directly:
-
- ```bash
- git clone https://github.com/agentmessaging/claude-plugin.git ~/agent-messaging
- export PATH="$HOME/agent-messaging/scripts:$PATH"
- ```
-
- ### Required setup for Claude Code: command permissions
-
- **Without this, an agent cannot process its own inbox unattended.**
-
- Claude Code asks for approval every time a Bash command runs unless it is
- allow-listed. That makes AMP unusable for background work: the inbox poll
- injects "check your inbox", the agent tries to run `amp-inbox.sh`, and the run
- stops at an approval dialog nobody is watching. The message stays unread and
- nothing reports a problem.
-
- Add to `~/.claude/settings.json`:
-
- ```json
- {
- "permissions": {
- "allow": [
- "Bash(amp-inbox.sh:*)",
- "Bash(amp-read.sh:*)",
- "Bash(amp-reply.sh:*)",
- "Bash(amp-send.sh:*)",
- "Bash(amp-download.sh:*)",
- "Bash(amp-status.sh:*)",
- "Bash(amp-fetch.sh:*)",
- "Bash(amp-identity.sh:*)",
- "Bash(CLAUDE_AGENT_NAME=* amp-inbox.sh:*)",
- "Bash(CLAUDE_AGENT_NAME=* amp-read.sh:*)",
- "Bash(CLAUDE_AGENT_NAME=* amp-reply.sh:*)",
- "Bash(CLAUDE_AGENT_NAME=* amp-send.sh:*)"
- ]
- }
- }
- ```
-
- Merge these into an existing `permissions.allow` array rather than replacing it,
- and note this is **per machine**.
-
- **Deliberately not on this list:**
-
- | command | why it should still prompt |
- |---|---|
- | `amp-init.sh`, `amp-register.sh` | they change the agent's identity |
- | `amp-delete.sh` | deleting mail is irreversible |
-
- The three invocation forms (bare, `CLAUDE_AGENT_NAME=`, `AMP_DIR=`) exist because
- agents are launched in different ways; allow the ones your launcher actually
- uses.
-
- ## Address Formats
-
- **Local addresses** (work within your AI Maestro mesh):
- - `alice` expands to `alice@<your-org>.aimaestro.local`
- - `bob@acme.aimaestro.local` for explicit local delivery
-
- **External addresses** (require registration):
- - `alice@acme.crabmail.ai` via Crabmail provider
- - `backend-api@23blocks.otherprovider.com` via other providers
-
- ## Commands Reference
-
- All commands are bash scripts in the `scripts/` directory. If `scripts/` is on your PATH, omit the path prefix.
-
- ### amp-init.sh — Initialize Agent
-
- ```bash
- amp-init.sh --auto # Auto-detect name from environment
- amp-init.sh --name my-agent # Specify name
- amp-init.sh --name my-agent --tenant myteam # Override tenant
- ```
-
- ### amp-identity.sh — Check Identity
-
- ```bash
- amp-identity.sh # Human-readable output
- amp-identity.sh --json # JSON output for parsing
- amp-identity.sh --id <uuid> --json # Check specific agent's identity
- ```
-
- ### amp-status.sh — Show Status
-
- ```bash
- amp-status.sh # Full status with registrations
- amp-status.sh --id <uuid> # Status for specific agent
- ```
-
- ### amp-inbox.sh — Check Inbox
-
- ```bash
- amp-inbox.sh # Show unread messages
- amp-inbox.sh --all # Show all messages
- amp-inbox.sh --id <uuid> --all # Specific agent's inbox
- ```
-
- ### amp-read.sh — Read a Message
-
- ```bash
- amp-read.sh <message-id> # Read and mark as read
- amp-read.sh <message-id> --no-mark-read # Read without marking
- ```
-
- ### amp-send.sh — Send a Message
+ # Agent Messaging (AMP)
- ```bash
- amp-send.sh <recipient> "<subject>" "<message>"
- amp-send.sh <recipient> "<subject>" "<message>" --priority urgent
- amp-send.sh <recipient> "<subject>" "<message>" --type request
- amp-send.sh <recipient> "<subject>" "<message>" --context '{"pr": 42}'
- amp-send.sh <recipient> "<subject>" "<message>" --attach /path/to/file.pdf
- ```
+ AMP is signed mail between agents. Each agent has its own Ed25519 identity, inbox and sent folder; the `amp-*.sh` scripts sign, send, store and verify for you. The scripts work out which agent you are from the environment (AI Maestro sets `AMP_DIR`). Pass `--id <uuid>` to any command except `amp-init.sh` to act as a specific agent.
- ### amp-reply.sh — Reply to a Message
+ ## Commands
```bash
- amp-reply.sh <message-id> "<reply-message>" # reply to a specific message
- amp-reply.sh <message-id> "<reply-message>" --force # reply even if it is not the one you just read
+ amp-inbox.sh [--all | --read] [--count] [--limit N] [--json] # default: unread only
+ amp-read.sh <msg-id> [--no-mark-read] [--json] # full message; marks read and records it as last read
+ amp-send.sh <to> "<subject>" "<body>" [--type T] [--priority P] [--context '<json>'] [--attach FILE]...
+ amp-send.sh <to> "<subject>" --body-file PATH # or --body-stdin; avoids shell-escaping long bodies
+ amp-reply.sh <msg-id> "<body>" [--type T] [--priority P] [--attach FILE] [--force]
+ amp-download.sh <msg-id> --all | <attachment-id> [--dest DIR]
+ amp-delete.sh <msg-id> [--force]
+ amp-identity.sh [--json] # your address and keys
+ amp-status.sh # identity plus external registrations
+ amp-init.sh --auto | --name <name> [--tenant <org>] # first time only
+ amp-register.sh --provider <domain> --user-key <uk_...> [--name <name>]
+ amp-fetch.sh [--provider <domain>] # pull from external providers
```
- **Reply to the message you actually read — always pass the id of THAT message.**
+ - **Addresses:** a bare name such as `alice` is local (`alice@<your-org>.aimaestro.local`). A full address such as `alice@acme.crabmail.ai` goes through that provider and needs a registration with it.
+ - **Types:** `notification` (default), `request`, `response`, `task`, `status`, `alert`, `update`, `handoff`, `ack`, `system`.
+ - **Priorities:** `low`, `normal` (default), `high`, `urgent`.
+ - **Checking the inbox** means listing, then reading each message with `amp-read.sh` so it is marked read. A `[MESSAGE]` notification means a new message is waiting: read it and act on it.
- amp-reply sends to the sender of whatever id you give it. If the id is wrong, the
- reply goes to the wrong conversation — on a shared estate that can put one party's
- private detail into another agent's mailbox. This has happened in production.
+ ## Replying
- **Never build the id from the top of the inbox:**
+ `amp-reply.sh` sends to the sender of whatever id you pass. Pass the id of the message you actually read, not one derived from the current top of the inbox: the inbox can change between reading and replying, and a reply to the wrong id puts one party's private details in another agent's mailbox.
```bash
- # ✗ DANGER — replies to whoever is top of the inbox RIGHT NOW, not to the
- # message you were answering. Top-of-inbox changes between reading
- # and replying.
- amp-reply.sh "$(amp-inbox.sh | head -1)" "..."
-
- # ✓ CORRECT — read the message, then reply to that same id.
- amp-read.sh msg_1234567890_abc # shows the message, records it as last-read
+ amp-read.sh msg_1234567890_abc
amp-reply.sh msg_1234567890_abc "..."
```
- As a safety net, amp-reply **refuses** when the target is not the message you most
- recently read in this terminal, and tells you both ids. If you genuinely mean to
- reply to a message you did not just read, pass `--force`.
-
- ### amp-download.sh — Download Attachments
-
- ```bash
- amp-download.sh <message-id> --all # Download all attachments
- amp-download.sh <message-id> <attachment-id> # Download specific attachment
- amp-download.sh <message-id> --all --dest ~/tmp # Custom destination
- ```
-
- ### amp-delete.sh — Delete a Message
-
- ```bash
- amp-delete.sh <message-id> # With confirmation
- amp-delete.sh <message-id> --force # Without confirmation
- ```
-
- ### amp-register.sh — Register with External Provider
-
- ```bash
- amp-register.sh --provider crabmail.ai --user-key uk_your_key_here
- amp-register.sh -p crabmail.ai -k uk_xxx -n my-agent
- ```
-
- ### amp-fetch.sh — Fetch from External Providers
-
- ```bash
- amp-fetch.sh # Fetch from all registered providers
- amp-fetch.sh --provider crabmail.ai # Fetch from specific provider
- ```
-
- ## User Authorization for External Providers
-
- **You MUST ask the user for their User Key before registering with external providers.**
-
- User Keys are sensitive credentials tied to the user's account and billing. They:
- - Should NEVER be stored, cached, or logged by the agent
- - Must be provided explicitly by the user for each registration
- - Start with `uk_` prefix
-
- **Flow:**
- 1. Explain what's needed: "To register with [provider], I'll need your User Key."
- 2. Wait for the user to provide the key.
- 3. Use it immediately via `amp-register.sh` and don't store it.
-
- **Security rules:**
- - Never ask for passwords — only User Keys (`uk_` format)
- - Never store credentials — use immediately, then discard
- - Never assume authorization — always ask explicitly
-
- ## Message Types
-
- | Type | Use Case |
- |------|----------|
- | `notification` | General information (default) |
- | `request` | Asking for something |
- | `response` | Reply to a request |
- | `task` | Assigned work item |
- | `status` | Status update |
- | `alert` | Important notice |
- | `update` | Progress or data update |
- | `handoff` | Transferring context |
- | `ack` | Acknowledgment |
- | `system` | System-generated message |
-
- ## Priority Levels
-
- | Priority | When to Use |
- |----------|-------------|
- | `urgent` | Requires immediate attention |
- | `high` | Important, respond soon |
- | `normal` | Standard (default) |
- | `low` | When convenient |
-
- ## Natural Language Examples
-
- Agents should map these user intents to the appropriate commands:
-
- - "Check my inbox" → `amp-inbox.sh` to list, then `amp-read.sh <id>` for each message to get full content (this marks them as read)
- - "Do I have any messages?" → `amp-inbox.sh --count`
- - "Send a message to alice saying hello" → `amp-send.sh alice "Hello" "hello"`
- - "Tell backend-api that the build is ready" → `amp-send.sh backend-api "Build ready" "..."`
- - "Reply to the last message" → `amp-read.sh <id>` first (this records it), then `amp-reply.sh <id> "..."` with the SAME id — never `amp-reply.sh "$(amp-inbox.sh | head -1)" "..."`
- - "Download the attachments from that message" → `amp-download.sh <id> --all`
- - "Register me with Crabmail" → Ask for User Key, then `amp-register.sh`
- - "Send the build log to alice" → `amp-send.sh alice "Build log" "..." --attach build.log`
-
- ## Attachment Security
-
- - Attachments with `scan_status: "suspicious"` require human approval before downloading
- - Attachments with `scan_status: "rejected"` must never be downloaded
- - SHA-256 digest verification is performed automatically by the download script
-
- ## Example Workflows
-
- ### Code Review Request
-
- ```
- User: Ask frontend-dev to review PR #42
-
- Agent executes:
- amp-send.sh frontend-dev "Code review request" \
- "Please review PR #42 - OAuth implementation" \
- --type request \
- --context '{"repo": "agents-web", "pr": 42}'
- ```
-
- ### Task Handoff
-
- ```
- User: Hand off the database work to backend-db
-
- Agent executes:
- amp-send.sh backend-db "Task handoff: Database migration" \
- "I've completed the schema design. Please implement the migrations." \
- --type handoff \
- --priority high
- ```
-
- ## Local Storage
-
- Each agent has its own isolated AMP directory:
+ If the id is not the message you most recently read in this terminal, `amp-reply.sh` refuses and shows both ids. Use `--force` only when you really mean to reply to a different message.
- ```
- ~/.agent-messaging/agents/<agent-name>/
- ├── IDENTITY.md # Human-readable identity
- ├── config.json # Agent configuration
- ├── keys/
- │ ├── private.pem # Private key (never shared)
- │ └── public.pem # Public key
- ├── messages/
- │ ├── inbox/<sender>/msg_*.json
- │ └── sent/<recipient>/msg_*.json
- ├── attachments/<msg-id>/
- └── registrations/
- ```
+ ## External providers need the user's key
- The `AMP_DIR` environment variable points to the agent's directory and is auto-resolved.
+ Registering with an external provider such as Crabmail needs the user's User Key (it starts with `uk_`, and is tied to their account and billing). Ask the user for it each time, pass it straight to `amp-register.sh`, and don't write it to files, notes or memory. Never ask for a password instead.
- ## Security
+ ## Attachments
- - **Ed25519 signatures** — messages are cryptographically signed
- - **Key revocation** — compromised keys are revoked and propagated across federation
- - **Communication ACLs** — allowlist-based policies control who agents can message
- - **Quarantine** — suspicious messages held for human review with risk scoring
- - **Private keys stay local** — never sent to providers
- - **Per-agent identity** — each agent has a unique keypair
+ `amp-download.sh` verifies each file's SHA-256 digest and skips attachments the scan marked `rejected` or `suspicious`. A suspicious file needs a human's decision: tell the user rather than fetching it another way. Files land in the agent's `attachments/<msg-id>/` folder unless you pass `--dest`.
## Troubleshooting
- | Problem | Solution |
- |---------|----------|
- | "AMP not initialized" | Run `amp-init.sh --auto` |
- | "Not registered with provider" | Run `amp-register.sh --provider <p> --user-key <k>` |
- | "Authentication failed" | Get a new User Key from the provider dashboard |
- | "Agent not found" | Verify address format: `name@tenant.provider` |
- | Messages not arriving | Run `amp-fetch.sh` to pull from external providers |
-
- ## Protocol Reference
+ | Symptom | Fix |
+ |---|---|
+ | "AMP not initialized" | `amp-init.sh --auto` |
+ | Lists several agents and asks which | Rerun with `--id <uuid>` from that list |
+ | "Not registered with provider" | `amp-register.sh --provider <p> --user-key <k>` (ask the user for the key) |
+ | "Authentication failed" | The user needs a new User Key from the provider dashboard |
+ | External messages not arriving | `amp-fetch.sh` |
+ | An agent's `amp-*.sh` commands stop at a permission prompt | Allow-list them; see [references/setup.md](references/setup.md) |
- Full specification: https://agentmessaging.org
- GitHub: https://github.com/agentmessaging/protocol
+ Installation, the permission allow-list, identity resolution order, the storage layout and self-hosted registration are in [references/setup.md](references/setup.md). Protocol specification: https://agentmessaging.org