# Technical Documentation: Mesh-LLM/AGENTS

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/Mesh-LLM/AGENTS)

### Overview (`README.md`)

# Mesh Agents

Mesh Agents lets a [mesh-llm](https://github.com/Mesh-LLM/mesh-llm) node host
and advertise useful [A2A](https://a2a-protocol.org/latest/specification/)
agents. A mesh node is not itself an agent, and the whole mesh is not one giant
agent. Instead, any node can publish one or more Agent Cards for agents it is
willing to run.

That makes the mesh a shared agent cloud. Instead of every developer
hand-wiring the same local helpers, people can contribute agents to a private
team mesh, discover agents contributed by others, and run them with the
inference, tools, and runtime capacity available across the mesh.

Codex, OpenCode, Goose, Claude, and other MCP-capable clients get one local MCP
endpoint for finding agents, inspecting their native
[A2A Agent Cards](https://a2a-protocol.org/latest/specification/#8-agent-discovery-the-agent-card),
sending tasks, and reading artifacts. The agent might run on your node, another
node in a private team mesh, or eventually a public mesh. The client does not
need to know where the agent lives.

Agents are defined once on the node that owns them and surfaced through Mesh's
MCP endpoint. That makes them easy to share, easy to reuse, and independent of
any one coding client.

This README uses a pull request reviewer named `pr-review` as the running
example. It is a realistic coding agent: a developer asks for a GitHub PR
review, the coding client discovers `pr-review` through Mesh MCP, Mesh sends the
work to the A2A agent, and the agent uses an ACP harness to inspect code and
return findings.

## What It Is

Mesh Agents provides:

- a directory-backed A2A agent registry
- A2A Agent Card loading from native JSON
- MCP tools for listing agents, sending messages, reading tasks, and reading artifacts
- persistent A2A task state backed by SQLite
- an ACP bridge for local coding-agent harnesses such as OpenCode
- CLI tools for authoring and validating local agent definitions
- packaged Agent Skills for using and authoring Mesh agents from AI clients

The local foundation is implemented today. Mesh-wide discovery and remote
routing are the next layer.

## FAQ

### Is every mesh node an A2A agent?

No. A mesh node can host zero, one, or many A2A agents. The node runs the Mesh
Agents plugin, and the plugin advertises whichever local agent definitions are
enabled by policy.

### Is the whole mesh exposed as one A2A agent?

No. The mesh is the discovery and routing fabric. Individual agents are exposed
through their own A2A Agent Cards. Your client talks to the local Mesh MCP
endpoint, Mesh finds the right agent, and A2A carries the task to that agent.

### What does "defined once and surfaced through MCP" mean?

You define an agent once under `~/.mesh-llm/agents/<agent-id>/` on the node
that should run it. MCP-capable clients such as Codex, OpenCode, Goose, Claude,
and Pi connect to Mesh's local MCP endpoint instead of each maintaining their
own copy of the agent configuration.

### Can I keep an agent private?

Yes. Local agent definitions start private. `visibility = "private"` keeps the
agent off public surfaces, `policy.advertise_on_mesh = false` prevents gossip
to other nodes, and `policy.public_mesh = false` protects against accidental
publication on a public mesh. Publish agents only when you intentionally want
other mesh peers to discover and use them.

### What if the agent has secret MCP connections?

Keep that agent private unless you intentionally want other mesh peers to send
it work. Secrets and private tool credentials stay on the node that owns the
agent, but a published agent runs with that node's configured tools. Treat
publishing as permission for other allowed peers to ask that agent to perform
work.

### How do MCP, A2A, and ACP fit together?

- MCP is how the coding client talks to Mesh.
- A2A is how Mesh describes and sends tasks to agents.
- ACP is how a local A2A agent drives a coding harness such as OpenCode, Codex,
  Goose, or Pi.

## Architecture

```
/* Detailed source-code truncated for AI context efficiency. */
```

The coding agent only needs one integration point: Mesh's MCP endpoint. Through
that endpoint it can discover available agents, inspect their A2A Agent Cards,
send work, and read the resulting task state or artifacts. This keeps Codex,
OpenCode, Goose, Claude, and similar clients out of the business of knowing how
agents are hosted or routed.

Mesh Agents runs inside the mesh node as the plugin that owns the agent control
plane. It loads local Agent Cards from `~/.mesh-llm/agents/`, advertises
available agents into the mesh, tracks which node owns each agent, and persists
A2A task state. If an agent is local, the task can run on the current node. If
the best agent is remote, Mesh routes the request to the owning node and returns
the same task/artifact shape to the caller.

A2A is the contract between Mesh and the agent. The Agent Card describes what
the agent can do, and A2A tasks carry the work, status updates, and artifacts.
For agents that need an interactive coding runtime, Mesh Agents bridges from
A2A into ACP. ACP is the harness-facing protocol: it starts a session, streams
work into OpenCode, Codex, or another compatible harness, and sends events back
to the A2A task. The result flows back to the coding agent as normal MCP tool
output.

## What It Is Used For

Use Mesh Agents when you want a mesh node to expose useful task-oriented agents
to AI clients.

Examples:

- a `pr-review` agent that reviews a GitHub pull request and returns prioritized findings
- a `docs-maintainer` agent that updates docs from a change summary
- a `release-notes` agent that turns merged PRs into release notes
- a `test-runner` agent that runs project-specific checks and summarizes failures

The caller talks to a local MCP tool. Mesh Agents owns the agent registry, task
state, and runtime bridge.

The rest of this README walks through `pr-review` as the example agent.

## Installation

Install the agents plugin through
[mesh-llm](https://github.com/Mesh-LLM/mesh-llm):

```bash
mesh-llm plugins install Mesh-LLM/agents
```

After installation, run the plugin's user-facing CLI through `mesh-llm`.

Released plugin archives include Agent Skills under `skills/`. Install the
plugin skills into detected AI clients:

```bash
mesh-llm skills install
```

Agent launch commands such as `mesh-llm goose`, `mesh-llm pi`,
`mesh-llm opencode`, and `mesh-llm claude` also install available plugin skills
for that agent before starting the session.

The normal MCP endpoint is hosted by the running mesh node. Launch a supported
client through mesh-llm and the client is wired to the mesh MCP endpoint,
including the Mesh Agents tools:

```bash
mesh-llm opencode
mesh-llm goose
mesh-llm pi
mesh-llm claude
```

Or register Mesh's MCP endpoint in any AI tool that can speak MCP over HTTP:

```bash
http://127.0.0.1:3131/mcp
```

## Defining Agents

Local agent definitions live under `~/.mesh-llm/agents/`. Each directory
describes one agent that Mesh can advertise, route to, and execute.

If you have not used A2A before, the key idea is that an agent has a public
contract and a private runtime. The public contract is the A2A Agent Card: it
answers "what is this agent, what can it do, and how do A2A clients talk to
it?" The private runtime config answers "how does this machine actually run
that agent?"

Create the `pr-review` local agent definition:

```bash
mesh-llm agents init pr-review --runtime opencode
```

That creates the files for the example pull request reviewer:

```text
~/.mesh-llm/
  agents/
    pr-review/
      agent-card.json
      runtime.toml
      instructions.md
```

This repository also includes a ready-to-use demo definition under
`examples/pr-review/`. During plugin development, copy that directory into your
local agent registry and validate it:

```bash
mkdir -p ~/.mesh-llm/agents
cp -R examples/pr-review ~/.mesh-llm/agents/pr-review
mesh-llm agents validate pr-review
```

The generated files and the example files use the same shape. `agents init` is
the quickest way to start a new local agent; `examples/pr-review` is the richer
demo version used throughout this README.

### Agent Card

`agent-card.json` is the native
[A2A Agent Card](https://a2a-protocol.org/latest/specification/#8-agent-discovery-the-agent-card).
Think of it as the agent's business card. Mesh and MCP clients use it to decide
whether an agent is appropriate for a task before sending work.

A card describes:

- the agent name, description, and version
- the A2A interface Mesh exposes for that agent
- supported input and output modes
- whether streaming is supported
- the agent's skills, such as `pr-review` or `release-notes`

For the `pr-review` example, the starter card created by
`mesh-llm agents init` is valid JSON and can be edited directly:

```json
{
  "name": "Pr Review",
  "description": "Reviews pull requests and returns prioritized findings with file/line references.",
  "version": "0.1.0",
  "supportedInterfaces": [
    {
      "url": "http://127.0.0.1:3131/a2a/agents/pr-review",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    }
  ],
  "capabilities": {
    "streaming": true
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/markdown"],
  "skills": [
    {
      "id": "pr-review",
      "name": "Pull request review",
      "description": "Inspect a GitHub pull request and report correctness, regression, and test risks.",
      "tags": ["github", "code-review", "pull-request"]
    }
  ]
}
```

For mesh-local agents like `pr-review`, Mesh owns the served A2A URL. You
normally edit the name, description, modes, capabilities, and skills; Mesh
handles where the agent is actually reachable.

### Runtime Policy

`runtime.toml` is Mesh Agents' private execution policy. It is not part of A2A
and is not advertised as the agent's public contract. It tells the local mesh
node whether to expose the agent, which harness to use, how much concurrency is
allowed, and what workspace policy to apply when tasks run.

Example `runtime.toml` for `pr-review`:

```toml
enabled = true
visibility = "private"

[runtime]
type = "opencode"
max_concurrent_tasks = 1

[runtime.workspace]
mode = "temp_per_task"
keep = "on_failure"

[instructions]
file = "instructions.md"
delivery = "first_prompt"

[tools.mesh]
enabled = true

[policy]
advertise_on_mesh = false
public_mesh = false
```

Important fields:

- `enabled`: controls whether Mesh loads the agent.
- `visibility`: starts as `private`; use this to keep local agents off public surfaces.
- `runtime.type`: selects how the agent runs. `opencode`, `goose`, and `pi`
  are named ACP presets. `acp` lets you provide an explicit ACP command.
  `remote` describes an externally hosted A2A agent.
- `runtime.max_concurrent_tasks`: caps simultaneous work for this agent. The
  default is `1`, which is safest for coding agents that mutate workspaces.
- `runtime.workspace.mode`: controls where work runs. `temp_per_task` creates a
  fresh temporary workspace per task; path-based workspace modes can pin an
  agent to a specific checkout.
- `runtime.workspace.keep`: controls cleanup. `on_failure` keeps failed task
  workspaces for debugging.
- `instructions.file`: points at the local instruction file delivered to the
  harness.
- `instructions.delivery`: `first_prompt` prepends the instructions to the
  first task prompt sent into the harness.
- `tools.mesh.enabled`: allows the harnessed agent to receive Mesh's own MCP
  tools.
- `policy.advertise_on_mesh`: controls whether this node gossips the agent to
  other mesh nodes.
- `policy.public_mesh`: protects against accidentally advertising private local
  agents on a public mesh.

Named runtimes are just convenience presets over ACP. Use `type = "acp"` when
you want full control over the command line:

```toml
[runtime]
type = "acp"
command = "$HOME/bin/my-agent-harness"
args = [
  "acp",
  "--cwd", "{{ task.workspace }}",
  "--mcp", "{{ mesh.mcp_url }}",
  "--agent", "{{ agent.id }}",
  "--instructions", "{{ instructions.file }}"
]
max_concurrent_tasks = 1

[runtime.env]
MESH_LLM_MCP_URL = "{{ mesh.mcp_url }}"
MESH_AGENT_ID = "{{ agent.id }}"
TASK_ARTIFACTS_DIR = "{{ task.artifacts_dir }}"
```

Substitutions are expanded when a task starts, because task-specific values do
not exist until then. Expansion applies to `runtime.command`, every
`runtime.args` item, and `runtime.env` values.

Mesh template variables use `{{ ... }}`. Environment variables use `$HOME`,
`${HOME}`, or `{{ env.HOME }}`. Missing variables are configuration errors.

Useful substitutions:

| Variable | Example value | Meaning |
|---|---|---|
| `{{ agent.id }}` | `pr-review` | Agent directory id. |
| `{{ agent.name }}` | `Pr Review` | Human-readable Agent Card name. |
| `{{ agent.dir }}` | `/Users/alice/.mesh-llm/agents/pr-review` | Agent definition directory. |
| `{{ agent.card_path }}` | `/Users/alice/.mesh-llm/agents/pr-review/agent-card.json` | Native A2A Agent Card path. |
| `{{ agent.runtime_path }}` | `/Users/alice/.mesh-llm/agents/pr-review/runtime.toml` | Local runtime policy path. |
| `{{ task.id }}` | `task-01J8R2` | A2A task id. |
| `{{ task.workspace }}` | `/var/folders/.../mesh-a2a-pr-review-task-01J8R2` | Workspace assigned to this task. |
| `{{ task.prompt_path }}` | `/Users/alice/.mesh-llm/a2a/agents/pr-review/runtime/task-01J8R2/prompt.txt` | File containing the task prompt. |
| `{{ task.artifacts_dir }}` | `/Users/alice/.mesh-llm/a2a/agents/pr-review/runtime/task-01J8R2/artifacts` | Directory for harness-written outputs. |
| `{{ task.logs_dir }}` | `/Users/alice/.mesh-llm/a2a/agents/pr-review/runtime/task-01J8R2/logs` | Directory for harness logs. |
| `{{ instructions.file }}` | `/Users/alice/.mesh-llm/agents/pr-review/instructions.md` | Resolved instruction file path. |
| `{{ instructions.dir }}` | `/Users/alice/.mesh-llm/agents/pr-review` | Directory containing the instruction file. |
| `{{ mesh.mcp_url }}` | `http://127.0.0.1:3131/mcp` | Mesh-hosted MCP endpoint. |
| `{{ mesh.api_url }}` | `http://127.0.0.1:3131` | Mesh node API and console base URL. |
| `{{ mesh.openai_url }}` | `http://127.0.0.1:9337/v1` | Mesh OpenAI-compatible inference endpoint. |
| `{{ mesh.model }}` | `auto` | Runtime model value, or `auto` if unset. |
| `{{ mesh.data_dir }}` | `/Users/alice/.mesh-llm` | Mesh data directory. |
| `{{ env.HOME }}` | `/Users/alice` | Explicit environment lookup. |
| `$HOME`, `${HOME}` | `/Users/alice` | Shell-style environment expansion. |

For example, this config:

```toml
[runtime]
type = "acp"
command = "opencode"
args = [
  "acp",
  "--cwd", "{{ task.workspace }}",
  "--mcp", "{{ mesh.mcp_url }}",
  "--instructions", "{{ instructions.file }}"
]
```

might start the harness like this for a `pr-review` task:

```bash
opencode acp \
  --cwd /var/folders/.../mesh-a2a-pr-review-task-01J8R2 \
  --mcp http://127.0.0.1:3131/mcp \
  --instructions /Users/alice/.mesh-llm/agents/pr-review/instructions.md
```

### Instructions

`instructions.md` is the agent's operating brief. For `pr-review`, this is
where you say what to prioritize, how to format findings, which checks to run,
and what not to do. Mesh Agents sends those instructions into the ACP harness
according to `runtime.toml`.

Useful authoring commands:

```bash
mesh-llm agents list
mesh-llm agents init <agent-id> --runtime opencode
mesh-llm agents validate [agent-id]
mesh-llm agents show <agent-id>
mesh-llm agents enable <agent-id>
mesh-llm agents disable <agent-id>
```

`mesh-llm agents init` is the starter authoring tool for local Agent Cards. For
`pr-review`, it creates a valid card skeleton, runtime policy, and instructions
file. Edit `agent-card.json` against the official A2A Agent Card docs, then run
`mesh-llm agents validate pr-review`.

## Discovering Agents

Clients discover agents through MCP. In normal use, the MCP endpoint is
`http://127.0.0.1:3131/mcp`. Register that URL in any AI tool that can speak
MCP over HTTP, or use client launchers such as `mesh-llm opencode`,
`mesh-llm goose`, `mesh-llm pi`, and `mesh-llm claude` to configure it for you.

Mesh's hosted MCP endpoint is an aggregate endpoint, so tool names are prefixed
by plugin name to avoid collisions with other plugins. The agents plugin exposes
these tools through that endpoint:

| Tool | Purpose | Example |
|---|---|---|
| `agents.get_agents` | List available agents. | "What mesh agents are available?" |
| `agents.get_agent` | Read one agent's native Agent Card and runtime summary. | "Show me what the `pr-review` agent can do." |
| `agents.send_message` | Send a message to an agent through A2A. | "Ask `pr-review` to review Mesh-LLM/mesh-llm#708." |
| `agents.get_task` | Fetch persisted task state. | "Check whether the PR review task has finished." |
| `agents.view_text_artifact` | Read text parts from a task artifact. | "Open the review findings artifact." |
| `agents.view_data_artifact` | Read a structured task artifact. | "Show the structured findings returned by the agent." |

When running as a mesh-llm plugin, these tools are surfaced through mesh-llm's
hosted MCP endpoint alongside the other mesh-provided tools. The plugin's
internal A2A bridge still owns the official tool semantics; mesh prefixes the
visible names because it is aggregating multiple plugins into one MCP namespace.

## Using Agents

Use agents by asking for the work you want done. You should not have to know
that agents exist, name an agent, or ask for discovery first. The client uses
Mesh's MCP tools behind the scenes to find the right A2A Agent Card, delegate
the task, poll task state, and read artifacts.

Example prompts using the `pr-review` agent:

```text
Code review Mesh-LLM/mesh-llm#708.
```

```text
Review the current branch for correctness regressions and missing tests.
```

```text
Review this PR and return only actionable findings with file and line
references: https://github.com/Mesh-LLM/mesh-llm/pull/708
```

```text
Show me the findings artifact from that review.
```

```text
Check whether the previous pull request review task has completed.
```

The same pattern works for other agents such as `docs-maintainer`,
`release-notes`, or `test-runner`. The client sees a normal local MCP tool
flow. Mesh Agents handles A2A task state, runtime execution, and artifact
persistence.

## Autonomous Agents

Autonomous agents should still use the same Mesh MCP and A2A surfaces as
user-invoked agents. The difference is the trigger: instead of a developer
typing "Code review this PR", a local loop notices work, prompts a coding
harness, and lets that harness discover and call Mesh agents.

A practical starting point is `opencode-loopd`. Run it from the project that
should be monitored:

```bash
opencode-loopd --project . --every 5m --prompt-file loop-prompt.md
```

`--project .` scopes the loop to the current checkout, `--every 5m` controls
the polling interval, and `--prompt-file loop-prompt.md` gives the loop its
standing instructions. The OpenCode environment should already have Mesh MCP
configured, either by launching through `mesh-llm opencode` or by registering
Mesh's MCP endpoint directly:

```text
http://127.0.0.1:3131/mcp
```

For example, `loop-prompt.md` for the `pr-review` demo might say:

```markdown
Check this repository for pull requests that are ready for review. When a PR
needs review, use Mesh MCP to find a suitable pull request review agent, send
the review task, wait for completion, and summarize the findings artifact.
Do not create duplicate reviews for the same PR.
```

This keeps autonomy out of the Mesh Agents admin surface. Mesh does not need a
separate scheduler to make the first demo useful: the loop is just another MCP
client. It discovers agents, sends A2A tasks, polls task state, and reads
artifacts using the same tools a human-driven coding client would use.

## Developing

Build the CLI:

```bash
cargo build -p mesh-agents
```

Run checks:

```bash
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
cargo build --workspace --locked
```

The live OpenCode ACP tests are ignored by default because they require an
installed and configured OpenCode ACP agent.

Run the private two-node PR review smoke before a demo:

```bash
MESH_LLM_BIN=/path/to/mesh-llm ./scripts/e2e-private-mesh-pr-review.sh
```

The script starts two isolated private mesh nodes, advertises
`examples/pr-review` from node A, discovers it from node B through
`http://127.0.0.1:<console>/mcp`, sends a remote A2A task, and verifies
`summary.md` plus `findings.json` artifacts.

### Adding Runtime Support

Runtime support is deliberately split between the public Agent Card and the
private harness bridge. A2A remains the public contract. ACP is how Mesh starts
local coding harnesses.

Most new coding runtimes should start with the generic ACP runtime. If the
runtime can serve an ACP-compatible stdio process, users can configure it
without a Mesh code change:

```toml
[runtime]
type = "acp"
command = "my-agent-harness"
args = [
  "acp",
  "--cwd", "{{ task.workspace }}",
  "--mcp", "{{ mesh.mcp_url }}"
]
max_concurrent_tasks = 1
```

Add a named runtime only when Mesh should provide a first-class preset, for
example `runtime.type = "my_harness"` instead of asking every user to remember
the command and ACP arguments. Named runtimes such as `opencode`, `goose`, and
`pi` should still resolve to ACP command templates. The usual code path is:

1. Add a `RuntimeKind` variant in `crates/mesh-agents-a2a/src/registry.rs`.
2. Add the matching `AgentRuntimeArg` value in `crates/mesh-agents-cli/src/main.rs`.
3. Teach `crates/mesh-agents-cli/src/agents.rs` how `mesh-llm agents init --runtime <name>` writes the starter `runtime.toml`.
4. Add command resolution in `crates/mesh-agents-acp-bridge/src/lib.rs`, mapping the new runtime to an ACP stdio command and default args.
5. Make sure the preset still runs through the same substitution path as `type = "acp"`.
6. Add tests for default command selection, explicit `runtime.command` override behavior, substitutions, and generated agent config.

Runtimes that are already full remote A2A services should not go through ACP.
Use `runtime.type = "remote"` and let Mesh route to the external A2A endpoint
described by the Agent Card.

Workspace layout:

```text
crates/mesh-agents-a2a/
  A2A Agent Card loading, local registry, local service, and SQLite task store.

crates/mesh-agents-acp-bridge/
  ACP harness bridge, OpenCode command expansion, workspace setup, and task execution.

crates/mesh-agents-cli/
  User-facing CLI and MCP stdio server.

skills/
  Agent Skills installed by mesh-llm for clients such as Goose, Pi, OpenCode,
  Claude, and Codex.
```

## Releasing

Releases are built by GitHub Actions. Push a version tag:

```bash
git tag v0.1.0
git push origin v0.1.0
```

Or run the `Release` workflow manually with a `v*` version. The workflow builds
and uploads:

- `agents-x86_64-unknown-linux-gnu.tar.gz`
- `agents-aarch64-apple-darwin.tar.gz`
- `agents-x86_64-pc-windows-msvc.zip`

Each archive is rooted under `agents/` and includes `plugin.toml`, the native
`agents` executable, packaged `skills/`, `README.md`, and `LICENSE`.

---

### Overview (`crates/mesh-agents-a2a/README.md`)

# mesh-agents-a2a

Shared A2A agent model code for mesh-llm.

This crate owns directory-only agent discovery, runtime configuration parsing,
and public A2A type boundaries. It depends on the official `a2a-lf`,
`a2a-client-lf`, and `a2a-server-lf` crates rather than defining local protocol
types.

It should not own CLI parsing, harness-specific ACP behavior, or mesh routing.

---

### Overview (`crates/mesh-agents-acp-bridge/README.md`)

# mesh-agents-acp-bridge

ACP harness bridge primitives for mesh-llm A2A agents.

This crate owns ACP command planning and, as implementation continues, ACP event
translation and harness session behavior. It depends on the official
`agent-client-protocol` crate for protocol boundaries.

It should not own A2A HTTP routing, mesh discovery, or CLI parsing.

---

### Plan (`docs/plan.md`)

# A2A End-To-End Demo Plan

This plan tracks the work needed to make Mesh Agents work end to end and be
excellent to demo without relying on console visibility.

The demo prompt should be natural:

```text
Code review Mesh-LLM/mesh-llm#708.
```

The demo must not depend on the user knowing that agents exist, naming an
agent, or asking to discover agents. The AI client should infer that the task
is delegatable, use Mesh MCP to find the right agent, and return the result as
part of the normal answer.

The target flow is:

```text
AI client -> Mesh MCP -> agent discovery -> A2A task -> ACP harness -> artifacts -> AI client
```

## 1. Stack Prerequisites

Mesh-LLM-side work should use the `plugin-agents` stack:

```text
main
  -> Mesh-LLM/mesh-llm#725  plugin-provided skills
    -> Mesh-LLM/mesh-llm#702  plugin mesh streams
      -> future plugin-agents work
```

- Keep `#725` based on `main`.
- Keep `#702` stacked on `#725`.
- Stack future mesh-llm work on `#702`.
- Label all related mesh-llm PRs `plugin-agents`.
- Use GitHub merge queue for landing ready PRs in order.

## 2. Finish Agents Plugin Packaging

The agents plugin release archive should include:

- `agents` executable
- `plugin.toml`
- `README.md`
- `LICENSE`
- `skills/`

The skills packaging should follow the same pattern as the Blackboard plugin:
top-level `skills/<skill-name>/SKILL.md` files copied into release archives.

## 3. Add A Real `pr-review` Example

Add a realistic example agent:

```text
examples/pr-review/
  agent-card.json
  runtime.toml
  instructions.md
```

Requirements:

- The A2A Agent Card clearly describes pull request review.
- The Agent Card includes skills/tags such as `github`, `code-review`, and
  `pull-request` so the client skill can match ordinary review prompts.
- `runtime.toml` uses ACP with substitutions.
- `max_concurrent_tasks = 1`.
- `instructions.md` tells the harness to return actionable findings with file
  and line references.
- The example should be directly usable as the main demo agent.

Status: implemented in `examples/pr-review/`.

## 4. Make Setup Simple

The happy path should be:

```bash
mesh-llm plugins install Mesh-LLM/agents
mesh-llm skills install
cp -R examples/pr-review ~/.mesh-llm/agents/pr-review
mesh-llm agents validate pr-review
mesh-llm opencode
```

Constraints:

- No direct `agents mcp`.
- No manual MCP config.
- No console dependency.
- `mesh-llm agents init pr-review --runtime opencode` remains the quick
  authoring path for creating a starter local agent, but the demo should use
  the richer checked-in `examples/pr-review` definition.

## 5. Make MCP Tools Reliable

The hosted Mesh MCP endpoint must support the full user flow:

- `agents.get_agents`
- `agents.get_agent`
- `agents.send_message`
- `agents.get_task`
- `agents.view_text_artifact`
- `agents.view_data_artifact`

Mesh's hosted MCP endpoint aggregates all plugin tools into one namespace, so
visible tool names should stay plugin-prefixed. The agents plugin can keep
official A2A tool semantics internally; the aggregate endpoint uses the
`agents.*` prefix to prevent collisions with other plugins.

The user should not need to know these tool names, name an agent, or ask to
find an agent. The packaged skills should guide the AI client to recognize
delegatable tasks, discover matching agents, inspect, delegate, poll, and read
artifacts.

For the demo, a prompt like `Code review Mesh-LLM/mesh-llm#708.` should be
enough for the client to choose `pr-review` through discovery.

## 6. Make Task Output Impressive

A completed `pr-review` task should return artifacts:

```text
summary.md
findings.json
```

Findings should include:

- severity
- file
- line
- issue
- recommendation

Task state should persist across mesh-llm restarts.

## 7. Select Mesh Models By Capability

Agents should not have to hard-code a specific mesh model when they really need
a capability. A `pr-review` agent usually wants a coding-capable text model
with tool calling. Other agents might need image, video, audio, multimodal,
reasoning, or long-context capability.

Plan:

- Let agent runtime policy express model intent by capability, not only by
  model name.
- Example capabilities: `text`, `coding`, `tool_calling`, `image`, `video`,
  `audio`, `multimodal`, `reasoning`, and `long_context`.
- Resolve capability requests to an available mesh model at task start.
- Expose the resolved model through `{{ mesh.model }}` for ACP command
  substitution.
- Keep explicit model selection available for agents that need a specific
  model.

Example direction:

```toml
[runtime.model]
capabilities = ["text", "coding", "tool_calling"]
fallback = "auto"
```

Open question:

- Verify whether Mesh's OpenAI-compatible `/v1/models` surface currently
  exposes model capabilities. If it does not, add a `plugin-agents` mesh-llm
  task to expose enough capability metadata for agents and client skills to
  choose models reliably.

## 8. Prove ACP Runtime Substitution

The demo agent should use the explicit ACP runtime path:

```toml
[runtime]
type = "acp"
command = "opencode"
args = [
  "acp",
  "--cwd", "{{ task.workspace }}",
  "--mcp", "{{ mesh.mcp_url }}",
  "--instructions", "{{ instructions.file }}"
]
max_concurrent_tasks = 1
```

Verify substitutions for:

- `{{ task.workspace }}`
- `{{ mesh.mcp_url }}`
- `{{ instructions.file }}`
- `{{ task.prompt_path }}`
- `{{ task.artifacts_dir }}`
- `{{ task.logs_dir }}`

## 9. Prove Mesh-Wide Discovery

After single-node success, run a two-node private mesh:

```text
Node A: user + AI client
Node B: owns pr-review
```

Show through MCP results:

- Node A discovers `pr-review`.
- Node A sends the A2A task.
- Node B runs the ACP harness.
- Node A receives final task state and artifacts.

No console visibility is required for the demo.

## 10. Harden Important Failures

Keep failure hardening scoped to task/debug quality:

- Invalid Agent Card points to file and field.
- Missing Mesh MCP endpoint names the URL.
- ACP process failure stores logs under `{{ task.logs_dir }}`.
- Failed task is persisted and readable through `agents.get_task`.

Do not spend time on harness install guidance.

## 11. Support Autonomous Agents

Autonomous agents should use the same A2A and MCP surfaces as user-invoked
agents. They are not a separate admin system. The difference is that a trigger
starts the task instead of a user prompt.

Example:

```text
github-pr-monitor -> Mesh MCP discovery -> pr-review -> test-runner -> summary artifact
```

A `github-pr-monitor` agent could watch a repository, notice that a new pull
request is ready for review, discover a suitable `pr-review` agent through Mesh
MCP, call it through A2A, then optionally call a `test-runner` agent if the
review finds risky changes. The final result is still persisted as A2A task
state and artifacts.

Planned trigger model:

- `manual`: normal user-initiated A2A task.
- `schedule`: run on an interval or wall-clock schedule.
- `webhook`: accept an external event and convert it into an A2A task.
- `mesh_event`: react to mesh-visible events, such as an agent advertisement,
  model capability change, or completed task.
- `watch`: poll an external system through an MCP tool or harness capability.

Example direction:

```toml
[triggers.pr_watch]
type = "schedule"
interval = "10m"
prompt = "Check Mesh-LLM/mesh-llm for pull requests that need review."

[autonomy]
enabled = true
max_actions_per_run = 4
max_delegate_depth = 2
dedupe_key = "github-pr-url"
```

Requirements:

- Trigger state must be persisted in SQLite so restarts do not duplicate work.
- Triggered tasks must look like normal A2A tasks with a clear initiator,
  parent task id, and trigger metadata.
- Autonomous agents use the same `max_concurrent_tasks` and queue policy as
  manually invoked agents.
- Failures are readable through `agents.get_task` and should include trigger context.
- The first demo should use a local scheduled trigger, not external webhooks.

Concrete demo path:

Use `opencode-loopd` as the first autonomous trigger. It runs as a normal
client-side harness loop, so it does not require a new Mesh admin surface or a
plugin-owned scheduler before the demo is useful.

```bash
opencode-loopd --project . --every 5m --prompt-file loop-prompt.md
```

- `--project .` points the loop at the repository or workspace to monitor.
- `--every 5m` gives a simple polling cadence for the demo.
- `--prompt-file loop-prompt.md` contains the standing autonomous instruction.
- OpenCode should have Mesh MCP configured through `mesh-llm opencode` or by
  registering `http://127.0.0.1:3131/mcp`.
- The loop prompt should ask for the outcome, not raw tool calls. For example:
  "Check this repository for PRs ready for review. When one exists, use Mesh
  MCP to find a pull request review agent, send the review task, and summarize
  the findings artifact."

This means the first autonomous demo is:

```text
opencode-loopd -> Mesh MCP discovery -> pr-review A2A task -> artifacts
```

Later Mesh-owned trigger support can adopt the same behavior internally:
persist dedupe state, create normal A2A tasks, and use Mesh MCP for delegation.

## 12. Support Agents Calling Agents

Agents should be able to call other agents through the same Mesh MCP tools that
clients use. This keeps composition official-looking and avoids inventing a
private plugin-only delegation API.

Requirements:

- Harnessed agents automatically receive Mesh's hosted MCP endpoint when
  `[tools.mesh] enabled = true`.
- The packaged `mesh-agents` skill should teach clients and harnessed agents
  to discover before delegating, inspect the Agent Card, send the A2A task,
  poll task state, and read artifacts.
- Child tasks should record `parent_task_id`, `root_task_id`, and caller agent
  id so task trees can be inspected later.
- Delegation needs guardrails:
  - maximum delegate depth
  - maximum child tasks per parent
  - optional allowed agent id or skill tags
  - cycle detection for repeated agent/task chains
  - clear failure when policy denies delegation
- Child task artifacts should be referenceable from the parent task result.

Good demo shape:

```text
User: Code review Mesh-LLM/mesh-llm#708.
Codex/OpenCode -> Mesh MCP -> pr-review
pr-review -> Mesh MCP -> test-runner
pr-review returns findings plus a linked test artifact
```

This is more compelling than asking the user to manually find and chain agents:
the user asks for the outcome, the selected agent decides which specialized
agents can help, and Mesh records the task tree.

## 13. Demo Script

1. Start a private mesh node.
2. Install the agents plugin.
3. Install skills.
4. Create or load `pr-review`.
5. Launch `mesh-llm opencode`.
6. Prompt naturally:

   ```text
   Code review Mesh-LLM/mesh-llm#708.
   ```

   Do not mention agents, Mesh, MCP, A2A, or tool names in the prompt.

7. Ask a follow-up:

   ```text
   Show me the findings artifact.
   ```

8. Restart mesh-llm and ask for the prior task state.
9. Optional: repeat with `pr-review` hosted on Node B.
10. Optional autonomy demo: enable a local scheduled monitor that discovers a
    PR needing review, delegates to `pr-review`, and stores the review artifact.
11. Optional composition demo: let `pr-review` call `test-runner` and link the
    child task artifact from the parent review.

## Execution Order

1. Commit and push skills packaging in `agents`.
2. Add `examples/pr-review`.
3. Verify single-node hosted MCP flow.
4. Improve task artifacts.
5. Add model capability selection for mesh inference.
6. Add ACP logs and failure behavior.
7. Land `Mesh-LLM/mesh-llm#725`.
8. Rebase and land `Mesh-LLM/mesh-llm#702`.
9. Build and validate two-node remote discovery/routing.
10. Add parent/child task metadata for agent-to-agent delegation.
11. Add local scheduled autonomous trigger support.
12. Run the final no-console demo end to end.

---

--- METRICS ---
- Files Extracted: 4
- Estimated Token Budget: ~9019 tokens
- Canonical Reference: https://codewiki.google/github.com/Mesh-LLM/AGENTS
