iicp-client · Rust SDK
Official Rust client library for the IICP protocol — route AI agent tasks by intent across a self-organising mesh of provider nodes. No central broker. No hardcoded endpoints.
urn:iicp:intent:llm:chat:v1 → discover → select → submit
Add to Cargo.toml
[]
= "0.2"
Or for the latest unreleased code:
[]
= { = "https://github.com/RobLe3/iicp-client-rust" }
Architecture — consumer or provider?
This SDK covers both sides of the IICP protocol:
| Role | What you do | Type |
|---|---|---|
| Consumer | Send AI tasks to the mesh; discover and submit | IicpClient |
| Provider | Run a node, register with the directory, serve tasks | IicpNode |
Consumer and provider can run in the same process. For production provider nodes backed by Ollama/vLLM, see iicp.network/docs/node-setup.
Quickstart
use ;
async
Configuration
use ClientConfig;
let config = ClientConfig ;
| Field | Default | Description |
|---|---|---|
directory_url |
"https://iicp.network/api" |
IICP directory endpoint |
timeout_ms |
30000 |
Request timeout — max 120 000 ms |
region |
None |
Preferred node region |
node_token |
None |
Bearer token for authenticated nodes |
Discover options
use DiscoverOptions;
let nodes = client.discover.await?;
Error handling
use IicpError;
match client.submit.await
Error codes match the IICP error reference.
Serving as a node — handler contract
When you run a serving node (IicpNode::serve), your handler returns the inner result
value; serve() wraps it in the TaskResponse.result envelope for you. Do not return
an already-wrapped {"result": ...} value — that double-nests the response and breaks
cross-flavour interop with the Python/TS SDKs (response shape must be {"result": {...}}).
The backends::invoke_backend / openai_compat::invoke helpers return a
{"result": ...} consumer envelope, so when using them as a serve handler, unwrap the
inner value first:
let v = invoke_backend
.await
.unwrap_or_else;
// serve() re-wraps in TaskResponse.result — return the inner value to stay single-level.
Ok
Listen port — default 9484, auto-increment (v0.7.5+)
The official IICP port 9484 is the default listen port (IICP_PORT, --port).
The iicp-node binary auto-increments to the next free port when 9484 is already
in use, so several nodes on one host don't need hand-picked ports — first binds
9484, second 9485, third 9486, etc. Each node gets its own port (hence its own NAT
pinhole); multiple models on one node share that single port. Auto-increment is
skipped when you pass an explicit --public-endpoint.
NAT traversal — automatic (v0.7.3+)
Since v0.7.3, NAT detection runs automatically on every iicp-node serve startup — no flags
needed. Requires the nat feature (UPnP detection):
[]
= { = "0.7", = ["nat"] }
# For relay substrate (CGNAT fallback): add "iicp-tcp"
= { = "0.7", = ["nat", "iicp-tcp"] }
| Tier | When | What happens |
|---|---|---|
| 0 | VPS/cloud (public IP on NIC) or IICP_PUBLIC_ENDPOINT set |
Registers directly |
| 1a | Home router with UPnP, no CGNAT | Port-forward via UPnP → register WAN IP |
| 1b | CGNAT + IPv6 + AddPinhole works | Registers IPv6 with firewall rule |
| 1c | CGNAT + IPv6 + AddPinhole fails (FRITZ!Box error 606) | Registers IPv6 + logs guidance |
| 3 | CGNAT + no usable IPv6 | Auto-elects relay from directory |
| 4 | Nothing worked | Serves locally with operator guidance |
Environment-specific behaviour
Docker bridge (-p 8020:8020) — UPnP is skipped (reaches Docker NAT, not home router).
Set IICP_PUBLIC_ENDPOINT:
CGNAT + no IPv6 → automatic relay:
[iicp-node] NAT tier=3: auto-electing relay from directory...
[iicp-node] auto-elected relay: relay.example.com:9485
Running a relay-capable node (relay operator)
use ;
let node = new;
Opt-out / override
IICP_AUTO_DETECT_NAT=false # disable detection entirely
IICP_PUBLIC_ENDPOINT=http://x.x.x.x:8020 # trust this endpoint
IICP_RELAY_WORKER_ENDPOINT=host:9485 # specific relay instead of auto-elect
SDK conformance
| Rule | Description | Status |
|---|---|---|
| SDK-01 | discover → select → submit pipeline | ✓ |
| SDK-02 | task_id auto-generated (UUID v4) |
✓ |
| SDK-03 | Intent URN pattern validation (regex) | ✓ |
| SDK-04 | timeout_ms capped at 120 000 ms |
✓ |
| SDK-05 | Retry on 429 / 503 | planned |
| SDK-06 | W3C traceparent propagation |
planned |
Conformance tier: iicp:sdk:v1 (spec S.14) · Request a badge
Development
Links
- Protocol spec — full IICP specification
- Node setup guide — run your own node
- Error reference — all error codes
- iicp-client-python — Python SDK
- iicp-client-typescript — TypeScript SDK
Apache 2.0 · iicp.network