High Risk:This skill has significant security concerns. Review the findings below before installing.

opcode

Caution·Scanned 2/18/2026

High-risk skill. Opcode is a workflow orchestration engine that exposes shell.exec, filesystem actions (fs.read/fs.write), and HTTP actions (http.request) and supports a secret vault (OPCODE_VAULT_KEY). These features enable arbitrary command execution, file I/O, network requests, and secret usage.

from clawhub.ai·v1.0·43.6 KB·0 installs
Scanned from 1.0.0 at 32aee7c · Transparency log ↗
$ vett add clawhub.ai/rendis/opcodeReview security findings before installing

OPCODE

Workflow orchestration engine for AI agents. Workflows are JSON-defined DAGs executed level-by-level with automatic parallelism. Communication happens via 5 MCP tools over stdio (JSON-RPC).

Token economy: define a template once, execute it unlimited times for free (no re-reasoning). Reasoning nodes store decisions as events and never replay them.

Prerequisites

  • Go 1.25+ (required)
  • CGO enabled (CGO_ENABLED=1) — required by embedded libSQL (go-libsql)
  • C compilergcc or clang for CGO compilation

Installation

Build from source

go build -o opcode ./cmd/opcode/

As a Go module dependency

go get github.com/rendis/opcode@latest

Running

OPCODE runs as a stdio MCP server (JSON-RPC over stdin/stdout). It is not a standalone daemon — your MCP client starts it as a subprocess.

Environment Variables

VariableDefaultDescription
OPCODE_DB_PATHopcode.dbPath to embedded libSQL database file
OPCODE_VAULT_KEY(empty)Passphrase for secret vault. If unset, ${{secrets.*}} interpolation is disabled
OPCODE_POOL_SIZE10Worker pool size for parallel step execution
OPCODE_LOG_LEVELinfoLog level: debug, info, warn, error

MCP Client Configuration

Add opcode as an MCP server in your client config. Examples:

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "opcode": {
      "command": "/path/to/opcode",
      "env": {
        "OPCODE_DB_PATH": "/path/to/opcode.db",
        "OPCODE_VAULT_KEY": "your-secret-passphrase"
      }
    }
  }
}

Claude Code (.mcp.json in project root):

{
  "mcpServers": {
    "opcode": {
      "command": "/path/to/opcode",
      "env": {
        "OPCODE_DB_PATH": "/path/to/opcode.db",
        "OPCODE_VAULT_KEY": "your-secret-passphrase"
      }
    }
  }
}

The MCP client launches the binary, communicates via stdio, and exposes the 5 tools below to the agent.

Startup Sequence

  1. Opens/creates libSQL database at OPCODE_DB_PATH, runs migrations
  2. Initializes secret vault (if OPCODE_VAULT_KEY set)
  3. Registers 24 built-in actions
  4. Starts cron scheduler (recovers missed jobs)
  5. Begins listening for MCP JSON-RPC on stdin/stdout
  6. Shuts down gracefully on SIGTERM/SIGINT (10s timeout)

MCP Tools

opcode.define

Register a reusable workflow template. Version auto-increments (v1, v2, v3...).

ParamTypeRequiredDescription
namestringyesTemplate name
definitionobjectyesWorkflow definition (see below)
agent_idstringyesDefining agent ID
descriptionstringnoTemplate description
input_schemaobjectnoJSON Schema for input validation
output_schemaobjectnoJSON Schema for output validation
triggersobjectnoTrigger configuration

Returns: { "name": "...", "version": "v1" }

opcode.run

Execute a workflow from a registered template.

ParamTypeRequiredDescription
template_namestringyesTemplate to execute
agent_idstringyesInitiating agent ID
versionstringnoVersion (default: latest)
paramsobjectnoInput parameters

Returns: ExecutionResult with workflow_id, status, output, per-step results.

opcode.status

Get workflow execution status.

ParamTypeRequiredDescription
workflow_idstringyesWorkflow to query

Returns: { "status": "...", "steps": {...}, "output": {...} }

Workflow statuses: pending, active, suspended, completed, failed, cancelled.

opcode.signal

Send a signal to a suspended workflow.

ParamTypeRequiredDescription
workflow_idstringyesTarget workflow
signal_typeenumyesdecision / data / cancel / retry / skip
payloadobjectyesSignal payload
step_idstringnoTarget step (required for decision signals)
agent_idstringnoSignaling agent
reasoningstringnoAgent's reasoning

For decisions: payload: { "choice": "<option_id>" }.

Returns: { "ok": true, "workflow_id": "...", "signal_type": "..." }

opcode.query

Query workflows, events, or templates.

ParamTypeRequiredDescription
resourceenumyesworkflows / events / templates
filterobjectnoFilter criteria

Filter fields by resource:

ResourceFields
workflowsstatus, agent_id, since (RFC3339), limit
eventsworkflow_id, step_id, event_type, since, limit
templatesname, agent_id, limit

Note: event queries require either event_type or workflow_id in filter.

Workflow Definition

{
  "steps": [ ... ],
  "inputs": { "key": "value or ${{secrets.KEY}}" },
  "timeout": "5m",
  "on_timeout": "fail | suspend | cancel",
  "on_complete": { /* step definition */ },
  "on_error": { /* step definition */ },
  "metadata": {}
}

Step Definition

{
  "id": "step-id",
  "type": "action | condition | loop | parallel | wait | reasoning",
  "action": "http.get",
  "params": { ... },
  "depends_on": ["other-step"],
  "condition": "CEL guard expression",
  "timeout": "30s",
  "retry": { "max": 3, "backoff": "exponential", "delay": "1s", "max_delay": "30s" },
  "on_error": { "strategy": "ignore | fail_workflow | fallback_step | retry", "fallback_step": "id" },
  "config": { /* type-specific */ }
}

type defaults to action. The config field varies by type. See workflow-schema.md for all config blocks.

Step Types

action (default)

Executes a registered action. Set action to the action name, params for input.

condition

Evaluates a CEL expression and branches. Config: expression, branches (map value -> steps), default.

{ "expression": "inputs.env", "branches": { "prod": [...], "staging": [...] }, "default": [...] }

loop

Iterates over a collection or condition. Config: mode (for_each/while/until), over, condition, body, max_iter.

{ "mode": "for_each", "over": "[\"a\",\"b\",\"c\"]", "body": [...], "max_iter": 100 }

Loop variables: ${{loop.item}}, ${{loop.index}}.

parallel

Executes branches concurrently. Config: branches (array of step arrays), mode (all/race).

{ "mode": "all", "branches": [ [{...}], [{...}] ] }

wait

Delays execution. Config: duration or signal.

{ "duration": "5s" }

reasoning

Suspends workflow for agent decision. Config: prompt_context, options, timeout, fallback, data_inject, target_agent.

{
  "prompt_context": "Review data and decide",
  "options": [ {"id": "approve", "description": "Proceed"}, {"id": "reject", "description": "Stop"} ],
  "timeout": "1h",
  "fallback": "reject"
}

Empty options array = free-form (any choice accepted).

Variable Interpolation

Syntax: ${{namespace.path}}

NamespaceExampleDescription
steps${{steps.fetch.output.body}}Previous step outputs
inputs${{inputs.api_key}}Workflow input params
workflow${{workflow.run_id}}Workflow metadata
context${{context.intent}}Workflow context
secrets${{secrets.DB_PASS}}Encrypted vault secrets
loop${{loop.item}}, ${{loop.index}}Loop iteration vars

Two-pass resolution: non-secrets first, then secrets via AES-256-GCM vault.

CEL gotcha: loop is a reserved word in CEL. Use iter.item / iter.index in CEL expressions. The ${{loop.item}} interpolation syntax is unaffected.

See expressions.md for CEL, GoJQ, Expr engine details.

Built-in Actions

CategoryActions
HTTPhttp.request, http.get, http.post
Filesystemfs.read, fs.write, fs.append, fs.delete, fs.list, fs.stat, fs.copy, fs.move
Shellshell.exec
Cryptocrypto.hash, crypto.hmac, crypto.uuid
Assertassert.equals, assert.contains, assert.matches, assert.schema
Workflowworkflow.run, workflow.emit, workflow.context, workflow.fail, workflow.log

See actions.md for full parameter specs.

Scripting with shell.exec

shell.exec supports any language (Bash, Python, Node, Go, etc.). Scripts receive input via stdin and produce output via stdout. JSON stdout is auto-parsed — access fields directly with ${{steps.cmd.output.stdout.field}}.

LanguageCommandArgsBoilerplate
Bashbash["script.sh"]set -euo pipefail; input=$(cat -)
Pythonpython3["script.py"]json.load(sys.stdin)json.dump(result, sys.stdout)
Nodenode["script.js"]Read stdin stream → JSON.parseJSON.stringify
Gogo["run","script.go"]json.NewDecoder(os.Stdin)json.NewEncoder(os.Stdout)

Convention: stdin=JSON, stdout=JSON, stderr=errors, non-zero exit=failure. Use stdout_raw for unprocessed text.

See patterns.md for full templates.

Reasoning Node Lifecycle

  1. Workflow reaches a reasoning step
  2. Executor creates PendingDecision, emits decision_requested event
  3. Workflow status becomes suspended
  4. Agent calls opcode.status to see pending decision with context and options
  5. Agent resolves via opcode.signal:
    { "workflow_id": "...", "signal_type": "decision", "step_id": "reason-step", "payload": { "choice": "approve" } }
    
  6. Workflow auto-resumes after signal
  7. If timeout expires: fallback option auto-selected, or step fails if no fallback

Common Patterns

See patterns.md for complete JSON examples:

  • Linear pipeline -- steps chained via depends_on
  • Conditional branching -- CEL expression routes to branches
  • For-each loop -- iterate over a collection
  • Parallel fan-out -- concurrent branches with all/race mode
  • Human-in-the-loop -- reasoning node for agent approval
  • Error recovery -- retry + fallback_step
  • Sub-workflow -- workflow.run calls child templates
  • MCP lifecycle -- define -> run -> status -> signal -> status

Error Handling

StrategyBehavior
ignoreStep skipped, workflow continues
fail_workflowEntire workflow fails
fallback_stepExecute fallback step
retryDefer to retry policy

Backoff: none, linear, exponential, constant. Non-retryable errors (validation, permission, assertion) are never retried.

See error-handling.md for circuit breakers, timeout interactions, error codes.