iii-directory
v0.5.0Engine introspection (functions / triggers / workers), workers registry proxy, and filesystem-backed skill + prompt reader.
- macOS: arm64 · x64
- Linux: arm64 · armv7 · x64
- Windows: arm64 · x64 · x86
full markdown
/workers/iii-directory.md?version=0.5.0. paste it into an llm prompt or pipe it through curl from a worker.install
configuration
- download_timeout_ms: 60000
registry_url: https://api.workers.iii.dev
skills_folder: ./skillsdependencies
readme
iii-directory
Engine introspection, workers registry proxy, and filesystem-backed
skill + prompt reader for the iii engine.
Every public function sits under a single directory::* namespace,
split into four sub-namespaces (all MCP-agnostic):
| Surface | What clients see | When to use it |
|---|---|---|
Skills (directory::skills::*) |
Markdown documents under iii://{id} plus an iii://directory/skills index |
Orientation: "when and why to use my worker's tools" |
Prompts (directory::prompts::*) |
Static prompt templates listed by directory::prompts::list and read by directory::prompts::get |
Parametric command templates the user invokes |
Engine (directory::engine::*) |
Read-side enrichment over engine::functions::list, engine::workers::list, engine::trigger-types::list, engine::triggers::list |
"What's connected to the engine right now?" |
Registry (directory::registry::*) |
HTTP proxy over api.workers.iii.dev with the same workers::{list,info} shape as directory::engine::workers::* |
"What's published in the public registry?" |
Skills and prompts are sourced from a single configured folder on disk
(skills_folder). The only write path is the
directory::skills::download function, which pulls markdown into
skills_folder from either the
workers registry or a GitHub repo. Once
downloaded, files belong to the developer — edit them however you want.
directory::engine::workers::* and directory::registry::workers::*
share the same envelope shape so callers can switch between the local
engine view and the published-registry view without re-learning the API.
Table of contents
- Install
- Configuration
- Quickstart: download some skills
- On-disk layout
- URI scheme
- Functions
- Custom trigger types
- Local development & testing
- Migration from skills v0.2.x
Install
iii worker add iii-directoryiii worker add fetches the binary, writes a config block into
~/.iii/config.yaml, and the engine starts the worker on the next
iii start.
Configuration
# Folder that backs every read (`iii://`, `directory::skills::fetch-skill`,
# `directory::skills::list`, `directory::prompts::*`) and every write
# from `directory::skills::download`. Relative paths are resolved
# against the process current working directory; absolute paths are
# used as-is.
skills_folder: ./skills
# Workers registry base URL — used by `directory::skills::download`
# and the `directory::registry::*` proxies when a `worker=` source is
# specified. Override for self-hosted deployments.
registry_url: https://api.workers.iii.dev
# Timeout for a single download (`git clone` or HTTP request) in ms.
download_timeout_ms: 60000The folder is created on first download if it doesn't exist.
Quickstart: download some skills
# Pull a specific worker's skills + prompts at a fixed semver from
# the registry. Files land under `<skills_folder>/agent-memory/`.
iii trigger --function-id=directory::skills::download \
--payload='{"worker": "agent-memory", "version": "1.2.3"}'
# Same, but always fetch whatever's tagged `latest` (also the default
# when neither version nor tag is given).
iii trigger --function-id=directory::skills::download \
--payload='{"worker": "agent-memory"}'
# Pull a single subfolder out of a public GitHub repo via
# `git clone --depth 1 --branch main`. Files land under
# `<skills_folder>/frontend-design/`. The `branch` field defaults to
# `main`; pass `"master"` for older repos that haven't migrated.
iii trigger --function-id=directory::skills::download \
--payload='{
"repo": "https://github.com/anthropics/skills",
"skill": "frontend-design"
}'The response is { namespace, skills_written, prompts_written, source }
where skills_written and prompts_written are arrays of relative
paths / prompt names that were materialised in this run.
After every successful download the worker fires the
directory::skills::on-change and/or directory::prompts::on-change
trigger types so that subscribers like the mcp worker can
forward MCP notifications/list_changed to their clients.
On-disk layout
The worker assumes a fixed layout under skills_folder:
skills_folder/
<namespace>/ # one folder per `directory::skills::download` namespace
index.md # → iii://<namespace>/index
contacts.md # → iii://<namespace>/contacts
emails/send-email.md # → iii://<namespace>/emails/send-email
prompts/ # ← magic marker for prompts
send-email.md # ← MCP slash-command (needs YAML frontmatter)
triage.mdA few rules:
- Skill ids are the relative path under
skills_folderwith.mdstripped. Each segment must satisfy[a-z0-9_-]{1,64}and the first segment must not be the literalfn(reserved for section URIs). - Prompts live under any
*/prompts/*.mdpath. They must start with a YAML frontmatter block declaring at leastdescription;nameis optional and overrides the file-stem default. - Files anywhere else (i.e. not in a
prompts/segment) are skills.
The download function namespaces by source:
| Source | Destination |
|---|---|
repo=URL skill=NAME branch?=main |
|
worker=NAME version=… |
|
worker=NAME tag=… (default tag=latest) |
|
Re-pulling the same source overwrites files file-by-file — existing siblings outside the response set are preserved (so hand-edited additions survive a re-pull).
URI scheme
Same scheme as previous releases, anchored now on the filesystem:
| URI | Returns |
|---|---|
iii://directory/skills |
Auto-rendered markdown index of every skill in skills_folder. |
iii://{id} |
The body at . Any depth. First segment must NOT equal fn. |
iii://fn/{a}/{b}/.../{leaf} |
Trigger function a::b::...::leaf with {} and serve its output. Each / after fn/ becomes ::. |
The directory::skills::fetch-skill function is a thin batched wrapper
over the same resolver. Pass either uri (single) or uris (array) —
each entry may be a full iii:// URI or a bare skill path (the id
returned by directory::skills::list, auto-prefixed with iii://).
Sections are wrapped as # {uri}\n\n{body} and joined with
\n\n---\n\n.
There is no recursion guard on iii://fn/ URIs — the resolver
will trigger any function the engine exposes, including state::* and
engine::* infra. Adapters that surface
directory::skills::fetch-skill to untrusted callers should add their
own filtering.
Functions
Fifteen functions, all under directory::*. All registrations are
namespace-clean; this worker is intentionally agnostic to MCP and any
other adapter.
directory::skills::* (filesystem reader)
| Function ID | Description |
|---|---|
directory::skills::download |
Pull markdown into skills_folder. Either {repo, skill, branch?} (defaults branch=main) or `{worker, version? |
directory::skills::list |
Metadata-only listing of every fs-backed skill. |
directory::skills::fetch-skill |
Batched read across one or more iii:// URIs or bare skill paths (returns plain markdown). |
directory::prompts::* (filesystem reader)
| Function ID | Description |
|---|---|
directory::prompts::list |
Metadata-only listing of every fs-backed prompt. |
directory::prompts::get |
Fetch one prompt's body + {name, description, modified_at}. Plain shape, no envelope. |
directory::engine::* (engine introspection)
| Function ID | Description |
|---|---|
directory::engine::functions::list |
List functions registered with the engine; filter by search/prefix/worker. |
directory::engine::functions::info |
Single-function detail: schemas, owning worker, registered triggers, bundled how-to. |
directory::engine::triggers::list |
List trigger TYPES registered with the engine; filter by search/prefix/worker. |
directory::engine::triggers::info |
Single trigger-type detail: configuration schema, return schema, instance count. |
directory::engine::registered-triggers::list |
List registered trigger INSTANCES (subscriber rows). |
directory::engine::registered-triggers::info |
Composite: instance + trigger-type detail + function detail. |
directory::engine::workers::list |
List workers connected to the engine; same row shape as directory::registry::workers::list. |
directory::engine::workers::info |
One worker's worker envelope + functions + trigger types + registered triggers. |
directory::registry::* (workers registry HTTP proxy)
| Function ID | Description |
|---|---|
directory::registry::workers::list |
Search published workers in api.workers.iii.dev. Same row shape as directory::engine::workers::list. |
directory::registry::workers::info |
Full registry detail for one worker: worker envelope (matching directory::engine::workers::info.worker) plus readme, api_reference, skills_tree. |
Both directory::registry::* responses are cached in-process for
registry_cache_ttl_ms (default 60s).
There is no directory::skills::register /
directory::prompts::register — see
Migration below.
Custom trigger types
| Trigger type | Fires when | Payload to subscribers |
|---|---|---|
directory::skills::on-change |
After a directory::skills::download that wrote at least one skill markdown file |
{ "op": "download", "namespace": " |
directory::prompts::on-change |
After a directory::skills::download that wrote at least one prompt markdown file |
{ "op": "download", "namespace": " |
Dispatches are fire-and-forget (Void), so the download path doesn't block on downstream latency.
Local development & testing
Run from source
cargo run --release -- --url ws://127.0.0.1:49134 --config ./config.yamlTests
# Fast, offline — exercises the pure helpers (markdown / URI / validators)
# without needing an iii engine.
cargo test --lib
# Full BDD suite — requires an iii engine on ws://127.0.0.1:49134
# (or III_ENGINE_WS_URL). The git-backed download scenarios spin up
# a local fixture repo via `git init`; the registry-backed scenarios
# point a wiremock server at the worker's `registry_url` config.
cargo test
# One feature group at a time. Available tags:
# @engine @read @prompts @download @download_repo @download_registry
cargo test --test bdd -- --tags @downloadThe BDD harness lives under tests/. Feature files mirror the
modules in src/functions/. Step definitions under
tests/steps/ drive each feature through the same
iii.trigger path the production binary uses.
api reference (json)
{
"functions": [
{
"description": "Fetch full registry metadata for one worker: worker envelope (same shape as directory::registry::workers::list rows and directory::engine::workers::info), readme, full API reference (functions + triggers schemas), and tree of skill/prompt file paths. Pass either `version` or `tag` (defaults to tag=\"latest\"). Results are cached for `registry_cache_ttl_ms`.",
"metadata": {},
"name": "directory::registry::workers::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "`directory::registry::workers::info` input. Pass either `version` or `tag`; if neither is provided we fall back to `tag: \"latest\"`.",
"properties": {
"name": {
"description": "Worker name in the registry (e.g. `\"resend\"`).",
"type": "string"
},
"tag": {
"default": null,
"type": [
"string",
"null"
]
},
"version": {
"default": null,
"description": "Mutually exclusive with `tag`. If neither is provided we fall back to `tag: \"latest\"`.",
"type": [
"string",
"null"
]
}
},
"required": [
"name"
],
"title": "WorkerInfoInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ApiReference": {
"properties": {
"functions": {
"default": [],
"items": {
"$ref": "#/definitions/ApiReferenceFunction"
},
"type": "array"
},
"triggers": {
"default": [],
"items": {
"$ref": "#/definitions/ApiReferenceTrigger"
},
"type": "array"
}
},
"type": "object"
},
"ApiReferenceFunction": {
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"metadata": true,
"name": {
"type": "string"
},
"request_schema": true,
"response_schema": true
},
"required": [
"name"
],
"type": "object"
},
"ApiReferenceTrigger": {
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"invocation_schema": true,
"metadata": true,
"name": {
"type": "string"
},
"return_schema": true
},
"required": [
"name"
],
"type": "object"
},
"RegistryAuthor": {
"properties": {
"is_verified": {
"default": false,
"type": "boolean"
},
"name": {
"type": [
"string",
"null"
]
},
"profile_picture": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"SkillsTree": {
"properties": {
"prompts": {
"default": [],
"items": {
"$ref": "#/definitions/SkillsTreePrompt"
},
"type": "array"
},
"skills": {
"default": [],
"items": {
"$ref": "#/definitions/SkillsTreeSkill"
},
"type": "array"
}
},
"type": "object"
},
"SkillsTreePrompt": {
"properties": {
"description": {
"default": null,
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
},
"SkillsTreeSkill": {
"properties": {
"path": {
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
},
"Worker": {
"description": "Shared worker envelope used by both `directory::registry::workers::list` rows and the `worker` field of `directory::registry::workers::info`. Same field names as [`crate::functions::directory::Worker`] so callers learn one shape across local + registry surfaces.",
"properties": {
"author": {
"anyOf": [
{
"$ref": "#/definitions/RegistryAuthor"
},
{
"type": "null"
}
],
"default": null
},
"description": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
"repo": {
"type": [
"string",
"null"
]
},
"version": {
"description": "Latest published version (worker-list) or the resolved version (worker-info, when called with `version` / `tag`).",
"type": [
"string",
"null"
]
}
},
"required": [
"name"
],
"type": "object"
}
},
"properties": {
"api_reference": {
"$ref": "#/definitions/ApiReference"
},
"readme": {
"type": [
"string",
"null"
]
},
"skills_tree": {
"$ref": "#/definitions/SkillsTree"
},
"worker": {
"allOf": [
{
"$ref": "#/definitions/Worker"
}
],
"description": "Same shape as `directory::registry::workers::list` rows (and `directory::engine::workers::info.worker`)."
}
},
"required": [
"api_reference",
"skills_tree",
"worker"
],
"title": "WorkerInfoOutput",
"type": "object"
}
},
{
"description": "Fetch one filesystem-backed prompt by name. Returns the raw markdown body plus name, description, and modified_at — no envelope, no templating.",
"metadata": {},
"name": "directory::prompts::get",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"title": "PromptGetInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"body": {
"description": "Raw markdown body (post-frontmatter) from disk.",
"type": "string"
},
"description": {
"type": "string"
},
"modified_at": {
"description": "File mtime as RFC 3339.",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"body",
"description",
"modified_at",
"name"
],
"title": "PromptGetOutput",
"type": "object"
}
},
{
"description": "Full denormalized detail for one registered trigger: instance config + trigger-type detail + function detail.",
"metadata": {},
"name": "directory::engine::registered-triggers::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
],
"title": "RegisteredTriggerInfoInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FunctionInfoOutput": {
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"function_id": {
"type": "string"
},
"how_guide": {
"anyOf": [
{
"$ref": "#/definitions/HowGuide"
},
{
"type": "null"
}
]
},
"metadata": true,
"registered_triggers": {
"items": {
"$ref": "#/definitions/RegisteredTriggerSummary"
},
"type": "array"
},
"related_skills": {
"description": "Other skills (any `type`) that mention this function via either the literal `function_id` or the `iii://fn/<dotted/path>` URI. Body content is omitted; fetch on demand via `skills::fetch-skill`.",
"items": {
"$ref": "#/definitions/RelatedSkillRef"
},
"type": "array"
},
"request_schema": true,
"response_schema": true,
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"function_id",
"registered_triggers",
"related_skills"
],
"type": "object"
},
"HowGuide": {
"description": "Primary how-to skill that documents this function. Kept tiny so `function-info` stays cheap to render; deeper related skills come back via [`FunctionInfoOutput::related_skills`] as title-only refs that callers can pull on demand through `skills::fetch-skill`.",
"properties": {
"body": {
"type": "string"
},
"skill_id": {
"type": "string"
},
"title": {
"type": "string"
}
},
"required": [
"body",
"skill_id",
"title"
],
"type": "object"
},
"RegisteredTriggerSummary": {
"properties": {
"config": true,
"id": {
"type": "string"
},
"trigger_type": {
"type": "string"
}
},
"required": [
"config",
"id",
"trigger_type"
],
"type": "object"
},
"RelatedSkillRef": {
"description": "Title-only reference to another skill that mentions a function. Bodies are intentionally omitted; callers fetch on demand via `skills::fetch-skill iii://<skill_id>`.",
"properties": {
"skill_id": {
"type": "string"
},
"title": {
"type": "string"
}
},
"required": [
"skill_id",
"title"
],
"type": "object"
},
"TriggerInfoOutput": {
"properties": {
"configuration_schema": {
"description": "SDK 0.11.3 surfaces a single `trigger_request_format` that doubles as the per-instance configuration shape; expose it explicitly so callers don't have to know the alias."
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"instance_count": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"return_schema": true,
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"description",
"id",
"instance_count"
],
"type": "object"
}
},
"properties": {
"config": true,
"function": {
"anyOf": [
{
"$ref": "#/definitions/FunctionInfoOutput"
},
{
"type": "null"
}
],
"description": "Full function detail for `function_id`. `None` if the function has been unregistered between calls."
},
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"metadata": true,
"trigger": {
"anyOf": [
{
"$ref": "#/definitions/TriggerInfoOutput"
},
{
"type": "null"
}
],
"description": "Full trigger-type detail for `trigger_type`. `None` if the type has been unregistered between calls."
},
"trigger_type": {
"type": "string"
},
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"config",
"function_id",
"id",
"trigger_type"
],
"title": "RegisteredTriggerInfoOutput",
"type": "object"
}
},
{
"description": "Full detail for one function: schemas, owning worker, registered triggers that target it, and any matching how-to skill from skills_folder.",
"metadata": {},
"name": "directory::engine::functions::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"function_id": {
"type": "string"
}
},
"required": [
"function_id"
],
"title": "FunctionInfoInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"HowGuide": {
"description": "Primary how-to skill that documents this function. Kept tiny so `function-info` stays cheap to render; deeper related skills come back via [`FunctionInfoOutput::related_skills`] as title-only refs that callers can pull on demand through `skills::fetch-skill`.",
"properties": {
"body": {
"type": "string"
},
"skill_id": {
"type": "string"
},
"title": {
"type": "string"
}
},
"required": [
"body",
"skill_id",
"title"
],
"type": "object"
},
"RegisteredTriggerSummary": {
"properties": {
"config": true,
"id": {
"type": "string"
},
"trigger_type": {
"type": "string"
}
},
"required": [
"config",
"id",
"trigger_type"
],
"type": "object"
},
"RelatedSkillRef": {
"description": "Title-only reference to another skill that mentions a function. Bodies are intentionally omitted; callers fetch on demand via `skills::fetch-skill iii://<skill_id>`.",
"properties": {
"skill_id": {
"type": "string"
},
"title": {
"type": "string"
}
},
"required": [
"skill_id",
"title"
],
"type": "object"
}
},
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"function_id": {
"type": "string"
},
"how_guide": {
"anyOf": [
{
"$ref": "#/definitions/HowGuide"
},
{
"type": "null"
}
]
},
"metadata": true,
"registered_triggers": {
"items": {
"$ref": "#/definitions/RegisteredTriggerSummary"
},
"type": "array"
},
"related_skills": {
"description": "Other skills (any `type`) that mention this function via either the literal `function_id` or the `iii://fn/<dotted/path>` URI. Body content is omitted; fetch on demand via `skills::fetch-skill`.",
"items": {
"$ref": "#/definitions/RelatedSkillRef"
},
"type": "array"
},
"request_schema": true,
"response_schema": true,
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"function_id",
"registered_triggers",
"related_skills"
],
"title": "FunctionInfoOutput",
"type": "object"
}
},
{
"description": "List filesystem-backed skills (id, body length, modified_at) from skills_folder.",
"metadata": {},
"name": "directory::skills::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ListSkillsInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"SkillEntry": {
"properties": {
"bytes": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"id": {
"type": "string"
},
"modified_at": {
"description": "File mtime as RFC 3339 (best effort; empty if unavailable).",
"type": "string"
}
},
"required": [
"bytes",
"id",
"modified_at"
],
"type": "object"
}
},
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/SkillEntry"
},
"type": "array"
}
},
"required": [
"skills"
],
"title": "ListSkillsOutput",
"type": "object"
}
},
{
"description": "List every worker currently connected to the engine. Filter by name substring, runtime, or status. Same row shape as directory::registry::workers::list so callers learn one envelope.",
"metadata": {},
"name": "directory::engine::workers::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"runtime": {
"default": null,
"description": "Exact runtime match (e.g. `\"rust\"`, `\"node\"`).",
"type": [
"string",
"null"
]
},
"search": {
"default": null,
"description": "Case-insensitive substring match against `name`.",
"type": [
"string",
"null"
]
},
"status": {
"default": null,
"description": "Exact status match (e.g. `\"connected\"`).",
"type": [
"string",
"null"
]
}
},
"title": "WorkerListInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Worker": {
"description": "Shared worker envelope used by both `directory::worker-list` rows and the `worker` field of `directory::worker-info`. Field names line up with `registry::Worker` (see [`crate::functions::registry::Worker`]) so callers learn one shape across local + registry surfaces.",
"properties": {
"active_invocations": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"connected_at_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"description": {
"description": "Engine-side workers carry no description; field present for shape parity with `registry::Worker.description`. Always `None`.",
"type": [
"string",
"null"
]
},
"function_count": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"id": {
"description": "Engine-assigned connection id (directory-specific).",
"type": "string"
},
"ip_address": {
"type": [
"string",
"null"
]
},
"isolation": {
"type": [
"string",
"null"
]
},
"name": {
"description": "Worker name as registered with the engine.",
"type": [
"string",
"null"
]
},
"os": {
"type": [
"string",
"null"
]
},
"runtime": {
"type": [
"string",
"null"
]
},
"status": {
"description": "Connection state (e.g. `\"connected\"`, `\"disconnected\"`).",
"type": "string"
},
"version": {
"description": "Worker version string from the worker's published manifest.",
"type": [
"string",
"null"
]
}
},
"required": [
"active_invocations",
"connected_at_ms",
"function_count",
"id",
"status"
],
"type": "object"
}
},
"properties": {
"workers": {
"items": {
"$ref": "#/definitions/Worker"
},
"type": "array"
}
},
"required": [
"workers"
],
"title": "WorkerListOutput",
"type": "object"
}
},
{
"description": "List every trigger TYPE registered with the engine. Filter by search, prefix, worker. (For registered trigger instances, use directory::engine::registered-triggers::list.)",
"metadata": {},
"name": "directory::engine::triggers::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"prefix": {
"default": null,
"type": [
"string",
"null"
]
},
"search": {
"default": null,
"type": [
"string",
"null"
]
},
"worker": {
"default": null,
"type": [
"string",
"null"
]
}
},
"title": "TriggerListInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"TriggerListEntry": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"description",
"id"
],
"type": "object"
}
},
"properties": {
"triggers": {
"items": {
"$ref": "#/definitions/TriggerListEntry"
},
"type": "array"
}
},
"required": [
"triggers"
],
"title": "TriggerListOutput",
"type": "object"
}
},
{
"description": "List filesystem-backed prompts (name, description, modified_at) from skills_folder.",
"metadata": {},
"name": "directory::prompts::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ListPromptsInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"PromptEntry": {
"properties": {
"description": {
"type": "string"
},
"modified_at": {
"description": "File mtime as RFC 3339.",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"modified_at",
"name"
],
"type": "object"
}
},
"properties": {
"prompts": {
"items": {
"$ref": "#/definitions/PromptEntry"
},
"type": "array"
}
},
"required": [
"prompts"
],
"title": "ListPromptsOutput",
"type": "object"
}
},
{
"description": "List registered trigger instances (the link rows between trigger types and target functions). Filter by trigger_type, function_id, worker, or free-text search.",
"metadata": {},
"name": "directory::engine::registered-triggers::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"function_id": {
"default": null,
"type": [
"string",
"null"
]
},
"search": {
"default": null,
"type": [
"string",
"null"
]
},
"trigger_type": {
"default": null,
"type": [
"string",
"null"
]
},
"worker": {
"default": null,
"type": [
"string",
"null"
]
}
},
"title": "RegisteredTriggerListInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"RegisteredTriggerListEntry": {
"properties": {
"config_summary": {
"description": "Truncated (~80 chars) JSON preview of `config` so listings stay scannable. Use `directory::registered-trigger-info` for the full payload.",
"type": "string"
},
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"trigger_type": {
"type": "string"
},
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"config_summary",
"function_id",
"id",
"trigger_type"
],
"type": "object"
}
},
"properties": {
"registered_triggers": {
"items": {
"$ref": "#/definitions/RegisteredTriggerListEntry"
},
"type": "array"
}
},
"required": [
"registered_triggers"
],
"title": "RegisteredTriggerListOutput",
"type": "object"
}
},
{
"description": "Fetches the content of one or more skill resources. Each entry may be either a full iii:// URI or a bare skill path (the id returned by directory::skills::list, e.g. \"directory/skills/list\") which is auto-prefixed with iii://. Batch with `uris` when helpful.",
"metadata": {
"tool": {
"label": "Fetch skill"
}
},
"name": "directory::skills::fetch-skill",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"uri": {
"default": null,
"description": "A single skill resource to read. Either a full `iii://` URI or a bare skill path (the id returned by `directory::skills::list`, e.g. `\"directory/skills/list\"`) which is auto-prefixed with `iii://`.",
"type": [
"string",
"null"
]
},
"uris": {
"default": null,
"description": "One or more skill resources to read in order. Same shape rules as `uri`. When both `uri` and `uris` are provided, `uris` wins (matches the TS reference implementation).",
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"title": "FetchSkillInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "String",
"type": "string"
}
},
{
"description": "Worker envelope plus the lists of functions, trigger types, and registered triggers it owns. The `worker` field has the same shape as directory::registry::workers::info so callers can switch between local + registry surfaces with the same parser.",
"metadata": {},
"name": "directory::engine::workers::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"title": "WorkerInfoInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Worker": {
"description": "Shared worker envelope used by both `directory::worker-list` rows and the `worker` field of `directory::worker-info`. Field names line up with `registry::Worker` (see [`crate::functions::registry::Worker`]) so callers learn one shape across local + registry surfaces.",
"properties": {
"active_invocations": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"connected_at_ms": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"description": {
"description": "Engine-side workers carry no description; field present for shape parity with `registry::Worker.description`. Always `None`.",
"type": [
"string",
"null"
]
},
"function_count": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"id": {
"description": "Engine-assigned connection id (directory-specific).",
"type": "string"
},
"ip_address": {
"type": [
"string",
"null"
]
},
"isolation": {
"type": [
"string",
"null"
]
},
"name": {
"description": "Worker name as registered with the engine.",
"type": [
"string",
"null"
]
},
"os": {
"type": [
"string",
"null"
]
},
"runtime": {
"type": [
"string",
"null"
]
},
"status": {
"description": "Connection state (e.g. `\"connected\"`, `\"disconnected\"`).",
"type": "string"
},
"version": {
"description": "Worker version string from the worker's published manifest.",
"type": [
"string",
"null"
]
}
},
"required": [
"active_invocations",
"connected_at_ms",
"function_count",
"id",
"status"
],
"type": "object"
},
"WorkerFunctionEntry": {
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"function_id": {
"type": "string"
}
},
"required": [
"function_id"
],
"type": "object"
},
"WorkerRegisteredTriggerEntry": {
"properties": {
"function_id": {
"type": "string"
},
"id": {
"type": "string"
},
"trigger_type": {
"type": "string"
}
},
"required": [
"function_id",
"id",
"trigger_type"
],
"type": "object"
},
"WorkerTriggerTypeEntry": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
}
},
"required": [
"description",
"id"
],
"type": "object"
}
},
"properties": {
"functions": {
"items": {
"$ref": "#/definitions/WorkerFunctionEntry"
},
"type": "array"
},
"registered_triggers": {
"items": {
"$ref": "#/definitions/WorkerRegisteredTriggerEntry"
},
"type": "array"
},
"trigger_types": {
"items": {
"$ref": "#/definitions/WorkerTriggerTypeEntry"
},
"type": "array"
},
"worker": {
"allOf": [
{
"$ref": "#/definitions/Worker"
}
],
"description": "Same shape as `worker-list` rows (and `registry::worker-info.worker`)."
}
},
"required": [
"functions",
"registered_triggers",
"trigger_types",
"worker"
],
"title": "WorkerInfoOutput",
"type": "object"
}
},
{
"description": "Download skills + prompts into skills_folder. Pass {repo, skill, branch?} to clone a single skill folder from a GitHub repo (git clone --depth 1 --branch <branch>; branch defaults to \"main\"), or {worker, version?|tag?} to pull from the workers registry (defaults to tag=\"latest\" when neither version nor tag is given). Files in the destination namespace are overwritten file-by-file.",
"metadata": {
"tool": {
"label": "Download skills"
}
},
"name": "directory::skills::download",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"branch": {
"default": null,
"description": "Source A: branch to clone. Defaults to `\"main\"`. Pass `\"master\"` (or any other branch name) for repos whose default branch is not `main`.",
"type": [
"string",
"null"
]
},
"repo": {
"default": null,
"description": "Source A: GitHub repo URL. Pair with `skill`.",
"type": [
"string",
"null"
]
},
"skill": {
"default": null,
"description": "Source A: subfolder under `skills/` inside the repo. Doubles as the destination namespace inside `skills_folder`.",
"type": [
"string",
"null"
]
},
"tag": {
"default": null,
"description": "Source B: registry tag to pull (e.g. `latest`). Mutually exclusive with `version`. Defaults to `\"latest\"` when neither `version` nor `tag` is provided.",
"type": [
"string",
"null"
]
},
"version": {
"default": null,
"description": "Source B: explicit semver to pull. Mutually exclusive with `tag`.",
"type": [
"string",
"null"
]
},
"worker": {
"default": null,
"description": "Source B: workers registry name. Pair with exactly one of `version` / `tag`.",
"type": [
"string",
"null"
]
}
},
"title": "DownloadInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"namespace": {
"type": "string"
},
"prompts_written": {
"items": {
"type": "string"
},
"type": "array"
},
"skills_written": {
"items": {
"type": "string"
},
"type": "array"
},
"source": true
},
"required": [
"namespace",
"prompts_written",
"skills_written",
"source"
],
"title": "DownloadOutput",
"type": "object"
}
},
{
"description": "List workers from the public registry (api.workers.iii.dev) matching the free-text term `search`. Same row shape as directory::engine::workers::list so callers learn one envelope. Results are cached for `registry_cache_ttl_ms` (default 60s).",
"metadata": {},
"name": "directory::registry::workers::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "`directory::registry::workers::list` input. Mirrors [`crate::functions::directory::WorkerListInput.search`] so callers can switch between local and registry surfaces without re-learning the API. Adds `limit` for paging because the registry is paged.",
"properties": {
"limit": {
"default": null,
"description": "Max results to return. Defaults to 20; capped at 100.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"search": {
"default": null,
"description": "Free-text query forwarded to the registry as `?q=…`. Required — the public registry doesn't support an unscoped browse endpoint.",
"type": [
"string",
"null"
]
}
},
"title": "WorkerListInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"RegistryAuthor": {
"properties": {
"is_verified": {
"default": false,
"type": "boolean"
},
"name": {
"type": [
"string",
"null"
]
},
"profile_picture": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"Worker": {
"description": "Shared worker envelope used by both `directory::registry::workers::list` rows and the `worker` field of `directory::registry::workers::info`. Same field names as [`crate::functions::directory::Worker`] so callers learn one shape across local + registry surfaces.",
"properties": {
"author": {
"anyOf": [
{
"$ref": "#/definitions/RegistryAuthor"
},
{
"type": "null"
}
],
"default": null
},
"description": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
"repo": {
"type": [
"string",
"null"
]
},
"version": {
"description": "Latest published version (worker-list) or the resolved version (worker-info, when called with `version` / `tag`).",
"type": [
"string",
"null"
]
}
},
"required": [
"name"
],
"type": "object"
}
},
"properties": {
"workers": {
"items": {
"$ref": "#/definitions/Worker"
},
"type": "array"
}
},
"required": [
"workers"
],
"title": "WorkerListOutput",
"type": "object"
}
},
{
"description": "List every function registered with the engine. Filter by free-text search, namespace prefix, and/or worker name.",
"metadata": {},
"name": "directory::engine::functions::list",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"prefix": {
"default": null,
"description": "Exact prefix match on `function_id` (e.g. `\"mem::\"`).",
"type": [
"string",
"null"
]
},
"search": {
"default": null,
"description": "Case-insensitive substring match against `function_id` and `description`.",
"type": [
"string",
"null"
]
},
"worker": {
"default": null,
"description": "Exact worker-name match (the worker that registered the function).",
"type": [
"string",
"null"
]
}
},
"title": "FunctionListInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FunctionListEntry": {
"properties": {
"description": {
"type": [
"string",
"null"
]
},
"function_id": {
"type": "string"
},
"worker_name": {
"description": "Worker that registered it (resolved via `WorkerInfo.functions[]`), or the first `::` segment of `function_id` as fallback.",
"type": [
"string",
"null"
]
}
},
"required": [
"function_id"
],
"type": "object"
}
},
"properties": {
"functions": {
"items": {
"$ref": "#/definitions/FunctionListEntry"
},
"type": "array"
}
},
"required": [
"functions"
],
"title": "FunctionListOutput",
"type": "object"
}
},
{
"description": "Full detail for one trigger type: configuration schema, return schema, owning worker, and current instance count.",
"metadata": {},
"name": "directory::engine::triggers::info",
"request_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
],
"title": "TriggerInfoInput",
"type": "object"
},
"response_schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"configuration_schema": {
"description": "SDK 0.11.3 surfaces a single `trigger_request_format` that doubles as the per-instance configuration shape; expose it explicitly so callers don't have to know the alias."
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"instance_count": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"return_schema": true,
"worker_name": {
"type": [
"string",
"null"
]
}
},
"required": [
"description",
"id",
"instance_count"
],
"title": "TriggerInfoOutput",
"type": "object"
}
}
],
"triggers": [
{
"description": "Fires after every successful directory::skills::download that wrote at least one skill markdown file.",
"invocation_schema": {},
"metadata": {},
"name": "directory::skills::on-change",
"return_schema": {}
},
{
"description": "Fires after every successful directory::skills::download that wrote at least one prompt markdown file.",
"invocation_schema": {},
"metadata": {},
"name": "directory::prompts::on-change",
"return_schema": {}
}
]
}