sprklai/zenii
by sprklai
README.md
# Zenii *(zen-ee-eye)*
<p align="center">
<img src="assets/zenii-master.gif" alt="Zenii demo" width="720" />
</p>
<h2 align="center">One local AI backend. Every interface.</h2>
<p align="center">
Run a daemon at <code>localhost:18981</code>. Your desktop app, CLI, TUI, scripts,
and MCP clients share the same memory, tools, providers, channels, and scheduler — no sync, no duplication.
</p>
<p align="center">
<a href="https://github.com/sprklai/zenii/releases/latest">
<img src="https://img.shields.io/github/v/release/sprklai/zenii?style=flat-square" alt="Latest release" />
</a>
<a href="https://github.com/sprklai/zenii/actions/workflows/ci.yml">
<img src="https://img.shields.io/github/actions/workflow/status/sprklai/zenii/ci.yml?style=flat-square&label=CI" alt="CI" />
</a>
<a href="LICENSE">
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="MIT license" />
</a>
<a href="https://github.com/sprklai/zenii/actions/workflows/ci.yml">
<img src="https://img.shields.io/badge/tests-1900-blue?style=flat-square" alt="1900 tests" />
</a>
<a href="https://github.com/sprklai/zenii/pulls">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square" alt="PRs welcome" />
</a>
</p>
---
## Start in 60 seconds
```bash
curl -fsSL https://raw.githubusercontent.com/sprklai/zenii/main/install.sh | bash
zenii-daemon &
# Store a fact once
curl -s -X POST http://localhost:18981/memory \
-H "Content-Type: application/json" \
-d '{"key":"deploy","content":"Production database is on port 5434"}' >/dev/null
# Ask about it later — from a script, cron job, or another machine
curl -s -X POST http://localhost:18981/chat \
-H "Content-Type: application/json" \
-d '{"session_id":"ops","prompt":"What port is the production database on?"}' | jq -r '.response'
```
That is the core contract: write state once, read it from anywhere that speaks HTTP.
> [!TIP]
> **Interactive API Docs** — once the daemon is running, open
> **[http://127.0.0.1:18981/api-docs](http://127.0.0.1:18981/api-docs)**
> in your browser. You get a full Swagger-style explorer: every endpoint documented, live request
> testing, and code-snippet generation for **curl, Python, Go, TypeScript, Rust**, and more.
> No separate setup needed — it's built in.
---
## Why Zenii
Most AI tools are per-session and per-interface. You get memory in the chat UI but not in your shell script. You wire a tool to one agent and have to re-wire it to the next.
Zenii solves this with a **shared local backend**:
| Without Zenii | With Zenii |
|---|---|
| Each script manages its own AI context | One daemon holds memory for all of them |
| Tools re-implemented per project | 19 tools registered once, available everywhere |
| Provider API keys scattered across configs | One credential store, one place to rotate |
| Desktop UI and scripts drift apart | Both call the same gateway |
| MCP tools only available inside the IDE | Expose the same tools to any MCP client |
---
## Architecture
<p align="center">
<img src="docs/assets/zenii_architecture.png" alt="Zenii system architecture" width="720" />
</p>
One Rust library crate (`zenii-core`) holds all business logic. Five thin binary crates (daemon, CLI, TUI, desktop, MCP server) are shell wrappers around the same axum gateway, SQLite database, agent loop, and tool registry.
---
## What Ships Today
**Interfaces**
| Binary | Use it for |
|---|---|
| `zenii-daemon` | Local HTTP + WebSocket API server — the core of everything |
| `zenii` | Quick prompts, shell pipelines, terminal workflows |
| `zenii-tui` | Interactive terminal UI |
| `zenii-desktop` | Native Tauri desktop app |
| `zenii-mcp-server` | Expose all 19 Zenii tools to Claude Code, Cursor, VS Code |
**Capabilities**
| Domain | What it does |
|--------|-------------|
| **Memory** | Persistent semantic recall — BM25 field weighting, temporal decay, vector deduplication, content-addressed dedup |
| **Karpathy LLM Wiki** | Ingest PDFs, DOCX, PPTX, XLSX, images — knowledge graph, AI query, auto-lint |
| **AI Agent** | Multi-step reasoning, tool use, streaming, delegation with human approvals |
| **Tools (19)** | Shell, file ops, web search, process control, patch, memory, wiki — one registry, every interface. Tool output compression keeps context lean (configurable per-tool line/result limits) |
| **Providers (6+)** | OpenAI · Anthropic · Gemini · OpenRouter · Vercel AI Gateway · Ollama · any OpenAI-compatible endpoint |
| **Workflows** | TOML/YAML DAG chains — tools, conditionals, loops, parallel steps, run history, cancellation |
| **Scheduler** | Cron + interval jobs, each run as a full agent turn with access to all tools |
| **Channels** | Telegram · Discord · Slack — inbound routing, unified inbox, threaded conversations (feature-gated) |
| **PAR (Polyglot Agent Runtime)** | Run external GitHub code (Python via `uvx`, Node via `npx`) as tools — dependencies installed on demand into an isolated cache (no bundled sidecar), with self-healing on failure |
| **MCP** | Server: expose all tools to Claude Code, Cursor, Gemini CLI, Windsurf · Client: consume external MCP servers |
| **Security** | OS keyring · AES-256-GCM encryption · surface-based permission model (CLI/desktop/TUI/MCP/API) |
---
## Model Routing Hints
Prepend a hint prefix to any prompt to route it to a specialized model without changing your provider config:
```bash
# Route to a reasoning-capable model
curl -s -X POST http://localhost:18981/chat \
-H "Authorization: Bearer $ZENII_TOKEN" \
-d '{"prompt":"hint:reasoning Explain how the Raft consensus algorithm handles leader election"}'
# Route to a fast low-latency model
curl -s -X POST http://localhost:18981/chat \
-H "Authorization: Bearer $ZENII_TOKEN" \
-d '{"prompt":"hint:fast What time is it?"}'
```
Configure each hint target in `config.toml`:
```toml
routing_hint_reasoning = "claude-opus-4-5"
routing_hint_fast = "gpt-4o-mini"
routing_hint_vision = "gpt-4o"
routing_hint_summarize = "claude-haiku-3-5"
```
If a hint has no configured target, the default model is used and a warning is logged.
---
## Karpathy LLM Wiki
Knowledge compiled at ingestion time, not re-derived at every query. Drop in a document; Zenii extracts, indexes, and links the knowledge so your agent can answer questions against it instantly.
```bash
# Ingest a runbook, spec, or doc
curl -s -X POST http://localhost:18981/wiki/ingest \
-H "Authorization: Bearer $ZENII_TOKEN" \
-d '{"url": "https://example.com/runbook.pdf"}'
# Query it — answers come from the compiled knowledge base
curl -s -X POST http://localhost:18981/wiki/query \
-H "Authorization: Bearer $ZENII_TOKEN" \
-d '{"query": "What does section 3 say about rollback?"}'
```
- Supports PDF, DOCX, PPTX, XLSX, and images via MarkItDown
- Knowledge graph with force-directed visualization in the web UI
- Queryable from any interface — CLI, desktop, or agent loop
- Auto-lint detects inconsistency and gaps across pages
Full guide: [docs.zenii.sprklai.com/wiki](https://docs.zenii.sprklai.com/wiki)
---
## MCP: Server and Client
**As MCP server** — expose all 19 Zenii tools to any agent:
```json
// .mcp.json — works with Claude Code, Cursor, Gemini CLI, Windsurf, Codex
{
"mcpServers": {
"zenii": {
"command": "zenii-mcp-server",
"args": ["--transport", "stdio"]
}
}
}
```
**As MCP client** — Zenii can also consume external MCP servers. Add GitHub, Postgres, Filesystem, or any custom MCP server and its tools become available in your agent loop alongside Zenii's own 19.
**[AGENT.md](AGENT.md)** — a machine-readable guide written for AI coding agents (Claude Code, Cursor, Gemini CLI, Windsurf, Codex). Drop it in your project or point your agent at it to give it a complete map of Zenii's API surface.
Full guide: [docs.zenii.sprklai.com/mcp](https://docs.zenii.sprklai.com/mcp)
---
## Polyglot Agent Runtime (PAR)
Run external code from GitHub as Zenii tools. Write a Python script or Node module, declare it in a manifest, and Zenii handles everything: dependency installation, runtime detection, isolation, and automatic repair on failure.
### Install a Python Tool
```bash
# Check runtimes
zenii runtime status
# Install uv (Python runtime) if needed
zenii runtime install uv
# Install a Python tool from GitHub
zenii plugin install https://github.com/yourteam/repo-analyzer
# Use it immediately
zenii chat
# > analyze the complexity of my Python project
```
### Write Your Own Tool
**zenii-plugin.toml:**
```toml
[plugin]
name = "repo-analyzer"
version = "0.1.0"
description = "Analyze repository structure"
[[tools]]
name = "analyze"
description = "Analyze repo complexity"
binary = "main.py"
runner = "uvx"
package = "git+https://github.com/yourteam/repo-analyzer@v0.1.0"
required_runtime = "python>=3.11"
[[tools.tests]]
input = { repo_path = "." }
expect = { file_count = { ">": 0 } }
```
**main.py:**
```python
import sys, json
# Tool receives JSON on stdin, returns JSON on stdout
data = json.loads(sys.stdin.read())
result = analyze(data["repo_path"])
print(json.dumps({"success": True, "output": result}))
```
### Key Features
- **On-demand deps** — installed via `uv`/`npx` into an isolated cache (no fat sidecar)
- **Runtime auto-detect** — doctor probes for Python, Node.js, etc.; users can install with `zenii runtime install uv`
- **Self-healing** — tools with declared `tests` auto-repair on failure: dependency errors get the missing module added, logic bugs get a reflective patch
- **Works everywhere** — available in chat, delegation, workflows, CLI, desktop, and MCP
Full guide: [docs.zenii.sprklai.com/par-guide](https://docs.zenii.sprklai.com/par-guide)
---
## Workflows and Scheduler
**Workflows** — chain tools into DAGs with conditionals, loops, and parallel steps:
```yaml
# ~/.config/zenii/workflows/daily-digest.yml
name: daily-digest
steps:
- id: search
tool: web_search
args: { query: "Rust ecosystem news today" }
- id: store
tool: memory_store
args: { key: "digest/{{date}}", content: "{{steps.search.result}}" }
```
Run manually: `POST /workflows/daily-digest/run`
**Natural Language Workflow Creation** — describe a workflow in plain English; Zenii generates the TOML and opens the visual builder automatically. Available from the Workflows page (toggle to "Describe in English") and from the chat window (⬡ Workflow button, mutually exclusive with Delegate).
**Scheduler** — trigger any prompt or workflow on a cron schedule, executed as a full agent turn with access to all tools:
```bash
curl -s -X POST http://localhost:18981/scheduler/jobs \
-H "Authorization: Bearer $ZENII_TOKEN" \
-d '{"name":"daily-digest","cron":"0 8 * * *","prompt":"Run the daily-digest workflow"}'
```
Full guide: [docs.zenii.sprklai.com/workflows](https://docs.zenii.sprklai.com/workflows) · [docs.zenii.sprklai.com/scheduler](https://docs.zenii.sprklai.com/scheduler)
---
## Install
### macOS / Linux
```sh
curl -fsSL https://raw.githubusercontent.com/sprklai/zenii/main/install.sh | sh
```
Installs `zenii` (CLI) and `zenii-daemon` to `~/.local/bin`.
### Windows
Download and run the desktop installer (`.msi` or `.exe`) from
[GitHub Releases](https://github.com/sprklai/zenii/releases/latest).
For headless / CLI-only, grab `zenii.exe` and `zenii-daemon.exe` from the same page.
### Cargo
```sh
cargo install --git https://github.com/sprklai/zenii zenii zenii-daemon
```
Full platform notes: [Installation & Usage](https://docs.zenii.sprklai.com/installation-and-usage)
---
## Build from Source
Prerequisites: Rust 1.85+, Bun, SQLite development libraries.
```bash
git clone https://github.com/sprklai/zenii.git
cd zenii
cargo build --release -p zenii-daemon # headless server
cargo build --release -p zenii-cli # CLI client
cd crates/zenii-desktop && cargo tauri build # desktop app
```
Full setup guide: [docs/development.md](docs/development.md)
---
## Good Fit
- Local automations that need shared memory across scripts, bots, and scheduled jobs
- Developer tooling that wants a single AI backend reachable via HTTP or MCP
- Self-hosted workflows where privacy and local control matter
- Projects that want a desktop UI and a scriptable backend without maintaining two stacks
- Self-hosted on a VPS, Raspberry Pi, or Docker — runs as a systemd service or container behind nginx/Caddy ([Deployment guide](https://docs.zenii.sprklai.com/deployment))
## Zenii PiDog (Raspberry Pi) Demo
<p align="center">
<img src="assets/Zenii-PiDog.gif" alt="Zenii running on a Raspberry Pi PiDog robot" width="540" />
</p>
Zenii runs on ARM — same binary, same API. Deploy it on a Raspberry Pi, attach tools, and your hardware becomes an AI-addressable endpoint over HTTP.
---
## Not a Good Fit
- Multi-user or SaaS deployments (single-user daemon, no multi-tenant auth)
- Drop-in OpenAI-compatible server (Zenii has its own API surface)
- Mobile apps (planned, not yet shipped)
---
## Docs
- [Website](https://zenii.sprklai.com)
- [Documentation](https://docs.zenii.sprklai.com)
- [Installation & Usage](https://docs.zenii.sprklai.com/installation-and-usage)
- [**Interactive API Explorer**](http://127.0.0.1:18981/api-docs) — live Swagger-style docs at `localhost:18981/api-docs` (daemon must be running)
- [API Reference](https://docs.zenii.sprklai.com/api-reference)
- [CLI Reference](https://docs.zenii.sprklai.com/cli-reference)
- [Configuration](https://docs.zenii.sprklai.com/configuration)
- [Polyglot Agent Runtime (PAR)](https://docs.zenii.sprklai.com/par-guide) — run external code as tools
- [LLM Wiki](https://docs.zenii.sprklai.com/wiki)
- [Workflows & Scheduler](https://docs.zenii.sprklai.com/workflows)
- [Architecture](https://docs.zenii.sprklai.com/architecture)
- [AGENT.md](AGENT.md) — guide for AI coding agents
- [CHANGELOG.md](CHANGELOG.md)
- [ROADMAP.md](ROADMAP.md)
---
## Contributing
Typo fixes, tests, and focused bug fixes can go straight to a PR.
Larger feature work should start with [CONTRIBUTING.md](CONTRIBUTING.md).
If Zenii is useful to you — [star the repo](https://github.com/sprklai/zenii) and tell a developer friend.
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues