Extending OpenFlows: Skills
OpenFlows is built around a small, stable core: a PocketFlow graph, typed Redis
SharedStore contracts, and a NEXUS reconcile loop. Extensions are added through three
primary mechanisms: skills, MCP servers, and custom model definitions. All three are
declared in orchestration/agent/registry.json v2, which is the single
extension point for agent behavior.
The extension philosophy is intentional: the orchestrator does not need to be rebuilt to
support a new capability. A skill is a directory with a SKILL.md manifest and
a handler. An MCP server is an external process exposing a standard tool interface. A model
is an alias and metadata entry. By keeping the registry as the source of truth, operators
can turn capabilities on and off without redeploying the controller.
registry.json v2 Structure
Version 2 of the registry adds top-level arrays for skills, MCPs, and models while
keeping the agent map from v1. The orchestrator refuses to load a v2 registry unless
schema_version is set to "2".
{
"schema_version": "2",
"workspace_provider": "coder",
"coder_module": "claude-code",
"ai_gateway": {
"primary": "coder",
"fallback": "litellm"
},
"agents": {
"nexus": { "provider": "anthropic", "model": "claude-sonnet-4-20250514", "active": true, "instances": 1 },
"forge": { "provider": "anthropic", "model": "claude-sonnet-4-20250514", "active": true, "instances": 2, "skills": ["terraform", "openapi"] },
"sentinel": { "provider": "openai", "model": "gpt-4.1", "active": true, "instances": 1 },
"vessel": { "provider": "openai", "model": "gpt-4o", "active": true, "instances": 1, "mcps": ["coder-mcp"] },
"lore": { "provider": "anthropic", "model": "claude-haiku-4-20250514", "active": true, "instances": 1 }
},
"skills": [
{ "name": "terraform", "path": "orchestration/plugin/skills/terraform", "entry": "terraform-skill" },
{ "name": "openapi", "path": "orchestration/plugin/skills/openapi", "entry": "openapi-skill" }
],
"mcps": [
{
"name": "coder-mcp",
"command": "npx",
"args": ["-y", "@coder/mcp-server"],
"env": { "CODER_URL": "https://coder.example.com" },
"timeout_ms": 30000
}
],
"models": [
{
"id": "claude-sonnet-4-20250514",
"provider": "anthropic",
"aliases": ["claude-sonnet", "sonnet"],
"context_window": 200000,
"cost_tier": "high"
}
]
}| Top-Level Field | Type | Description |
|---|---|---|
schema_version | string | "2" - must be present for the orchestrator to interpret v2 fields. |
workspace_provider | string | "coder" or "local". Coder is the only production runtime. |
coder_module | string | Default Coder Registry module for installing a CLI agent into workspaces. |
ai_gateway | object | Primary and fallback AI Gateway configuration. |
agents | object | Map of role names to agent definitions. |
skills | array | List of registered skill plugins. Each entry points to a directory and a registry entry. |
mcps | array | List of MCP servers available to all agents. Per-agent MCP lists override this. |
models | array | Optional registry of custom model definitions and aliases. |
| Agent Field | Type | Description |
|---|---|---|
provider | string | LLM provider slug known to the Coder AI Gateway. |
model | string | Model identifier or alias. |
coder_module | string | Per-agent CLI module override. |
active | bool | Whether the agent is enabled. |
instances | int | Number of parallel worker slots. |
mcps | array | Optional list of MCP servers available to this agent only. |
skills | array | Optional list of skill names this agent can invoke. |
max_retries | int | Override the default flow-level retry count for this agent. |
timeout_ms | int | Override the default LLM timeout for this agent. |
Schema version is mandatory
schema_version is missing, the orchestrator interprets the registry as v1
and ignores the skills, mcps, and models arrays. The
registry will still load, but none of your extensions will be available.
Adding Skills
A skill is a discrete capability an agent can invoke during a task. Examples include
generating Terraform plans, validating OpenAPI schemas, running a custom linter, or
fetching data from an internal API. Skills live in
orchestration/plugin/skills/{skill-name}/ and consist of a
SKILL.md manifest plus an executable handler.
The agent does not import the skill at compile time. Instead, the orchestrator reads the
skill manifest at runtime, registers the skill name, and makes it available to agents that
list it in their skills array. When an agent decides to use a skill, it emits
a structured skill invocation; the orchestrator spawns the handler in a fresh subprocess
(or a sandboxed Coder workspace for untrusted handlers) and returns the result to the
agent.
Skill Directory Layout
orchestration/plugin/skills/
└── terraform/
├── SKILL.md
├── terraform-skill # entry executable (can be a script or compiled binary)
└── fixtures/
└── example.tf
SKILL.md Manifest
SKILL.md is a machine-readable manifest at the top of the skill directory. It
describes the skill's contract so the orchestrator can validate invocations and present
the skill to the agent in its prompt context. The manifest must be valid YAML front matter
followed by Markdown documentation.
---
name: terraform
version: 1.0.0
description: Generate, validate, and plan Terraform changes for an AWS repository.
entry: terraform-skill
inputs:
- name: action
type: string
enum: [plan, validate, fmt]
required: true
- name: directory
type: string
default: "."
outputs:
- name: plan_path
type: string
- name: exit_code
type: integer
examples:
- input: { action: plan, directory: "infra" }
output: { plan_path: "infra/tfplan", exit_code: 0 }
---
# Terraform Skill
Use this skill when the ticket involves AWS infrastructure defined in Terraform. The skill
runs `terraform init`, `terraform validate`, and `terraform plan` in the target
directory and returns the plan output. Do not use this skill for ad-hoc shell commands.
| Field | Type | Description |
|---|---|---|
name | string | Unique skill name used in registry.json and agent prompts. |
description | string | What the skill does, when to use it, and what input it expects. |
entry | string | Path to the skill's executable or handler script relative to the skill directory. |
inputs | array | JSON Schema of accepted parameters. |
outputs | array | JSON Schema of returned values. |
examples | array | One or more example invocations showing expected input and output. |
Registering a Skill
After creating the skill directory and manifest, register the skill in
orchestration/agent/registry.json. Add it to the top-level skills
array and list it in the skills array of any agent that should be able to use
it.
{
"skills": [
{ "name": "terraform", "path": "orchestration/plugin/skills/terraform", "entry": "terraform-skill" }
],
"agents": {
"forge": { "skills": ["terraform"] },
"vessel": { "skills": ["terraform"] }
}
}Skills are hot-reloaded
registry.json on every NEXUS poll cycle. Adding a new
skill or changing an existing skill does not require a controller restart. However, the
handler binary must be executable and must be present in the skill directory before the
orchestrator attempts to invoke it.
Continue reading