Skip to content
Open
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,80 @@ Worker modules for the [III engine](https://github.com/iii-hq/iii).

## Modules

### mcp

MCP protocol worker — exposes iii-engine functions as MCP tools via stdio and Streamable HTTP.

**Protocol version:** `2025-11-25`

**Features:**
- Dual transport: stdio (Claude Desktop, Cursor) + HTTP (`POST /mcp`)
- 6 built-in tools: worker register/stop, trigger register/unregister/void/enqueue
- 4 MCP resources: `iii://functions`, `iii://workers`, `iii://triggers`, `iii://context`
- 4 MCP prompts: register-function, build-api, setup-cron, event-pipeline
- Metadata filtering: only functions with `mcp.expose: true` are exposed (unless `--expose-all`)
- Spawn Node.js/Python workers on the fly via `iii_worker_register` tool

#### Build

```bash
cd mcp
cargo build --release
```

#### Usage

```bash
iii-mcp # MCP stdio (Claude Desktop, Cursor)
iii-mcp --no-stdio # MCP HTTP only (POST /mcp)
iii-mcp --expose-all # show all functions, ignore metadata filter
```

Tag functions for MCP exposure:
```js
iii.registerFunction({
id: 'orders::process',
metadata: { "mcp.expose": true }
}, handler)
```

---

### a2a

A2A protocol worker — exposes iii-engine functions as A2A agent skills via HTTP.

**Features:**
- Full A2A type system: AgentCard, Task (8 states), Message, Part, Artifact
- Methods: `message/send`, `tasks/get`, `tasks/cancel`, `tasks/list`
- Agent card at `GET /.well-known/agent-card.json`
- Task state stored via engine KV (`a2a:tasks` scope)
- Metadata filtering: only functions with `a2a.expose: true` are exposed (unless `--expose-all`)

#### Build

```bash
cd a2a
cargo build --release
```

#### Usage

```bash
iii-a2a # A2A HTTP (POST /a2a + GET /.well-known/agent-card.json)
iii-a2a --expose-all # show all functions as skills
```
Comment on lines +145 to +150
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Document the public URL flag in the A2A usage section.

The PR adds a configurable agent-card URL, but this block only shows local/default invocations. Please document --base-url here and clarify whether it expects the public origin or the full /a2a endpoint; otherwise non-local deployments have no guidance for advertising a reachable interface.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 64 - 69, Update the Usage section to document the new
--base-url flag: explain that the flag configures the public origin used to
build the agent-card URL (not the full /a2a path), give a concrete example
invocation like "iii-a2a --base-url https://example.com" and note that the
agent-card will be served at <base-url>/a2a and the /.well-known/agent-card.json
will reference that origin so non-local deployments can advertise a reachable
interface; reference the CLI invocation shown (iii-a2a) and the --base-url flag
so readers can find the relevant behavior.


Tag functions for A2A exposure:
```js
iii.registerFunction({
id: 'orders::process',
metadata: { "a2a.expose": true }
}, handler)
```

---

### image-resize

A Rust-based image resize worker that connects to the III engine via WebSocket and processes images through stream channels.
Expand Down
27 changes: 27 additions & 0 deletions a2a/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "iii-a2a"
version = "0.3.0"
edition = "2024"
description = "A2A protocol worker for iii-engine"
license = "Apache-2.0"
authors = ["Rohit Ghumare <ghumare64@gmail.com>"]
repository = "https://github.com/iii-hq/workers"
homepage = "https://github.com/iii-hq/workers"
rust-version = "1.85"
keywords = ["a2a", "agent-to-agent", "ai", "iii-engine"]
categories = ["command-line-utilities"]

[[bin]]
name = "iii-a2a"
path = "src/main.rs"

[dependencies]
iii-sdk = "0.10.0"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time", "signal"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
clap = { version = "4", features = ["derive"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
anyhow = "1"
uuid = { version = "1", features = ["v4"] }
Loading
Loading