/iii-sdk-reference
Use when working with iii SDK APIs across Node.js, browser, Python, Rust, or Go: package installation, worker initialization, function registration, calling functions, observers and observer hooks, local dispatch, channels, logging, OpenTelemetry, and language-specific caveats.
Claude Code
$ npx -y skills add iii-hq/iii --skill iii-sdk-reference --agent claude-code
Codex
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a codex -y
Cursor
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a cursor -y
Gemini CLI
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a gemini-cli -y
GitHub Copilot
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a github-copilot -y
OpenCode
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a opencode -y
Windsurf
$ npx skills add iii-hq/iii --skill iii-sdk-reference -a windsurf -y
SKILL.md
iii-sdk-reference.SKILL.mdname: iii-sdk-reference
description: >-
Use when working with iii SDK APIs across Node.js, browser, Python, Rust, or Go: package
installation, worker initialization, function registration, calling functions, observers and
observer hooks, local dispatch, channels, logging, OpenTelemetry, and language-specific caveats.
SDK Reference
Use this skill for language-specific SDK details. Use `iii-core-primitives` for the common model and `iii-error-handling` for exception handling.
Install
# TypeScript / Node.js
npm install iii-sdk
# Browser apps
npm install iii-browser-sdk
# Python
pip install iii-sdk
# Rust
cargo add iii-sdk
# Go
go get github.com/iii-hq/iii/sdk/packages/go/iii
Choose the SDK
| SDK | Package | Best for | Important caveat | | --- | --- | --- | --- | | Node.js | `iii-sdk` | Server-side TypeScript/JavaScript workers | Supports custom headers, Logger, OpenTelemetry, HTTP-invoked functions | | Browser | `iii-browser-sdk` | Web apps and interactive UI callbacks | Connect through the `rbac-proxy` worker's public port, never the engine port; keep secrets server-side | | Python | `iii-sdk` | Sync or async Python workers | Use `call_async` inside async handlers | | Rust | `iii-sdk` | High-performance tokio workers | Handler error type should map into `iii_sdk::Error` | | Go | `github.com/iii-hq/iii/sdk/packages/go/iii` | Go services | Handlers take `(ctx, json.RawMessage)`; pass the handler's `ctx` to `Call` |
`Logger`/OpenTelemetry, HTTP request/response types, stream, queue, and worker-connection types live in the helpers package, installed alongside the SDK: `@iii-dev/helpers` (Node, with submodules like `/observability` and `/http`) or `iii-helpers` (Python `iii_helpers.*`, Rust `iii_helpers::*`).
Common API Map
| Capability | Node / browser | Python | Rust | Go | | --- | --- | --- | --- | --- | | Connect worker | `registerWorker(url, options?)` | `register_worker(address, options?)` | `register_worker(url, InitOptions)` | `iii.RegisterWorker(url, opts...)` | | Register local function | `registerFunction(id, handler, options?)` | `register_function(id, handler, **options)` | `register_function("id", RegisterFunction::new(...))` | `client.RegisterFunction(id, handler, opts...)` | | Call a function | `call({ function_id, payload })` | `call(request)` / `call_async(request)` | `call(CallRequest::new(id, payload))` | `client.Call(ctx, iii.CallRequest{...})` | | Durable enqueue | `CallAction.Enqueue({ queue })` | `{"type": "enqueue", "queue": name}` | `CallAction::Enqueue { queue }` | `iii.EnqueueAction(queue)` | | Fire and forget | `CallAction.Void()` | `{"type": "void"}` | `CallAction::Void` | `iii.VoidAction()` | | Observe a function | `observe(source, target, options?)`; `observe('fn::id', target)` | `observe(source, target, options)` | `observe(Source::function(id)..., target)` / `observe_with(.., ObserverOptions)` | `client.Observe(iii.Source{...}, target, opts...)` / `client.ObserveFunction(id, target)` | | Function options for observers | `{ args_format, private, observable }` | `args_format=`, `private=`, `observable=` | `.args_format::<T>().private().observable(false)` | `iii.FunctionOptions{ArgsFormat, Private, ...}` | | Observer hooks, one function | `iii.onObserverAdded(id, h)`, `onObserverRemoved(id, h)`, `onObservationMatch(id, m)`, `onObservationDeliver(id, h)`, or the same on the `FunctionRef` | `@iii.on_observer_added(id)`, `@ref.on_observer_removed`, `ref.on_observation_match(m)`, `ref.on_observation_deliver(h)` | `on_observer_added_for(id, h)`, `on_observer_removed_for(id, h)`, `on_observation_match_for(id, m)`, `on_observation_deliver_for(id, h)`, or `function.on_observer_added(h)` | `client.OnObserverAddedFor(id, h)`, `OnObserverRemovedFor`, `OnObservationMatchFor`, `OnObservationDeliverFor`, or `ref.OnObserverAdded(h)` | | Observer hooks, every function | `iii.onObserverAdded(h)`, `iii.onObserverRemoved(h)` | `@iii.on_observer_added`, `@iii.on_observer_removed` | `on_observer_added(h)`, `on_observer_removed(h)` | `client.OnObserverAdded(h)`, `client.OnObserverRemoved(h)` | | Match observers to calls | `onObservationMatch(id, (obs, call) => boolean)` or `onObservationMatch(id, { observer, call })` | `on_observation_match(id, predicate)` or `on_observation_match(id, observer=, call=)` | `Match::predicate(f)` or `Match::keys(observer_keys, call_keys)` | `iii.MatchFunc(f)` or `iii.MatchKeys(observerKeys, callKeys)` | | Call through an observer (no metadata) | `call({ observer: obs, payload })` | `call_async({"observer": obs, "payload": p})` | `call(CallRequest::observer(&obs, payload))` | `client.Call(ctx, iii.CallRequest{Observer: obs, Payload: p})` | | Current invocation | `currentInvocation()` | `current_invocation()` | `iii_sdk::current_invocation()` | `iii.InvocationFromContext(ctx)` | | Channels | `createChannel(iii)` (`iii-sdk/helpers`) | `create_channel(iii)` / `create_channel_async(iii)` (`iii.helpers`) | `iii_sdk::helpers::create_channel(&iii, None).await` | `client.CreateChannel(ctx, nil)` |
A call's `metadata` is any JSON value, delivered to the handler beside the payload. `null` (Python `None`, Rust `Value::Null`, Go `json.RawMessage("null")`) is the same as no metadata on every path, local or routed. A call through an observer takes no metadata: its target receives the observer's, and every SDK refuses one that names metadata with "a call through an observer takes no metadata; its target receives the observer's metadata".
Node.js
import { registerWorker } from "iii-sdk";
import { Logger } from "@iii-dev/helpers/observability";
const iii = registerWorker("ws://localhost:49134", {
workerName: "node-worker",
invocationTimeoutMs: 30000,
});
iii.registerFunction("users::lookup", async (input) => {
new Logger().info("looking up user", { userId: input.userId });
return { userId: input.userId, name: "Ada" };
});Node supports custom WebSocket headers, `Logger`, OpenTelemetry opti
Read more
name: iii-sdk-reference description: >- Use when working with iii SDK APIs across Node.js, browser, Python, Rust, or Go: package installation, worker initialization, function registration, calling functions, observers and observer hooks, local dispatch, channels, logging, OpenTelemetry, and language-specific caveats.
SDK Reference
Use this skill for language-specific SDK details. Use `iii-core-primitives` for the common model and `iii-error-handling` for exception handling.
Install
# TypeScript / Node.js npm install iii-sdk # Browser apps npm install iii-browser-sdk # Python pip install iii-sdk # Rust cargo add iii-sdk # Go go get github.com/iii-hq/iii/sdk/packages/go/iii
Choose the SDK
| SDK | Package | Best for | Important caveat | | --- | --- | --- | --- | | Node.js | `iii-sdk` | Server-side TypeScript/JavaScript workers | Supports custom headers, Logger, OpenTelemetry, HTTP-invoked functions | | Browser | `iii-browser-sdk` | Web apps and interactive UI callbacks | Connect through the `rbac-proxy` worker's public port, never the engine port; keep secrets server-side | | Python | `iii-sdk` | Sync or async Python workers | Use `call_async` inside async handlers | | Rust | `iii-sdk` | High-performance tokio workers | Handler error type should map into `iii_sdk::Error` | | Go | `github.com/iii-hq/iii/sdk/packages/go/iii` | Go services | Handlers take `(ctx, json.RawMessage)`; pass the handler's `ctx` to `Call` |
`Logger`/OpenTelemetry, HTTP request/response types, stream, queue, and worker-connection types live in the helpers package, installed alongside the SDK: `@iii-dev/helpers` (Node, with submodules like `/observability` and `/http`) or `iii-helpers` (Python `iii_helpers.*`, Rust `iii_helpers::*`).
Common API Map
| Capability | Node / browser | Python | Rust | Go | | --- | --- | --- | --- | --- | | Connect worker | `registerWorker(url, options?)` | `register_worker(address, options?)` | `register_worker(url, InitOptions)` | `iii.RegisterWorker(url, opts...)` | | Register local function | `registerFunction(id, handler, options?)` | `register_function(id, handler, **options)` | `register_function("id", RegisterFunction::new(...))` | `client.RegisterFunction(id, handler, opts...)` | | Call a function | `call({ function_id, payload })` | `call(request)` / `call_async(request)` | `call(CallRequest::new(id, payload))` | `client.Call(ctx, iii.CallRequest{...})` | | Durable enqueue | `CallAction.Enqueue({ queue })` | `{"type": "enqueue", "queue": name}` | `CallAction::Enqueue { queue }` | `iii.EnqueueAction(queue)` | | Fire and forget | `CallAction.Void()` | `{"type": "void"}` | `CallAction::Void` | `iii.VoidAction()` | | Observe a function | `observe(source, target, options?)`; `observe('fn::id', target)` | `observe(source, target, options)` | `observe(Source::function(id)..., target)` / `observe_with(.., ObserverOptions)` | `client.Observe(iii.Source{...}, target, opts...)` / `client.ObserveFunction(id, target)` | | Function options for observers | `{ args_format, private, observable }` | `args_format=`, `private=`, `observable=` | `.args_format::<T>().private().observable(false)` | `iii.FunctionOptions{ArgsFormat, Private, ...}` | | Observer hooks, one function | `iii.onObserverAdded(id, h)`, `onObserverRemoved(id, h)`, `onObservationMatch(id, m)`, `onObservationDeliver(id, h)`, or the same on the `FunctionRef` | `@iii.on_observer_added(id)`, `@ref.on_observer_removed`, `ref.on_observation_match(m)`, `ref.on_observation_deliver(h)` | `on_observer_added_for(id, h)`, `on_observer_removed_for(id, h)`, `on_observation_match_for(id, m)`, `on_observation_deliver_for(id, h)`, or `function.on_observer_added(h)` | `client.OnObserverAddedFor(id, h)`, `OnObserverRemovedFor`, `OnObservationMatchFor`, `OnObservationDeliverFor`, or `ref.OnObserverAdded(h)` | | Observer hooks, every function | `iii.onObserverAdded(h)`, `iii.onObserverRemoved(h)` | `@iii.on_observer_added`, `@iii.on_observer_removed` | `on_observer_added(h)`, `on_observer_removed(h)` | `client.OnObserverAdded(h)`, `client.OnObserverRemoved(h)` | | Match observers to calls | `onObservationMatch(id, (obs, call) => boolean)` or `onObservationMatch(id, { observer, call })` | `on_observation_match(id, predicate)` or `on_observation_match(id, observer=, call=)` | `Match::predicate(f)` or `Match::keys(observer_keys, call_keys)` | `iii.MatchFunc(f)` or `iii.MatchKeys(observerKeys, callKeys)` | | Call through an observer (no metadata) | `call({ observer: obs, payload })` | `call_async({"observer": obs, "payload": p})` | `call(CallRequest::observer(&obs, payload))` | `client.Call(ctx, iii.CallRequest{Observer: obs, Payload: p})` | | Current invocation | `currentInvocation()` | `current_invocation()` | `iii_sdk::current_invocation()` | `iii.InvocationFromContext(ctx)` | | Channels | `createChannel(iii)` (`iii-sdk/helpers`) | `create_channel(iii)` / `create_channel_async(iii)` (`iii.helpers`) | `iii_sdk::helpers::create_channel(&iii, None).await` | `client.CreateChannel(ctx, nil)` |
A call's `metadata` is any JSON value, delivered to the handler beside the payload. `null` (Python `None`, Rust `Value::Null`, Go `json.RawMessage("null")`) is the same as no metadata on every path, local or routed. A call through an observer takes no metadata: its target receives the observer's, and every SDK refuses one that names metadata with "a call through an observer takes no metadata; its target receives the observer's metadata".
Node.js
import { registerWorker } from "iii-sdk";
import { Logger } from "@iii-dev/helpers/observability";
const iii = registerWorker("ws://localhost:49134", {
workerName: "node-worker",
invocationTimeoutMs: 30000,
});
iii.registerFunction("users::lookup", async (input) => {
new Logger().info("looking up user", { userId: input.userId });
return { userId: input.userId, name: "Ada" };
});Node supports custom WebSocket headers, `Logger`, OpenTelemetry opti
Other skills on iii.
More skills from other plugins.
karpathy-guidelines
Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid…
agent-builder
Design and build AI agents for any domain. Use when users: (1) ask to "create an agent", "build an assistant", or "design an AI…
Questions about iii-sdk-reference.
- Which coding agents can use iii-sdk-reference?
- iii-sdk-reference installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

