registry
↗
install.sh
2.4k
18,298
Menu
GitHub
18,298
Discord
2.4k
install.sh
unreasonably
scalable
software engineering
Software engineering is an exercise in assembling categories of services.
Every new capability means a new system to learn, configure, deploy, and monitor. The complexity of actual integrations is — overwhelming for devs and for AI context.
quadratic
iii fundamentally . And we ship integrations the same way node ships packages so using a new service is as easy as importing a new library.
eliminates this complexity
get started
→
copy prompt
“
Read https://iii.dev/llms.txt and https://iii.dev/AGENTS.md…
”
Thanks for subscribing!
Follow our development
implementation
O
(
n
(
n
−
1
)
2
·
your tolerance for integrations
)
20
integrations
§ 00 · EXPERIENCE
any task.
iii makes it unreasonably efficient to create and extend software.
one experience.
Slack Messages
A
Alex
Product Lead
We need to classify user-submitted content for toxicity before it goes live. Can you set something up?
TKT-001
/
Classify user content for toxicity
See what it's like to work with iii
↵
1
any service.
The answer to "we need X" stops being "evaluate, procure, integrate." It becomes: add a worker.
one abstraction.
matches
00
View the Worker Registry
↗
any language.
python registers a function. rust registers a function. node consumes both.
one protocol.
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
Rust Worker
data transform
02
iii_sdk
use
::
{
register_worker
,
IIIError
,
Value
,
}
;
serde_jsonjson
use
::
;
async
fn
transform
(
input
:
Value
,
)
->
Result
<
Value
,
IIIError
>
{
nums
let
:
Vec
<
f64
>
=
serde_jsoninput
::
from_value
(
)
?
;
result
let
:
Vec
<
f64
>
=
numsx x
.
iter
(
)
.
map
(
|
|
*
2.0
)
.
collect
(
)
;
result
Ok
(
json!
(
)
)
}
#[tokio::main]
async
fn
main
(
)
->
Result
<
(
)
,
IIIError
>
{
iii
let
=
register_worker
(
"ws://localhost:49134"
,
InitOptions
::
default
(
)
,
)
?
;
iii
.
register_function
(
"data::transform"
,
transform
,
)
;
Ok
(
(
)
)
}
Python Worker
ML inference
03
torch
import
iii register_worker
from
import
iii
=
register_worker
(
"ws://localhost:49134"
)
input
async
def
predict
(
)
:
t torchinput
=
.
tensor
(
[
"data"
]
)
result t
=
model
(
)
return
{
result
"predictions"
:
.
tolist
(
)
}
iii
.
register_function
(
predict
"ml::predict"
,
)
ts → rs
→
rs runs
→
nums resolved
→
ts → py
→
py runs
→
pred resolved
→
log
step / 7 —
3
node await resolves — nums = [2.0, 4.0, 6.0]
ts → rs
rs runs
nums resolved
ts → py
py runs
pred resolved
log
node triggers data::transform — awaiting
step 1/7
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
rust transform() runs
step 2/7
Rust Worker
data transform
02
iii_sdk
use
::
{
register_worker
,
IIIError
,
Value
,
}
;
serde_jsonjson
use
::
;
async
fn
transform
(
input
:
Value
,
)
->
Result
<
Value
,
IIIError
>
{
nums
let
:
Vec
<
f64
>
=
serde_jsoninput
::
from_value
(
)
?
;
result
let
:
Vec
<
f64
>
=
numsx x
.
iter
(
)
.
map
(
|
|
*
2.0
)
.
collect
(
)
;
result
Ok
(
json!
(
)
)
}
#[tokio::main]
async
fn
main
(
)
->
Result
<
(
)
,
IIIError
>
{
iii
let
=
register_worker
(
"ws://localhost:49134"
,
InitOptions
::
default
(
)
,
)
?
;
iii
.
register_function
(
"data::transform"
,
transform
,
)
;
Ok
(
(
)
)
}
node await resolves — nums = [2.0, 4.0, 6.0]
step 3/7
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
node triggers ml::predict — awaiting
step 4/7
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
python predict() runs
step 5/7
Python Worker
ML inference
03
torch
import
iii register_worker
from
import
iii
=
register_worker
(
"ws://localhost:49134"
)
input
async
def
predict
(
)
:
t torchinput
=
.
tensor
(
[
"data"
]
)
result t
=
model
(
)
return
{
result
"predictions"
:
.
tolist
(
)
}
iii
.
register_function
(
predict
"ml::predict"
,
)
node await resolves — pred = { predictions: […] }
step 6/7
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
logger.info(pred) — result printed
step 7/7
Node.js Worker
orchestrator
01
register
import
{
Worker
,
Logger
}
from
"iii-sdk"
iii
const
=
registerWorker
(
"ws://localhost:49134"
)
logger
const
=
new
Logger
(
)
nums iii
const
=
await
.
trigger
(
{
function_id
:
"data::transform"
,
payload
:
[
1.0
,
2.0
,
3.0
]
,
}
)
// → [2.0, 4.0, 6.0]
pred iii
const
=
await
.
trigger
(
{
function_id
:
"ml::predict"
,
nums
payload
:
{
data
:
}
,
}
)
// → { predictions: […] }
loggerpred
.
info
(
)
// ml::predict → { predictions: [0.91, 0.07, 0.02] }
step /7
3
any agent.
agents aren't a new category of infrastructure. they're just workers — same protocol, same trace, same engine.
one system.
any log.
a system you and your agents can from end to end.
one context.
see
developerconsole
workers
functions
triggers
states
streams
queues
traces
logs
config
online · 4/4
v0.11.3 · 127.0.0.1:1111
/ 09 ·
01
workers
workers
▣
10/10
internal · refresh
⌕ search workers by name, id, runtime, ip…
all 10
node 3
rust 4
python 2
go 1
planner
node 0.11.3
127.0.0.1 · pid 252 · 4 fn · 1m ago
›
tool-runner
rust 0.11.3
127.0.0.1 · pid 95970 · 11 fn · · 1m ago
3 active
›
embed-worker
python 0.11.0
127.0.0.1 · pid 218 · 3 fn · 1m ago
›
iii-lsp
rust 0.1.0
127.0.0.1 · pid 28041 · 2 fn · 1m ago
›
content-router
node 0.11.3
127.0.0.1 · pid 14872 · 5 fn · · 2m ago
2 active
›
iii-state
rust 0.11.3
10.0.0.4 · pid 4421 · 6 fn · 4m ago
›
iii-durable
rust 0.11.3
10.0.0.4 · pid 4422 · 8 fn · · 4m ago
5 active
›
content-classifier
python 0.11.0
10.0.0.7 · pid 9128 · 2 fn · 6m ago
›
billing-svc
go 0.11.0
10.0.0.9 · pid 7203 · 4 fn · 7m ago
›
notify-bridge
node 0.11.3
10.0.0.11 · pid 6610 · 3 fn · 8m ago
›
every worker — across runtimes — discovered as it connects.
functions
≡
38
system · refresh
⌕ search functions…
▾ agent
5 functions
</>
agent::plan
›
</>
agent::run_tools
⌄
</>
agent::synthesize
›
</>
agent::critique
›
</>
agent::reflect
›
▾ tools
6 functions
</>
tools::web_search
›
</>
tools::code_exec
›
</>
tools::browse
›
</>
tools::fetch
›
</>
tools::file_io
›
</>
tools::shell
›
▾ memory
4 functions
</>
memory::recall
›
</>
memory::store
›
</>
memory::embed
›
</>
memory::search
›
▾ content
4 functions
</>
content::classify
›
</>
content::route
›
</>
content::on-flagged
›
</>
content::publish
›
▾ state
4 functions
</>
state::get
›
</>
state::set
›
</>
state::delete
›
</>
state::scan
›
▾ durable
3 functions
</>
durable::publish
›
</>
durable::subscribe
›
</>
durable::ack
›
▾ billing
4 functions
</>
billing::charge
›
</>
billing::refund
›
</>
billing::usage
›
</>
billing::invoice
›
▾ notify
3 functions
</>
notify::email
›
</>
notify::slack
›
</>
notify::webhook
›
▾ iii
5 functions
</>
iii::on_functions_available
›
</>
iii::on_worker_connect
›
</>
iii::trace::open
›
</>
iii::log
›
</>
iii::heartbeat
›
agent::run_tools
execute a message
invoke function
input (json)
{ "plan_id": "p_7f3a", "tools": ["web_search","code_exec"] }
every function — every language — invokable from one place.
triggers
⌁
12
all 12
http 5
event 5
cron 2
⌕ search triggers, functions, paths, topics…
▾ http
5 triggers
⌖
POST /agent/run
agent::plan
http
⌖
POST /content/submit
content::route
http
⌖
POST /billing/charge
billing::charge
http
⌖
GET /memory/search
memory::search
http
⌖
POST /webhooks/stripe
notify::webhook
http
▾ event
5 triggers
◇
tool::completed
agent::synthesize
event
◇
plan::ready
agent::run_tools
event
◇
content::flagged
content::on-flagged
event
◇
billing::charged
notify::email
event
◇
worker::connected
iii::on_worker_connect
event
▾ cron
2 triggers
⏱
every 5m
iii::heartbeat
cron
⏱
0 0 * * *
billing::invoice
cron
POST /agent/run
function: agent::plan
api endpoint
POST /api/engine/agent/run
request body
{ "query": "research iii's primitives" }
200
{ "run_id": "r_98ac", "plan_id": "p_7f3a" }
http, events, cron, websockets — every entrypoint, one schema.
states
◫
key-value store
7 groups
refresh
⌕ search groups…
▣
agent
42
▣
memory
128
▣
session
31
▣
moderation
87
▣
billing
54
▣
config
19
▣
cache
364
key ↑
type
preview
plan_p_7f3a
json
{ steps: 4, …}
⎘ ✕
plan_p_88e1
json
{ steps: 7, …}
⎘ ✕
plan_p_a1c4
json
{ steps: 3, …}
⎘ ✕
token_count
number
148,209
⎘ ✕
last_query
string
"research iii…"
⎘ ✕
flags:u_4188
number
3
⎘ ✕
flags:u_9920
number
1
⎘ ✕
embed_index
vector
[1024d × 8,420]
⎘ ✕
session:s_be12
json
{ user: "u_4188", …}
⎘ ✕
cache:web:opentel…
blob
14.2 KB
⎘ ✕
plan_p_7f3a
type
json
value
{ "steps": 4, "tools": ["web_search","code_exec"], "estimate_ms": 7400 }
durable state — namespaced, typed, observable.
streams
≋
websocket monitor
pause · export · clear · system
messages
2,418
1,892 inbound
↘
526 outbound
↗
size: 184 kb
ws://127.0.0.1:3113/ws/streams
all
↘ inbound
↗ outbound
12:38:01.030
disconnected
{"message":"WebSocket connection closed"}
12:38:00.020
connected
{"message":"WebSocket connection established","url":"ws://127.0.0.1:3113/ws/streams"}
12:37:59.823
disconnected
{"message":"agent::token","token":"primitives"}
12:37:55.819
connected
{"message":"agent::token","token":"composable"}
12:37:52.805
disconnected
{"message":"agent::token","token":"runtime"}
12:37:49.798
connected
{"message":"tool::web_search","query":"opentelemetry"}
12:37:46.794
connected
{"message":"agent::step","idx":2}
12:37:42.602
connected
{"message":"content::flagged","author":"u_4188","score":0.91}
12:37:39.118
connected
{"message":"billing::charged","amount":2400,"customer":"c_8821"}
12:37:35.482
connected
{"message":"memory::store","key":"emb:3f02","bytes":4096}
12:37:31.227
connected
{"message":"notify::email","to":"alex@motia.dev","template":"flagged"}
12:37:28.014
connected
{"message":"durable::publish","topic":"comment.publish","seq":18420}
12:37:24.901
connected
{"message":"worker::heartbeat","worker":"tool-runner","load":0.42}
live websocket bus — agent tokens, tool calls, status, in real time.
queues
≣
9 topics
12 subscribers
refresh
⌕ filter queues…
≣
tool-calls
durable
142 pending · 38 in-flight · 2 dead
›
≣
plan-events
fanout
12 pending · 9 in-flight · 0 dead
›
≣
embed-batch
durable
821 pending · 64 in-flight · 4 dead
›
≣
comment.publish
durable
48 pending · 21 in-flight · 0 dead
›
≣
comment.review
durable
204 pending · 12 in-flight · 1 dead
›
≣
billing.charge
durable
6 pending · 3 in-flight · 0 dead
›
≣
notify.email
fanout
88 pending · 14 in-flight · 0 dead
›
≣
notify.slack
fanout
2 pending · 1 in-flight · 0 dead
›
≣
memory.index
durable
312 pending · 28 in-flight · 0 dead
›
named queues — backpressure & retries, native to the protocol.
traces
⎇
1,847
system · pause · refresh
⌕ search traces… · status · time range · duration · service · operation
POST /agent/run
e08ff04 · 1.95ms · ⎇
plan
run_tools
web_search
code_exec
synthesize
12:38:36
POST /content/submit
4cda981 · 8.42ms · ⎇
route
classify
publish
notify
12:38:32
iii::on_functions_available
b92fbded · 2.28ms
12:38:30
POST /billing/charge
71f084a · 14.21ms · ⎇
charge
state::set
notify::email
12:38:24
tools::web_search
709bb22b · 2.71ms
12:38:16
memory::search
3e78c2f · 42.18ms
embed
vector::knn
12:38:08
memory::store
aa521adb · 2.40ms
12:37:50
tools::code_exec
5f631ce1 · 1.06ms
12:37:48
notify::webhook
9b211ce · 502 · 3.04s
timeout
12:37:14
agent::synthesize
2ce92e90 · 1.46ms
12:36:50
opentelemetry, native — every span across every language, one trace.
logs
›_
14,208/14,208
pause · export · clear
time ▾
all severities ▾
⌕ search by trace id, source, or message…
11,402 2,612 184 10
●
●
●
●
●
12:38:35.302
221e521…
iii
new functions detected, firing functions-available trigger
●
12:38:34.821
billing-svc
charge succeeded customer= amount=
c_8821
2400
●
12:38:33.114
notify-bridge
delivered → alex@motia.dev
notify::email
●
12:38:32.402
content-router
classifier latency p99=842ms (budget 600ms)
●
12:38:16.336
iii
Endpoint →
[REGISTERED]
POST /agent/run
agent::plan
●
12:38:16.336
iii
Function
[REGISTERED]
tools::web_search
●
12:38:16.335
iii
Worker registered (rust)
tool-runner
●
12:38:14.610
iii
Worker registered (go)
billing-svc
●
12:38:14.610
iii
tool-runner reconnect attempt 1
●
12:38:13.815
iii
Function
[UNREGISTERED]
tools::web_search
●
12:38:08.219
embed-worker
indexed batch 0e8f2a · vectors= · 184ms
512
●
12:37:39.302
8a682f6a…
iii
Function not found: agent::critique
●
12:37:14.022
notify-bridge
webhook 502 stripe.com — retry queued (3/5)
●
12:37:18.301
7e0703f4…
iii
tools::code_exec called in Python with q="2+2"
●
12:36:54.594
iii
new functions detected, firing functions-available trigger
●
12:36:52.567
iii
Function
[REGISTERED]
iii.on_functions_available
structured logs — protocol-native, severity-coded, trace-linked.
configuration
◉
10/10 healthy
view config · export · system · refresh
▣
10
workers
≡
38
functions
⌁
12
triggers
≣
9
queues
◫
725
state keys
≋
2,418
stream msgs
⎇
1,847
traces
✓
10
healthy
iii engine
●
REST API & DevTools
http://127.0.0.1:3113/api/engine
streams
●
websocket streams
ws://127.0.0.1:3113/ws/streams
sdk bridge
●
worker connections
ws://localhost:49134
traces
●
otel collector
grpc://127.0.0.1:4317
state store
●
durable kv
tcp://10.0.0.4:7521
queue broker
●
durable topics
tcp://10.0.0.4:7522
embed index
●
vector store
tcp://10.0.0.7:6333
billing
●
payment gateway
https://10.0.0.9:8080
notify bridge
●
email · slack · webhook
https://10.0.0.11:8081
auth
●
jwt · oidc
https://auth.iii.local
trigger types
⌁
10
http
"http"
event
"event"
cron
"cron"
state
"state"
stream::join
"stream::join"
stream::leave
"stream::leave"
subscribe
"subscribe"
queue
"queue"
webhook
"webhook"
log
"log"
worker pools
▤
4
rust
4
connected workers
node
3
connected workers
python
2
connected workers
go
1
connected workers
the system at a glance — every primitive, healthy and addressable.
in a nutshell.
iii
every capability, every framework, and every tool become a pattern on the same core system.
execution model
— how iii runs work. durable, interoperable, simple.
01 / 06
durable orchestration
coordinate long-running, failure-tolerant execution across workers and triggers.
02 / 06
interoperable execution
execute across languages natively, as if it were one runtime.
03 / 06
simple primitives
collapse distributed backend design into a paradigm humans and agents can reason about.
live system traits
— what iii becomes once running. discoverable, extensible, observable.
04 / 06
live discovery
functions and triggers exposed by one worker become visible across the system in real time.
05 / 06
live extensibility
add new workers and capabilities to a live iii system without redesigning the architecture.
06 / 06
live observability
observe operations, traces, and behavior across the entire connected stack in real time.
get started.
install the engine, check out the code, chat with us, or subscribe for updates.
$
curl -fsSL install.sh | sh
Thanks for subscribing!
GitHub
Discord
online
130
a next-generation software system. workers. triggers. functions.
developers
contact
© Motia LLC ·
pronounced
"three eye"
tweaks · navbar
accent
link case
install pill
show mode toggle
hero viz design