Get started.
No API keys, no cloud account. One line installs the whole stack — Node, Ollama, agent + memory + council — and hands off to the tachi-agent setup wizard. Then open an interactive chat with bare tachi-agent. Ctrl-C halts cleanly; progress goes to stderr, the answer to stdout.
One line installs everything. Then just chat.
tachi-agent setup picks a brain — local Ollama by default, or paste one OpenRouter key to power the agent and the whole tachibot council — wires the MCP servers, generates GATEWAY_TOKEN, optionally installs the daemon service, then runs doctor. It's re-runnable and merge-preserving: existing values in ~/.tachi/.env become the defaults. Skip it with TACHI_NO_WIZARD=1.chmod 600. Every tachi-agent bin loads it as defaults at startup — real env vars always win; TACHI_ENV_FILE overrides the path.tachi-agent opens a persistent REPL. The prompt shows tachi [driver·skill] ›. The session is multi-turn; /reset starts fresh; /help lists commands. Ctrl-D or /exit to leave.1# ONE LINE — installs Node ≥ 22 + Ollama if missing, then tachi-agent + dokoro2# + tachibot-mcp, and hands off to the interactive setup wizard3curl -fsSL https://bypawel.github.io/tachi-agent/install.sh | sh4 5# — or manually —6# 1. install the stack globally7npm i -g tachi-agent dokoro tachibot-mcp8 9# 2. pull a local brain (the wizard offers OpenRouter as the one-key alternative)10ollama serve &11ollama pull qwen2.512 13# 3. run the wizard — picks a brain, wires MCP servers, writes ~/.tachi/.env (chmod 600)14tachi-agent setup15 16# 4. preflight check17tachi-agent doctor18 19# 5. open interactive chat20tachi-agentOne-shot tasks and local development.
Ctrl-C halts the run cleanly (AbortSignal → aborted). Progress streams to stderr; the final answer prints to stdout — so you can pipe the answer while still watching steps.
Installing globally (or npm link from a clone) puts eight binaries on your PATH:
1# one-shot task (pass a string argument)2tachi-agent "verify HEAD against ADR-1..3"3 4# develop from source5npm install6npm test # vitest — core orchestrator, fully mocked7npm run build # tsc → dist/1# 1. local brain2ollama serve & # start Ollama3ollama pull qwen2.5 # recommended local tool-calling model4 5# 2. point at your MCP servers (council + memory)6export TACHIBOT_CMD="npx -y tachibot-mcp"7export DOKORO_CMD="npx -y @devlog-mcp/core" # optional; omit to run tachibot-only8 9# 3. build + link the tachi-agent command10npm install && npm run build && npm link11 12tachi-agent # interactive chat (default, no args)13tachi-agent "verify HEAD against ADR-1..3" # one-shot task14tachi-agent --driver openai # chat with the OpenAI heart15tachi-agent --skill researcher # chat with the researcher skill active16# dev mode: npm run dev -- "your task"All three layers in two commands.
The first command exercises every layer: dokoro recalls prior context (memory), tachibot_jury adjudicates the finding (reasoning), and the ReAct loop drives the whole flow (runtime). The second confirms the decision persists across sessions.
1# 1. run a task that exercises memory → reasoning → runtime2tachi-agent "review this repo, find one risky architectural issue, verify it with the council, remember the decision"3 4# 2. next session: the agent recalls what you decided5tachi-agent "what did we decide last time about that architecture risk?"Talk to the same hub, any surface.
Every front-end just calls orchestrator.run(task) — or attaches to a running daemon with an identical surface.
tachi-agent opens the interactive REPL; multi-turn (the conversation carries across turns; /reset clears). Pass a string for a one-shot task.--skill <name> loads a .tachi/skills/*.md recipe — system prompt + tool allowlist + driver preset./commands surface and per-chat multi-turn memory.run_agent MCP server; pass driver / skill / systemPrompt to run tachi-agent as a configurable sub-agent. Or delegate to external CLIs with run_coding_agent.GatewayClient.npm run swarm — see Swarm.tachi-agent service install (macOS launchd, primary path) or node dist/daemon/index.js under systemd — see Standalone.Env vars are the config surface.
Set them in ~/.tachi/.env (the wizard writes it) or a project .env loaded with node --env-file=.env. Real env vars always win.
Orchestrator
| Variable | Default | Purpose |
|---|---|---|
| TACHI_ALLOW | curated council/search/memory set | Comma-separated tool allowlist (exact names or server_ prefixes). tachibot_,dokoro_ exposes everything. |
| TACHI_FORCE_SEARCH | off | 1/true/yes/on → force a grounding search before reasoning on every task. |
| TACHI_MAX_EMPTY_TURNS | 2 | Consecutive blank model turns nudged through before halting as empty-response. |
| TACHI_CALL_TIMEOUT_MS | 120000 | Per-MCP-tool-call timeout. |
| TACHI_RUN_TIMEOUT_MS | 90000 | Whole-run wall-clock cap for the run_agent MCP server (max 3600000); callers can pass timeoutMs per call. The MCP client's own call timeout must be ≥ this (Claude Code: MCP_TOOL_TIMEOUT). |
| TACHI_MAX_TOOL_RESULT_CHARS | 30000 | Truncate tool results before they reach the model context (0 disables). |
| TACHI_CONTEXT_INSPECT | off | 1 → emit per-turn context JSONL to .tachi/context-inspect/. |
| TACHI_ENV_FILE | ~/.tachi/.env | Path of the wizard-managed env file. Every bin loads it as defaults at startup; real env vars always win. |
| TACHI_NO_WIZARD | unset | 1 skips the setup wizard at the end of the one-line installer. |
Drivers
| Variable | Default | Purpose |
|---|---|---|
| TACHI_DRIVER | ollama | Default brain by registered name: ollama · hermes · openai · openrouter. A queued task's driver field overrides per task. |
| OLLAMA_BASE_URL | http://127.0.0.1:11434 | Ollama endpoint for the local brain. |
| OLLAMA_MODEL | qwen2.5 | Local model name. |
| OLLAMA_NUM_CTX | 8192 | Context window override. |
| HERMES_BASE_URL / _MODEL / _API_KEY | unset | Optional Hermes (OpenAI-compatible) driver. |
| OPENAI_API_KEY | unset | Required for the openai driver. |
| OPENAI_MODEL | gpt-4o-mini | OpenAI model. |
| OPENAI_BASE_URL | https://api.openai.com/v1 | OpenAI-compatible endpoint (include /v1). |
| OPENROUTER_API_KEY | unset | Required for the openrouter driver. |
| OPENROUTER_MODEL | openrouter/auto | OpenRouter model. |
| OPENROUTER_BASE_URL | https://openrouter.ai/api/v1 | OpenRouter endpoint. |
MCP servers & skills
Front-ends
| Variable | Default | Purpose |
|---|---|---|
| TELEGRAM_BOT_TOKEN / TELEGRAM_ALLOWED_USER_IDS | required | Bot token + comma-separated numeric allowlist (fail-closed: empty = refuse to start). |
| SLACK_BOT_TOKEN / SLACK_APP_TOKEN / SLACK_ALLOWED_USER_IDS | required | Bot + Socket-Mode app token + user-ID allowlist (fail-closed). |
Gateway / daemon
| Variable | Default | Purpose |
|---|---|---|
| GATEWAY_TOKEN / GATEWAY_TOKENS | required | Bearer auth (single token, or name:token pairs for tenants). The daemon refuses to start without one. |
| GATEWAY_PORT | 8787 | Gateway listen port (tachi-agent-gateway). |
| TACHI_DAEMON_URL | unset | When set, thin clients (cli / repl / telegram / slack) attach to the daemon instead of building a local runtime. |
| TACHI_DAEMON_PORT | 8787 | Daemon listen port. |
| TACHI_SESSION_TTL_MS | 600000 | Idle TTL before an unattached finished run is GC'd. |
| TACHI_SESSION_BUFFER_MAX | 10000 | Per-run SSE replay ring-buffer cap. |
| TACHI_DRAIN_TIMEOUT_MS | 30000 | Hard upper bound on graceful-shutdown drain. |
| TACHI_DEBUG | off | Verbose stderr diagnostics. |
Standalone & swarm
| Variable | Default | Purpose |
|---|---|---|
| TACHI_QUEUE_FILE | .tachi/queue.json | Persistent task-queue file (atomic writes; crash-safe). |
| TACHI_QUEUE_POLL_MS | 2000 | Worker poll cadence over the queue. |
| TACHI_RUN_LOG_DIR | .tachi/runs | Durable per-run JSONL event log directory. |
| TACHI_NOTIFY | unset | Outcome push targets: comma-separated kind:target, e.g. telegram:123,slack:C0ABC. |
| TACHI_SCHEDULES_FILE | .tachi/schedules.json | Hand-edited recurring schedules (state kept separately in …-state.json). |
| TACHI_SCHEDULES_POLL_MS | 30000 | Schedule evaluation cadence. |
| TACHI_SWARM_ROLES | built-in roles | Comma-separated roles; name or name:driver; empty = defaults. |
TACHI_CODING_ROOTS, TACHI_CODING_ALLOW_WRITE, …) are documented on the Coding workers page.Extend without forking.
Register any brain, build the hub from a name, run. The complete public API is three interfaces — see src/types.ts. Implement Driver, ToolHost, or Memory and compose the same hub; no core changes required.
1import { createOrchestrator, registerDriver } from "tachi-agent";2 3// 1. register any brain (Hermes, a cloud model, OpenClaw, a Kimi-swarm driver)4registerDriver("hermes", () => new HermesDriver());5 6// 2. build the hub from a registered name (or a raw Driver instance)7const controller = new AbortController();8const result = await createOrchestrator({9 driver: "hermes",10 host,11 memory,12 options: {13 maxIterations: 12,14 timeoutMs: 90_000,15 signal: controller.signal,16 // memoryInLoop: true // opt-in: refresh recall + write a working-memory note17 // // each iteration. Off by default (adds per-step tool calls).18 },19}).run("verify HEAD against ADR-1..3");20// elsewhere: controller.abort() → run halts with haltedBy: "aborted"