{
  "markdown": "# Orca\n\n[![CI](https://github.com/jascal/orca-lang/actions/workflows/ci.yml/badge.svg)](https://github.com/jascal/orca-lang/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@orcalang/orca-lang)](https://www.npmjs.com/package/@orcalang/orca-lang)\n[![Node 20+](https://img.shields.io/badge/node-20%2B-blue)](https://nodejs.org/)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/jascal/orca-lang)\n\n**Orchestrated State Machine Language** — a two-layer architecture for reliable LLM code generation.\n\nThe core insight: LLMs generate flat transition tables reliably, but they struggle to guarantee topology correctness on their own. Orca separates *program structure* (state machine topology) from *computation* (action functions), then verifies the structure automatically before any code runs.\n\nMachines are written in plain Markdown — a format LLMs can read and write natively.\n\n---\n\n## What it looks like\n\n```markdown\n# machine PaymentProcessor\n\n## context\n\n| Field       | Type    | Default |\n|-------------|---------|---------|\n| order_id    | string  |         |\n| amount      | decimal |         |\n| retry_count | int     | 0       |\n\n## events\n\n- submit_payment\n- payment_authorized\n- payment_declined\n- retry_requested\n- settlement_confirmed\n\n## state idle [initial]\n> Waiting for a payment submission\n\n## state authorizing\n> Waiting for payment gateway response\n- on_entry: send_authorization_request\n\n## state declined\n> Payment was declined\n\n## state settled [final]\n> Payment fully settled\n\n## transitions\n\n| Source      | Event                | Guard      | Target      | Action           |\n|-------------|----------------------|------------|-------------|------------------|\n| idle        | submit_payment       |            | authorizing |                  |\n| authorizing | payment_authorized   |            | settled     |                  |\n| authorizing | payment_declined     |            | declined    |                  |\n| declined    | retry_requested      | can_retry  | authorizing | increment_retry  |\n| declined    | retry_requested      | !can_retry | settled     | record_failure   |\n\n## guards\n\n| Name      | Expression              |\n|-----------|-------------------------|\n| can_retry | `ctx.retry_count < 3`   |\n\n## actions\n\n| Name                       | Signature                                | Effect      |\n|----------------------------|------------------------------------------|-------------|\n| send_authorization_request | `(ctx) -> Context`                       | AuthRequest |\n| increment_retry            | `(ctx) -> Context`                       |             |\n| record_failure             | `(ctx) -> Context`                       |             |\n\n## effects\n\n| Name        | Input                              | Output                   |\n|-------------|------------------------------------|--------------------------|\n| AuthRequest | `{ order_id: string, amount: decimal }` | `{ token: string }`  |\n```\n\nThe verifier checks this before anything runs: reachability, deadlocks, guard determinism, orphan declarations, and effect consistency.\n\n---\n\n## Features\n\n**Language**\n- States with `[initial]` / `[final]` markers, descriptions, `on_entry` / `on_exit` actions\n- Transitions as a flat table — the format LLMs generate most reliably\n- Guard expressions: comparisons, boolean logic, null checks\n- Hierarchical (nested) states\n- Parallel regions with `all-final` / `any-final` / `custom` sync strategies\n- Timeouts: `timeout: 30s -> state_name`\n- Ignored events: `ignore: EVENT_NAME`\n- Machine invocation: one machine calling another, with input mapping and completion events\n- Multi-machine files: multiple machines in one `.orca.md` separated by `---`\n- `## effects` section: named I/O schemas for external side effects\n- **[Decision tables](DECISION_TABLES.md)**: co-located conditional logic without guard explosion — verified for completeness, consistency, and cross-machine reachability\n\n**Verifier**\n- Reachability: every state is reachable from the initial state\n- Deadlock detection: every non-final state has an outgoing transition\n- Completeness: every (state, event) pair is handled or explicitly ignored\n- Guard determinism: multi-transition guards are mutually exclusive\n- Property checking: bounded model checking with BFS — `reachable`, `unreachable`, `passes_through`, `live`, `responds`, `invariant`\n- Cross-machine: cycle detection, child reachability to final state, input mapping validation\n- Effect consistency: `ORPHAN_EFFECT` (declared but unused) and `UNDECLARED_EFFECT` (referenced but not declared)\n- Decision table checks: completeness, consistency, redundancy, coverage gap, dead guards, DT-constrained reachability — see [DECISION_TABLES.md](DECISION_TABLES.md)\n\n**Compilers**\n- XState v5 `createMachine()` config\n- Mermaid `stateDiagram-v2`\n\n**Runtimes** (standalone — no XState dependency)\n- TypeScript (`@orcalang/orca-runtime-ts`)\n- Python (`orca-runtime-python`)\n- Go (`orca-runtime-go`)\n\nAll three runtimes share the same feature set: guard evaluation, action registration, event bus (pub/sub + request/response), timeouts, parallel regions, snapshot/restore, machine invocation, persistence, and structured logging.\n\n---\n\n## Monorepo structure\n\n```\npackages/\n  orca-lang/       Core: parser, verifier, XState/Mermaid compiler, CLI\n  runtime-ts/      TypeScript runtime\n  runtime-python/  Python async runtime\n  runtime-go/      Go runtime\n  demo-ts/         Text adventure game (uses runtime-ts)\n  demo-python/     Agent framework scenarios (uses runtime-python)\n  demo-go/         Ride-hailing coordinator — 5 machines (uses runtime-go)\n  demo-nanolab/    nanoGPT training orchestrator — 5 machines (uses runtime-python)\n  mcp-server/      MCP server exposing Orca tools to Claude and other agents\n```\n\n---\n\n## Setup\n\n```bash\n# TypeScript packages\npnpm install\npnpm build\n\n# Python packages (runtime + demos, requires Python >= 3.11)\npnpm run setup:python\n\n# Go packages\npnpm run setup:go\npnpm run build:demo-go\n```\n\n---\n\n## CLI\n\n```bash\ncd packages/orca-lang\n\n# Verify a machine\nnpx tsx src/index.ts verify examples/payment-processor.orca.md\n\n# Compile to XState\nnpx tsx src/index.ts compile xstate examples/payment-processor.orca.md\n\n# Compile to Mermaid\nnpx tsx src/index.ts compile mermaid examples/text-adventure.orca.md\n\n# Convert legacy .orca to .orca.md\n# npx tsx src/index.ts convert <path-to-legacy.orca>\n```\n\n---\n\n## Language features\n\n### Parallel regions\n\n```markdown\n## state processing [parallel]\n> Payment and notification run concurrently\n- on_done: -> completed\n\n### region payment_flow\n\n#### state charging [initial]\n#### state paid [final]\n\n### region notification_flow\n\n#### state sending_email [initial]\n#### state notified [final]\n```\n\nThe machine transitions to `completed` when both regions reach their final state (`all-final` sync, the default).\n\n### Machine invocation\n\n```markdown\n---\n\n# machine OrderCoordinator\n\n## state processing_payment\n- invoke: PaymentProcessor\n- on_done: payment_confirmed\n- on_error: payment_failed\n\n---\n\n# machine PaymentProcessor\n\n## state idle [initial]\n## state settled [final]\n...\n```\n\nThe parent owns the child's lifecycle: starts it on entry, stops it on exit. The child's context is isolated from the parent's.\n\n### Timeouts\n\n```markdown\n## state waiting_for_response\n> LLM call in progress\n- timeout: 30s -> timed_out\n```\n\n### Snapshot and resume\n\nAll runtimes support saving and restoring machine state:\n\n```typescript\n// Save\nconst snap = machine.snapshot();\npersistence.save('run-id', snap);\n\n// Resume later (without re-running on_entry)\nconst snap = persistence.load('run-id');\nawait machine.resume(snap);\n```\n\n### Structured logging\n\n```typescript\nimport { MultiSink, FileSink, ConsoleSink, makeEntry } from '@orcalang/orca-runtime-ts';\n\nconst sink = new MultiSink(new ConsoleSink(), new FileSink('audit.jsonl'));\n\nconst m = new OrcaMachine(def, bus, {\n  onTransition: (oldState, newState) => {\n    sink.write(makeEntry({ runId, machine: def.name, from: oldState.toString(), to: newState.toString(), ... }));\n  }\n});\n```\n\n---\n\n## Using a runtime\n\n### TypeScript\n\n```typescript\nimport { parseOrcaAuto, OrcaMachine, EventBus } from '@orcalang/orca-runtime-ts';\n\nconst def = parseOrcaAuto(source);\nconst bus = new EventBus();\nconst machine = new OrcaMachine(def, bus);\n\nmachine.registerAction('send_authorization_request', (ctx, event) => {\n  return { ...ctx, payment_token: 'tok_123' };\n});\n\nmachine.start();\nmachine.send({ type: 'submit_payment', payload: { order_id: 'ord_1', amount: 99.99 } });\n```\n\n### Python\n\n```python\nfrom orca_runtime_python import parse_orca_auto, OrcaMachine, EventBus\n\ndef_ = parse_orca_auto(source)\nbus = EventBus()\nmachine = OrcaMachine(def_, bus)\n\n@machine.register_action('send_authorization_request')\nasync def send_auth(ctx, event):\n    return {**ctx, 'payment_token': 'tok_123'}\n\nawait machine.start()\nawait machine.send({'type': 'submit_payment', 'payload': {'order_id': 'ord_1', 'amount': 99.99}})\n```\n\n### Go\n\n```go\nimport \"orca-runtime-go/orca_runtime_go\"\n\ndef, _ := orca_runtime_go.ParseOrcaAuto(source)\nbus := orca_runtime_go.NewEventBus()\nmachine := orca_runtime_go.NewOrcaMachine(def, bus, nil, nil)\n\nmachine.RegisterAction(\"send_authorization_request\", func(ctx map[string]any, event orca_runtime_go.Event) map[string]any {\n    ctx[\"payment_token\"] = \"tok_123\"\n    return ctx\n})\n\nmachine.Start()\nmachine.Send(orca_runtime_go.Event{Type: \"submit_payment\"})\n```\n\n---\n\n## Running the demos\n\n```bash\n# Text adventure (TypeScript) — interactive CLI\ncd packages/demo-ts && pnpm run cli\n\n# Smoke test (non-interactive)\npnpm test:demo-ts\n\n# Agent framework (Python)\npnpm run test:demo-python\n\n# Ride-hailing coordinator (Go) — runs FareSettlement end-to-end\npnpm run test:demo-go\n# With snapshot/resume:\ncd packages/demo-go && ./trip --resume\n\n# nanoGPT training orchestrator (Python, no torch required for tests)\npnpm run test:demo-nanolab\n\n# nanoGPT training with PyTorch (GPU support)\n# Install torch with GPU support, then run the full pipeline\n.venv/bin/pip install torch torchvision torchaudio numpy requests\npnpm run run:demo-nanolab\n```\n\n---\n\n## Running tests\n\n```bash\n# All TypeScript packages\npnpm test\n\n# Core language only\npnpm test:lang\n\n# Go runtime\ncd packages/runtime-go && go test ./...\n\n# Python runtime\ncd packages/orca-lang && ../../.venv/bin/python -m pytest ../runtime-python/tests/ -v\n\n# nanolab tests\npnpm run test:demo-nanolab\n```\n\n**Test counts:** 233 orca-lang · 63 runtime-ts · 87 runtime-python · 16 runtime-go · 47 demo-nanolab\n\n---\n\n## Examples\n\nAll in `packages/orca-lang/examples/`:\n\n| File | Description |\n|------|-------------|\n| `simple-toggle.orca.md` | Minimal 2-state machine |\n| `payment-processor.orca.md` | Guards, retries, effects |\n| `text-adventure.orca.md` | Multi-state game engine |\n| `hierarchical-game.orca.md` | Nested compound states |\n| `parallel-order.orca.md` | Parallel regions with sync |\n| `payment-with-properties.orca.md` | Bounded model checking properties |\n| `key-exchange.orca.md` | Multi-machine: client/server key exchange protocol |\n| `invocation-order.orca.md` | Multi-machine: order processing with child invocations |\n| `saas-auth.orca.md` | SaaS authentication and registration flow |\n| `health-check.orca.md` | Health check machine used by the dogfood runner |\n| `simple-discount.orca.md` | Minimal standalone decision table |\n| `payment-routing.orca.md` | Payment gateway router decision table |\n| `shipping-rules.orca.md` | Shipping cost calculator decision table |\n| `payment-with-routing.orca.md` | Combined machine + decision table |\n\nSee [DECISION_TABLES.md](DECISION_TABLES.md) for a full guide to decision tables.\n\n---\n\n## Skills & MCP setup\n\nOrca ships six Claude Code skills backed by the `@orcalang/orca-mcp-server` MCP server. The skills call MCP tools directly — no shell or file access needed.\n\n| Skill | Trigger | What it does |\n|-------|---------|--------------|\n| `/orca-generate` | `<spec>` | Generate a verified machine from a natural language spec |\n| `/orca-generate-multi` | `<spec>` | Generate a coordinated multi-machine system |\n| `/orca-verify` | `[file]` | Verify a machine for errors and warnings |\n| `/orca-refine` | `[file]` | Auto-fix verification errors using an LLM |\n| `/orca-compile` | `[xstate\\|mermaid] [file]` | Compile to XState TypeScript or Mermaid |\n| `/orca-actions` | `[typescript\\|python\\|go] [file]` | Generate action scaffold stubs |\n\nSkills that use an LLM (`/orca-generate`, `/orca-generate-multi`, `/orca-refine`, and optionally `/orca-actions --use-llm`) call the MCP server, which calls your configured LLM provider. Skills that are purely structural (`/orca-verify`, `/orca-compile`, plain `/orca-actions`) never make LLM calls.\n\n### MCP server environment variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `ORCA_API_KEY` | Yes | API key for your LLM provider |\n| `ORCA_PROVIDER` | Yes | `anthropic`, `openai`, `ollama`, or `grok` |\n| `ORCA_BASE_URL` | No | Override the provider's default base URL (for OpenAI-compatible APIs) |\n| `ORCA_MODEL` | No | Model name (defaults to `claude-sonnet-4-6` for Anthropic) |\n\nUse `ORCA_PROVIDER=openai` with `ORCA_BASE_URL` for any OpenAI-compatible provider (MiniMax, Together, local vLLM, etc.).\n\n---\n\n### Claude Desktop\n\nAdd the `orca` server to your Claude Desktop config file:\n\n- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`\n- **Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"orca\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@orcalang/orca-mcp-server\"],\n      \"env\": {\n        \"ORCA_API_KEY\": \"<your-api-key>\",\n        \"ORCA_PROVIDER\": \"anthropic\"\n      }\n    }\n  }\n}\n```\n\nFor an OpenAI-compatible provider (e.g. MiniMax):\n\n```json\n{\n  \"mcpServers\": {\n    \"orca\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@orcalang/orca-mcp-server\"],\n      \"env\": {\n        \"ORCA_API_KEY\": \"<your-api-key>\",\n        \"ORCA_PROVIDER\": \"openai\",\n        \"ORCA_BASE_URL\": \"https://api.minimaxi.chat/v1\",\n        \"ORCA_MODEL\": \"MiniMax-M3\"\n      }\n    }\n  }\n}\n```\n\nRestart Claude Desktop after editing. Skills in `.claude/skills/` are discovered automatically when you open this repo.\n\n> **Node.js version** — Claude Desktop uses its own bundled Node.js, which may be older than the Node 18+ required by this package (ESM). If the server fails to start, add a `PATH` entry to `env` that puts your system Node's `bin` directory first — this is the most reliable way to ensure the right `npx` is found:\n> ```json\n> \"env\": {\n>   \"PATH\": \"/usr/local/bin:/usr/bin:/bin\",\n>   \"ORCA_API_KEY\": \"...\"\n> }\n> ```\n> Run `dirname $(which npx)` to find the correct path. On nvm it will be something like `~/.nvm/versions/node/v22.x.x/bin`.\n\n---\n\n### Claude Code\n\nClaude Code reads MCP server config from `.mcp.json` at the project root. This file is gitignored because it contains credentials — each developer creates their own.\n\n**Option A — use the published package** (same as Desktop, no rebuild needed):\n\n```json\n{\n  \"mcpServers\": {\n    \"orca\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@orcalang/orca-mcp-server\"],\n      \"type\": \"stdio\",\n      \"env\": {\n        \"ORCA_API_KEY\": \"<your-api-key>\",\n        \"ORCA_PROVIDER\": \"anthropic\"\n      }\n    }\n  }\n}\n```\n\n**Option B — use the local build** (recommended for development — changes take effect after rebuild):\n\n```json\n{\n  \"mcpServers\": {\n    \"orca\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/orca-lang/packages/mcp-server/dist/server.js\"],\n      \"type\": \"stdio\",\n      \"env\": {\n        \"ORCA_API_KEY\": \"<your-api-key>\",\n        \"ORCA_PROVIDER\": \"anthropic\"\n      }\n    }\n  }\n}\n```\n\nBuild (or rebuild after changes):\n\n```bash\npnpm --filter @orcalang/orca-mcp-server build\n# or from the package directory:\ncd packages/mcp-server && npx tsc\n```\n\nCreate `.mcp.json` at the project root (it is already in `.gitignore`), then restart Claude Code. Skills are auto-discovered from `.claude/skills/` — no additional configuration needed.\n\n> **Node.js version** — Claude Code may use an older Node.js than the Node 18+ required by this package (ESM). If the server fails to start, add a `PATH` entry to `env` that puts your system Node's `bin` directory first:\n> ```json\n> \"env\": {\n>   \"PATH\": \"/usr/local/bin:/usr/bin:/bin\",\n>   \"ORCA_API_KEY\": \"...\"\n> }\n> ```\n> Run `dirname $(which npx)` to find the correct path. On nvm it will be something like `~/.nvm/versions/node/v22.x.x/bin`.\n\n---\n\n## Background\n\n### Why \"Orca\"?\n\nThe name comes from **Orc**hestrated (state machine language), but the whale was in mind too: orcas are highly coordinated, hunt in structured pods, and divide roles precisely — which maps well to a multi-machine system where a coordinator directs child machines through well-defined protocols.\n\n**Disambiguation:** There is another project called [Orca](https://100r.co/site/orca.html) — a visual live-coding environment for sequencing MIDI and audio events, built by Hundred Rabbits. It's excellent, completely unrelated, and worth knowing about if you work in music or creative coding. This project is a different thing entirely: a state machine language for software orchestration.\n\n### Does this sidestep the halting problem?\n\nYes, deliberately — and that's the point.\n\nThe halting problem says you cannot decide in general whether an arbitrary program will terminate. That result applies to Turing-complete computations. Finite state machines are not Turing-complete: they have a finite, explicitly enumerated set of states and transitions declared upfront, with no unbounded loops or dynamic control flow in the topology itself. Reachability and deadlock analysis on an FSM is just graph traversal — it always terminates in O(states + transitions).\n\nOrca's verifier exploits this by only verifying the *topology* layer — the state machine structure — where decidability is guaranteed. It does not attempt to verify the *computation* layer — the action functions you write inside each state. Those functions can be as complex as you like, and Orca makes no claims about them.\n\nThe practical consequence: the verifier can give you hard guarantees about your program's control flow (every state is reachable, no deadlocks, every event is handled, guards are mutually exclusive) without requiring your business logic to be formally specified. The two-layer separation is what makes this tractable. You get real structural correctness, scoped to the part of the program that can actually be checked.\n",
  "bytes": 18586,
  "sha": "3a4b52c24162e84c18eb9a12e0fb1f853a36fdb4d73510f26f2b7ae27055bed6",
  "repo_slug": "jascal/orca-lang",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_jascal_orca_mcp_server_720b4d0f/readme"
}