Cori
Reference

Activity kinds reference

Full API templates and rules for all five activity kinds — cli, mcp_tool, code, llm, and builtin.

cli

Runs a shell command or external binary.

Template:

steps/NN_name.ts
import { step } from '@cori-do/sdk';
import { z } from 'zod';

export const input = z.object({
  // define step inputs
});

export const output = z.object({
  // define step outputs
});

export default step.cli({
  description: 'What this step does',
  command: ({ input }) => `your-binary --flag ${input.some_value}`,
  parse_output: (stdout) => ({
    // parse stdout into output shape
  }),
});

Rules:

  • Declare the binary in the manifest's tools_required. Validated at cori check time.
  • If the binary is not found on PATH, run cori status to check the worker's environment.
  • Default retry: 1 attempt (transient failures are not automatically retried).
  • Default per-attempt timeout: 60 seconds.

mcp_tool

Calls a tool on an MCP server.

Template:

steps/NN_name.ts
import { step } from '@cori-do/sdk';
import { z } from 'zod';

export const input = z.object({
  // define step inputs
});

export const output = z.object({
  // define step outputs
});

export default step.mcp_tool({
  description: 'What this step does',
  server: 'server-name',   // must match mcp_servers in manifest
  tool: 'tool_name',
  args: ({ input }) => ({
    // tool arguments
  }),
  parse_output: (result) => ({
    // parse MCP result into output shape
  }),
});

Rules:

  • Declare the MCP server in the manifest's mcp_servers. Validated at cori check time.
  • Default retry: 1 attempt.
  • Default per-attempt timeout: 60 seconds.

code

Pure TypeScript computation with no I/O.

Template:

steps/NN_name.ts
import { step } from '@cori-do/sdk';
import { z } from 'zod';

export const input = z.object({
  // define step inputs
});

export const output = z.object({
  // define step outputs
});

export default step.code({
  description: 'What this step does',
  run: ({ input }) => {
    // pure computation — no network, no filesystem, no shell
    return {
      // output shape
    };
  },
});

Rules:

Never put external I/O in a code step. No network calls, no filesystem reads, no shell commands. Code steps run in the Temporal workflow execution context and must be deterministic pure functions.

  • Default retry: 3 attempts.
  • Default per-attempt timeout: 30 seconds.

What a code step may import. Steps run in a Deno subprocess launched with a fixed import map containing exactly two entries — @cori-do/sdk and zod — resolved against that map, never against any node_modules.

  • Default: import only @cori-do/sdk, zod, and JS/Web/Deno globals that need no import (JSON, Intl, Date, Math, Map/Set, structuredClone, TextEncoder, crypto.subtle, URL, …). Most pure transforms need nothing more.
  • node:* imports are forbiddencori check rejects them with a hard error, and the sandbox lacks the permissions those modules want.
  • Need a third-party library? Use an explicit registry specifier, not a bare name: npm:<pkg>@<ver>, jsr:<scope>/<pkg>, or https://esm.sh/<pkg>@<ver>. The package must be pure JS/Wasm — native addons or anything touching node:fs/net/child_process fails under the sandbox. A bare import _ from 'lodash' does not work; it must be import _ from 'npm:lodash@4'. Testing with deno test catches a bad bare import before runtime, because tests resolve against the same import map.

llm

Calls a language model with a prompt and parses the typed output.

Template:

steps/NN_name.ts
import { step } from '@cori-do/sdk';
import { z } from 'zod';

export const input = z.object({
  // define step inputs
});

export const output = z.object({
  // define step outputs — required for llm steps
});

export default step.llm({
  description: 'What this step does',
  model: 'gpt-4o-mini',
  prompt: ({ input }) => `Your prompt here. Data: ${JSON.stringify(input)}`,
  output_schema: output,
  // optional:
  system: 'You are a helpful assistant.',
});

Rules:

  • output_schema is required. LLM steps must declare a typed output.
  • Use llm only for content that varies at runtime (translation, classification, extraction).
  • Provider credentials are configured at the worker level, not in the step file.
  • Default retry: 3 attempts.
  • Default per-attempt timeout: 300 seconds.

builtin — deferred in v1

builtin steps are accepted by the compiler but the v1 runtime does not execute them. The constructors below are documented for reference only. Do not use them in workflows you intend to run today.

The builtin constructors provide workflow-level control flow:

ConstructorDescription
step.builtin.map(...)Fan out over a list, run a step per item
step.builtin.for_each(...)Iterate over items sequentially
step.builtin.branch(...)Conditional execution
step.builtin.parallel(...)Run multiple steps concurrently
step.builtin.wait(...)Wait for an external event or signal

These will be executable in a future version of Cori.

On this page