zymi-core
Compile what your agent figured out into pipelines that run without it — declarative, event-sourced, approval-gated, callable from any MCP host.
Pronounced zoomi — like dog zoomies.
Why zymi-core?
You ask your coding agent to add a VPN user, deploy a service, or clean up a server. It figures it out — after some trial and error. A week later you ask again, and it figures it out again, slightly differently. Then the agent is rate-limited, offline, or simply not there, and nobody remembers the steps.
zymi is for the moment you notice that. The procedure the agent converged on gets compiled into a YAML pipeline — most steps are plain deterministic tool calls, an LLM appears only where judgment is actually needed — and from then on:
- It runs without the agent.
zymi run add_vpn_userfrom any terminal. Tool-only pipelines need no model and no API key at all, and missing inputs are asked interactively. - Your agent still uses it — as one MCP tool, via
zymi mcp serve, instead of re-deriving the procedure every time. - Dangerous steps wait for a human. Steps emit intentions (shell, file write, HTTP) that pass policy, contracts and optional approval before anything happens. Over MCP the approval is a native approve/deny form in the calling agent's UI.
- Every run is on the record. Each state change is an immutable, hash-chained event: replay it, fork-resume it from any step, browse it in a TUI, or let the agent read its own run trace to explain a failure.
zymi is deliberately not an autonomous agent, an IDE plugin or a chat UI. It is the governed, reproducible layer underneath them: the place where the behaviour you want to keep stops being emergent.
Two minutes: a personal pipeline library
uv tool install zymi-core # one-time; puts `zymi` on PATH globally
zymi init --home # your library at ~/.zymi
zymi ls # from any directory
zymi run hello # asks for its input, runs, no LLM involved
Don't have
uv?curl -LsSf https://astral.sh/uv/install.sh | sh(macOS/Linux) orirm https://astral.sh/uv/install.ps1 | iex(Windows).
~/.zymi is an ordinary zymi project that every command falls back to when you're not inside another one (ADR-0044). Add your own pipeline — say, a site check:
# ~/.zymi/tools/http_status.yml
name: http_status
description: "HTTP status code of a URL"
parameters:
type: object
properties:
url: { type: string }
required: [url]
implementation:
kind: shell
command_template: "curl -sS -o /dev/null -w '%{http_code}' ${args.url}"
# ~/.zymi/pipelines/site_check.yml
name: site_check
description: "Is the site up?"
inputs:
- name: url
required: true
description: "Full URL, e.g. https://example.com"
steps:
- id: status
tool: http_status
args: { url: "${inputs.url}" }
output:
step: status
Allow the command in ~/.zymi/project.yml (policy.allow: ["curl *"] — anything unlisted asks for approval first), then zymi run site_check. The run, its arguments and its output are now in ~/.zymi/.zymi/events.db; zymi observe shows them.
Hand it to your agent. Point any MCP host at the library and every pipeline with an expose.mcp: block becomes a tool:
{ "command": "zymi", "args": ["mcp", "serve", "--dir", "/Users/you/.zymi"] }
Add a model only where it earns its place. Declare endpoints once per machine in ~/.zymi/providers.yml and reference them by name from any project — llm: neuraldeep, or llm: { use: neuraldeep, model: other }. Keys live in ~/.zymi/.env. A provider that can't be resolved only disables agent steps; the tool-only pipelines keep working.
Full walkthrough in docs/getting-started.md.
What's in the box
Pipelines — DAGs of agent, tool and ask steps
A pipeline is a list of steps with depends_on: edges; independent steps run in parallel. Each step is one of:
- a deterministic tool step (ADR-0024) — direct dispatch with templated args, no LLM hop;
- an agent step — an LLM ReAct loop with a tool allowlist;
- an ask step (ADR-0042) — the run parks and asks whoever called it (a human at the terminal under
zymi run, the connected agent underzymi mcp serve), then resumes with the answer. No second model to configure.
steps:
- id: recon # deterministic — no LLM
tool: disk_report
args: { host: "${inputs.host}" }
- id: analyse # LLM, only for the judgment call
agent: sysadmin
task: "What is eating the disk? ${steps.recon.output}"
depends_on: [recon]
- id: confirm # the caller answers
ask: "Clean up as proposed?\n${steps.analyse.output}"
depends_on: [analyse]
Branches (ADR-0028) — a step can carry when:; skipped branches cascade to descendants and land in the trace as StepSkipped events. One pipeline can serve several actions:
- id: add_client
tool: vpn_add_client
args: { email: "${inputs.email}" }
depends_on: [route]
when: "${inputs.action} == 'add'"
Schema, examples, gotchas → docs/pipelines.md.
Tools — four kinds, one catalogue
- Declarative shell / HTTP in
tools/<name>.yml— no code. - Python
@toolintools/<name>.py— sync or async, signature → JSON Schema, auto-discovered; runs in the project's own.venv(ADR-0032). - MCP servers — one
mcp_servers:entry gives N tools, namespacedmcp__<server>__<tool>(ADR-0023). - Builtins —
read_file,write_file,write_memory,execute_shell_command,spawn_sub_agent.
All four emit the same ToolCallRequested / ToolCallCompleted events. → docs/tools.md
zymi as an MCP server
zymi mcp serve exposes pipelines as MCP tools over stdio to Claude Code, Claude Desktop, Cursor, or any framework with an MCP adapter (ADR-0033). Exposure is opt-in per pipeline:
expose:
mcp:
name: vpn_provision
description: "Provision a VPN client: preflight, then an approval-gated add."
mode: sync # or async — the caller task-augments (SEP-1686)
- Approvals render in the caller's UI — a gated step sends
elicitation/createback through the livetools/call; in Claude Code that's an approve/deny form. Clients without elicitation fail closed. ask:steps borrow the caller's brain — on a task-augmented call the task goesinput_requiredwith{ prompt, resume_token }, the agent answers viazymi/reasoning/resume. The answer is recorded, so replay is byte-identical.- The agent can debug its own runs —
--expose-observabilityadds read-onlyzymi.runs.list/.get/.events/.step_io(ADR-0034).
Honest limits: approvals inside async tasks wait on host adoption and time out (sync calls are fully interactive); cancellation is best-effort; arguments cross the boundary as strings; mcp serve is Unix-only for now.
Approvals — event-sourced, restart-safe
requires_approval: true on a tool publishes ApprovalRequested; a channel routes the human decision back. Channels: terminal, http, telegram, mcp_elicitation (ADR-0022). Resolution: pipeline override → project default → fail-closed. A crash mid-approval is repaired on restart. → docs/approvals.md
Replay, resume, observe
zymi runs # pipeline runs
zymi events --stream <run-id> # every event of one run
zymi verify # hash-chain integrity, with its denominator
zymi observe # TUI: runs / DAG / events, live
zymi resume <run-id> --from-step <id> # fork-resume; upstream steps stay frozen
Long-running services
zymi serve reacts to events from declarative connectors — http_inbound, http_poll, cron, file_read, stdin — and answers through outputs (http_post, file_append, stdout). That's enough for a full chat bot in YAML: zymi init --example telegram scaffolds one with approvals over Telegram buttons. SQLite by default; one store: postgres://… line for multi-process serving against shared state. → docs/connectors.md · docs/store-backends.md
Context window management
An agent's context is reconstructed from the event log each iteration, not accumulated in a buffer: older observations are masked in place, and only when the budget is still tight does one summarisation call compact the oldest batch (ADR-0016). → docs/context.md
Python embedding
With zymi-core in a project's venv (uv add zymi-core), the same wheel exposes Runtime, Event, EventBus, EventStore, ToolRegistry and the @tool decorator:
from zymi import Runtime
rt = Runtime.for_project(".", approval="terminal")
result = rt.run_pipeline("site_check", {"url": "https://example.com"})
print(result.success, result.final_output)
Cross-process patterns (a web app driving zymi serve over the shared store) → docs/python-api.md.
CLI cheatsheet
zymi init [--home | --example telegram] # scaffold a project, or the ~/.zymi library
zymi ls # what can I run (falls back to ~/.zymi)
zymi run <pipeline> [-i key=value …] # one-shot run; asks for missing inputs on a TTY
zymi fetch # uv sync — build ./.venv for @tool deps
zymi serve <pipeline…> | --all # long-running, event-driven
zymi pipelines # step-level view of every pipeline
zymi runs · zymi events · zymi verify · zymi observe · zymi resume
zymi mcp serve [--expose-observability] # pipelines as MCP tools
zymi mcp probe <name> -- <cmd> [args …] # smoke a third-party MCP server
zymi schema {project|agent|pipeline|tool|--all}
Commands use --dir, else the current directory if it is a project, else ~/.zymi. Full reference → docs/cli.md.
Documentation
- Getting started · CLI reference · Project YAML
- Pipelines · Tools · Agents · Approvals
- Connectors · Store backends · Events and replay · Python API
- zymi-skill — an Agent Skill that teaches your coding assistant to write zymi-native YAML
- llms.txt — flat index of these docs for LLMs and RAG tools
adr/— one short record per architectural decision
Contributing & License
zymi-core is built in Rust and shipped via PyPI. Bug reports, examples and PRs welcome — see CONTRIBUTING.md for the dev loop, test matrix and ADR workflow.
MIT — see LICENSE.
Metadata
Release files for zymi-core 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zymi_core-0.9.1.tar.gz | 1.1 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| zymi_core-0.9.1-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| zymi_core-0.9.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| zymi_core-0.9.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| zymi_core-0.9.1-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| zymi_core-0.9.1-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 30.8 MB
Release files / zymi_core-0.9.1.tar.gz
| Download URL | zymi_core-0.9.1.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5df89b00632901c37323af520cc2d8f3943da0aeed5dccf36c63f8a2d736e430
|
|
BLAKE2b-256 checksum How to use checksums |
16038a06961837c1c7f8a02e26a44a81a8f7796c4cedc886d07fc220700235cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / zymi_core-0.9.1-cp39-abi3-win_amd64.whl
| Download URL | zymi_core-0.9.1-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 6.4 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4a04e7136ec874ab1773cbcb5b6d3e23da84138e63099807f57e5acbe563dfd5
|
|
BLAKE2b-256 checksum How to use checksums |
b093a8ab64d094f1c1e4265261b54ff8041d5e7ca40e6d789a474aa8e26cd26a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / zymi_core-0.9.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | zymi_core-0.9.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 6.1 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
6d6c9c716bf53d96859f41e4bc00dc2ae5d4de8d29497b17b0b63ab6eaa12fdb
|
|
BLAKE2b-256 checksum How to use checksums |
2b5ab726d26bfd5b4a61401fdc6f7a7e1c378446ddfb00a8b2fee8a7b0d48bb0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / zymi_core-0.9.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | zymi_core-0.9.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
fbbd8267eaf63cd932d8c2e4710ebe63c343cd49862afb63cacfeef7a4b9b34c
|
|
BLAKE2b-256 checksum How to use checksums |
c0365bbaf85f8ef1a18653ba1409eceaf7964a363c9142cb4b24c5dd8b17cb4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / zymi_core-0.9.1-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | zymi_core-0.9.1-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 5.5 MB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c414df8fadc615b3f879043fa6eb72044c08eec8df5811de074d6b3b562ecbf1
|
|
BLAKE2b-256 checksum How to use checksums |
bb3431a7005135bf9af04145ff196c099cfc6a8f760f165c73ea112bc81020b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / zymi_core-0.9.1-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | zymi_core-0.9.1-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 5.9 MB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
a159dd13f193b6e21fa68aa982086b1149828ee580f1219b6b52830f69285be4
|
|
BLAKE2b-256 checksum How to use checksums |
d2703767a1a21bb3235cc5ff12f2eb088ec58bd0a44749795cf40076cbc4d235
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency log