Skip to main content
The Ziro mark: a geometric Z cradled in rotating gyroscope gimbal rings
Ziro is a LangGraph conversational agent runtime you run on your own machine. It ships as a Python package with a Textual terminal UI, keeps long-term memory and conversation checkpoints on local disk by default, and talks to any model through OpenRouter, Anthropic, OpenAI, or a custom endpoint you define yourself. Everything that shapes behaviour (persona, tools, permissions, guardrails, compaction) is a per-agent YAML file you can read and edit.

Quickstart

One install script to your first chat session in under five minutes.

Installation

Prerequisites, dependency groups, storage modes, and where state lives.

Architecture

The agent loop, the graph nodes, and how a turn actually runs.

Configuration

The per-agent policy files and how config layers resolve.

What’s in the box

Multi-agent flavours

A flavour is a top-level container chosen once at launch. It scopes which agents you can see, which threads exist, and one shared long-term memory, and it overlays a common policy baseline onto its member agents. The bundled flavours are chat, engineering, research, and safe. Inside a flavour you switch agents freely without losing memory or your current thread. Each agent lives in its own folder with its own persona, model, provider, tool policy, MCP servers, guardrails, and compaction policy, plus an enabled flag so individual agents can be turned on or off.

Agents

Per-agent folders, meta.yaml, personas, and the config layer chain.

Flavours

Scoping agents, threads, and memory behind one launch-time choice.

Progressive tool loading

Tools sit in three tiers. Core tools bind to the model every turn. Meta-tools provide the discovery surface. Deferred tools are registered but not bound until the model asks for them:
Activated tools persist for the rest of the thread up to a configured maximum, with LRU eviction after that. The result is a small prompt that still reaches a large tool surface. See Tools.

MCP servers

External MCP servers declared in an agent’s mcp_servers.yaml load at startup over stdio, sse, streamable_http, or websocket, with OAuth support. Their tools register under the server name as a namespace and enter the same deferred-discovery surface as local tools. A live manager holds a persistent session per server so tool calls reuse it, and server failures are non-fatal. See MCP.

Skills

SKILL.md files are indexed into a searchable collection. The agent finds relevant skills with search_skills, then pulls a specific reference or script file on demand with load_skill_ref, so a large skill library costs almost nothing in context until it is needed. Skills reach the agent from three sources, each tagged in the /skills list: bundled, workspace, and plugin. See Skills.

Guardrails

Input and output guards run as conditional graph nodes, toggled per agent by guardrails_policy.yaml. Backends include deterministic regex prompt-injection patterns, a HuggingFace classifier, Presidio PII detection, Llama Guard content safety, and any OpenAI-compatible endpoint for LLM-based evaluation. Rules are YAML, so adding one needs no code. If a guard blocks, the graph routes straight to a refusal with no model call. See Guardrails.

Automatic compaction

When a turn’s request exceeds a configured fraction of the model’s usable input budget, the compaction node picks a split that never orphans a tool message, folds the dropped span into a running summary carried in the system prompt, and removes those messages from both the live request and the persisted checkpoint. The most recent messages are always kept verbatim. Budget math reads the model’s real context length and output limits, so triggers stay honest per model. See Compaction.

Subagents

A parent agent delegates a self-contained subtask to a child running on a namespaced thread with its own persona, an empty message history, and a restricted toolset, then folds back one compact result. Subagents are single-file *.agent.md definitions: YAML frontmatter for the tool and skill allowlists, a Markdown body for the system prompt. A child’s rights are the intersection of its own declaration and the parent’s current rights, never wider. See Subagents.

Plugins

Ziro reads the native Claude Code plugin layout, so existing plugins work without re-authoring. Install from a git URL, a local path, or a marketplace; an enabled plugin’s skills, agents, prompt-macro commands, MCP servers, and hooks fold into the running agent with live hot-load and no restart. Third-party code that can execute (shell hooks and stdio MCP subprocesses) stays inert until you explicitly trust the plugin, and any file edit revokes that trust. See Plugins.

Textual TUI

The terminal UI paints in about 1.6 seconds and is usable while the engine finishes building on a background thread; anything you type early is queued and runs in order. It streams a turn live (reasoning, inline tool calls, then the answer) and carries a todo and active-tools side pane, a context-usage meter, an approval modal for human-in-the-loop gates, an MCP control panel, and live themes. Slash commands dispatch before the model, so /help or /agent costs no tokens. See The TUI.

Local-first storage

With no DATABASE_URL set, Ziro runs entirely on local files: SQLite for long-term memory and conversation checkpoints, FAISS for vectors. Set DATABASE_URL and the same code switches to PostgreSQL with pgvector.

Start here

The bare ziro command walks a first-run setup wizard, then the user, flavour, thread, and agent pickers, and drops you into chat.

Next steps

Agents

How an agent is defined, configured, and selected.

The TUI

The terminal interface, panels, streaming, and keybindings.