Wintermolt: The Everything-Agent in 3 MB
A single native binary with zero runtime that ships 6 AI backends, 16 built-in tools, cron scheduling, Tailscale mesh networking, camera vision, browser automation, MCP bidirectional support, chat bridges to 4 platforms, and a macOS menu bar app.
What is Wintermolt?
Wintermolt is an autonomous AI agent CLI written entirely in Zig 0.15.
It compiles to a single 3 MB native binary with only
two external dependencies — libcurl for HTTPS and
sqlite3 for persistence — both pre-installed on macOS and
most Linux distributions. Unlike every other agent in this set, it has
zero runtime: no Node.js, no Python, no Electron, no
virtual environments.
The project ships ~18,400 lines of Zig across 51 source files,
plus two prebuilt Zig static libraries (libforagent.a and
libforlearn.a) from sibling projects. The codebase is
organized into clean modules: agent core, API clients, tools, MCP,
chat/web/menubar bridges, and a canvas renderer.
Key differentiator
Wintermolt is the only agent in this entire set that
cross-compiles to any platform Zig supports — ARM boards like Jetson
and Raspberry Pi included — with a single build command:
zig build -Dtarget=aarch64-linux-gnu.
Architecture overview
| Module | Files | Lines | What it does |
|---|---|---|---|
src/main.zig |
1 | 1,202 | Entry point, REPL, 7 execution modes |
src/agent/ |
13 | 5,226 | Core agent: loop, tools, config, history, storage, scheduler, RAG, skills, subagents, router |
src/api/ |
7 | 2,460 | Multi-backend AI clients (Ollama, Claude, OpenAI, DeepSeek, Qwen, Gemini) |
src/tools/ |
14 | 4,521 | 16+ built-in tools: bash, file I/O, grep, glob, HTTP, search, camera, browser, Tailscale, canvas |
src/mcp/ |
4 | 1,001 | MCP client + server (bidirectional) |
src/chat/bridge.zig |
1 | 278 | Chat platform IPC (Discord, Telegram, Slack, WhatsApp) |
src/web/bridge.zig |
1 | 1,062 | Web UI WebSocket bridge with streaming |
src/menubar/bridge.zig |
1 | 314 | macOS native menu bar Swift sidecar IPC |
src/gateway/bridge.zig |
1 | 213 | OpenAI-compatible API gateway |
The agentic loop
The core loop lives in src/agent/loop.zig (~646 lines).
The AgentLoop struct runs a
prompt → tools → observe → repeat cycle with up to
25 tool iterations per turn:
-
User message added to history with approximate
token counting (
approx_tokens += text.len / 3) -
RAG indexing — fire-and-forget
rag.indexMessage()for Pinecone semantic memory -
Tool relevance filtering — keyword-matches user
text against trigger lists to select extended tools
(
tools.getRelevantDefinitions()) - API call — streams to the primary backend with live terminal output via callback
-
Response parsing:
.end_turn,.max_tokens,.stop_sequence,.tool_use, or.unknown -
Tool execution —
executeTools()iterates over tool_use content blocks - Results fed back as user-role messages (required by the API pattern)
- Context overflowhistory.emergencyCompact() (drops to 40% budget) and retries
The sendToBackend method implements
automatic fallback: if the primary backend fails,
it tries Ollama first (local, no rate limits), then OpenAI.
Key file
src/agent/loop.zig — AgentLoop struct,
processInput() at line 182,
sendToBackend() at line 294
6 AI backends — one binary
All backends share a unified protocol.Message /
protocol.Response wire type in
src/api/protocol.zig (~281 lines). The dispatch happens
in loop.zig's switchBackend:
| Backend | Protocol | Streaming | Auth | Default Model |
|---|---|---|---|---|
| Ollama | NDJSON | Yes, line-by-line | None (local) | qwen3:0.6b |
| Claude | SSE (Anthropic) | Yes, event-driven | X-Api-Key |
claude-sonnet-4-20250514 |
| OpenAI | SSE (OpenAI) | Yes | Bearer token | gpt-4o-mini |
| DeepSeek | SSE (OpenAI-compatible) | Yes | Bearer | deepseek-chat |
| Qwen | SSE (OpenAI-compatible) | Yes | Bearer | qwen-plus |
| Gemini | SSE (OpenAI-compatible) | Yes | Bearer | gemini-2.0-flash |
The DeepSeekClient struct is effectively a
universal OpenAI-compatible client — it's reused for
OpenAI, DeepSeek, Qwen, Gemini, and the custom forAI
endpoint by simply overriding the api_url field.
Three hand-written streaming parsers handle the wire formats:
sse.zig (~461 lines) for Anthropic SSE,
openai_sse.zig (~287 lines) for OpenAI SSE, and
ndjson.zig (~250 lines) for Ollama NDJSON. Each is
an incremental character-by-character parser with no streaming
library dependency.
The 16 built-in tools
Tool dispatch lives in src/agent/tools.zig (~717 lines)
with a three-layer architecture:
- Layer 1 — Built-in tools hardcoded in the
executeTooldispatch chain - Layer 2 — Runtime skills loaded from
skill.jsonmanifests - Layer 3 — MCP remote tools from external MCP servers (prefixed like
filesystem__read_file)
| Tool | What it does |
|---|---|
bash | Shell execution with safety checks (pattern-matches against rm -rf /, dd if=, etc.) |
file_read | Read any file (text or images via multimodal) |
file_write | Create or overwrite files |
file_edit | Surgical find-and-replace editing |
glob | Recursive file search by pattern |
grep | Content search with regex |
http_request | HTTP GET/POST/PUT/DELETE to any URL |
web_search | DuckDuckGo search (no API key) |
camera_capture | Camera snapshots, screenshots, OAK-D depth |
image_process | Format conversion (BMP, PNG via sips/ffmpeg) |
browser_control | Full Chrome automation via DevTools Protocol (~895 lines) |
memory_search | Semantic search over conversation history (Pinecone RAG) |
schedule | Cron jobs — schedule recurring commands |
tailscale | Mesh VPN — query peers, devices, connectivity |
canvas_update | A2UI — render rich UI surfaces in terminal or web |
harness_create | CLI-Anything — generate agent wrappers for any software |
The bash tool includes automatic API key redaction —
it scans for 12 secret patterns (sk-ant-,
sk-proj-, xoxb-, ghp_,
AIza, etc.) before returning output to the AI context.
Cron scheduler
src/agent/scheduler.zig (~756 lines) implements a
SQLite-persisted job scheduler with three schedule
types:
every— repeat interval ("5m","1h","30s")at— daily at time ("09:00","14:30")cron— standard cron expression ("*/5 * * * *")
The tickScheduler() is called from the REPL loop on
every iteration. It queries due jobs, executes each via the bash tool,
and updates last_run/next_run. Jobs are
auto-disabled after max_retries consecutive failures.
No other agent in this set has a built-in cron scheduler.
MCP: both client and server
Wintermolt is one of only two agents in this set that implements MCP bidirectionally (Crush is the other).
As server (src/mcp/server.zig, ~214 lines):
Exposes 20+ Wintermolt tools via JSON-RPC 2.0 over stdio. Supports
initialize, tools/list,
tools/call, resources/list,
prompts/list, ping.
As client (src/mcp/client.zig, ~421 lines):
Loads external MCP servers from ~/.wintermolt/mcp.json,
spawns each as a child process with stdin/stdout pipes, runs the
3-step MCP handshake, and prefixes all discovered tool names with
"servername__" (e.g., filesystem__read_file).
Chat bridges
All bridges follow the same sidecar IPC pattern: Zig spawns a child process (TypeScript/Swift), communicates via JSON lines over stdin/stdout pipes. No sockets, no HTTP servers, no shared memory — clean process boundaries.
| Bridge | Sidecar | What it does |
|---|---|---|
| Chat | TypeScript | Discord, Telegram, Slack, WhatsApp — multi-platform bot |
| Web | TypeScript | WebSocket UI at localhost:3000 with token-by-token streaming |
| Menu Bar | Swift | macOS native NSStatusBar app (~270 lines, no Electron) |
| Gateway | TypeScript | Exposes OpenAI-compatible /v1/chat/completions API |
The chat bridge uses a 7-tier priority binding system
in src/agent/router.zig (~585 lines):
peer → parent_peer →
guild_role → guild → team →
account → channel.
Memory and RAG
Tier 1 — SQLite (src/agent/storage.zig,
~793 lines): ~/.wintermolt/history.db with
conversations and messages tables. All
public methods are designed for catch-and-ignore — storage failures
never break the agentic loop.
Tier 2 — Pinecone RAG
(src/agent/rag.zig, ~577 lines): Vector database for
semantic search with auto-embedding via Pinecone's integrated
inference. Every user and assistant message is indexed fire-and-forget.
Namespaced by user session (web mode) or domain (knowledge bases).
Skills system
Two-layer skill system:
-
Comptime catalog (
src/agent/skills.zig, 158 lines): 14 built-inSkillEntrystructs — zero allocation, zero I/O, pure string literals. -
Runtime plugins
(
src/agent/skill_loader.zig, ~367 lines): Scans./skills/,~/.wintermolt/skills/, and~/.wintermolt/plugins/*/skills/. Each skill gets its owntool_schema, optionalbackend/modelpreferences, and a handler type (bash,mcp,script, orprompt).
The project ships 79 skill definitions across 11 domains: Zortran Core, Fortran Kernels, Zig Systems, Physics/Simulation, AI/ML Kernels, Cybersecurity, Synthetic Data, Agent Architecture, Audio/Music, 3D/VFX, and Engineering.
Unique engineering decisions
No @cImport pattern
All C interop uses explicit extern fn declarations
(~12 curl functions, ~15 sqlite functions). No header file parsing,
no platform-specific header dependency. Keeps the binary small and
cross-compilation clean.
Hand-written streaming parsers
Three SSE/NDJSON parsers, each ~250–460 lines of incremental character-by-character processing. No streaming library dependency. Each handles escape sequences, nested objects, partial chunks across curl callbacks.
Docker sandbox mode
Optional sandboxed bash via Docker: read-only CWD mount, no network, memory/CPU limits, timeout enforcement. Falls back to host execution if Docker is unavailable.
Subagent system
Parent-child spawning with depth limiting (max depth 3, max
concurrent 4). Each subagent gets its own AgentLoop
with independent history and config. Callback-based design avoids
circular dependencies.
Camera + vision built-in
Captures from cameras (imagesnap on macOS, ffmpeg on Linux, OAK-D depth). Object detection via local LLaVA model. Base64-encoded images flow through the agentic loop as vision content blocks.
Browser automation
Full Chrome DevTools Protocol integration (~895 lines). List tabs, navigate, click elements, type text, evaluate JS, screenshot, and snapshot page content.
7 execution modes
| Mode | Command | Description |
|---|---|---|
| REPL | wintermolt | Interactive terminal session |
| Single-shot | wintermolt -e "prompt" | Run one prompt, print result, exit |
| Setup | wintermolt --setup | Interactive API key + model wizard |
| Chat | wintermolt --chat | Multi-platform messaging bot |
| Web | wintermolt --web | Browser UI at localhost:3000 |
| Menu Bar | wintermolt --menubar | macOS native status bar app |
| MCP Server | wintermolt --mcp-server | Expose tools via JSON-RPC 2.0 |
Strengths
- Binary footprint — 3 MB vs 200–500 MB for Node.js/Electron agents
- Zero runtime — no npm, pip, venv, node_modules, or Docker required
- Cross-compilation — one command targets ARM, x86_64, macOS, Linux
- Feature breadth — no other single agent has cron + Tailscale + camera + browser + MCP + chat bridges
- Secrets redaction — automatic API key scrubbing from bash output (12 patterns)
- Fallback chain — primary backend failure auto-falls back to Ollama then OpenAI
- Clean process boundaries — all sidecars use JSON-lines over stdio, no sockets
Tradeoffs
Where Wintermolt gives things up
- TypeScript sidecars — while the core is pure Zig, the chat, web, and gateway bridges require TypeScript runtimes. The core binary doesn't need them, but full functionality does.
-
Prebuilt libraries —
libforagent.aandlibforlearn.aare distributed as prebuilt Zig archives, not built from source in-tree. - Bash safety is pattern-based — unlike Neovate's quote-aware pipeline parser or Claude's tree-sitter AST analysis, Wintermolt's bash guards use regex pattern matching.
- Less polished than Claude Code — the feature surface is enormous, but the UX polish of productized agents like Claude Code or Crush is not quite there yet.
- Harder to audit — 18,400 lines of Zig is compact for what it does, but the breadth of features (cron, Tailscale, camera, browser, chat, MCP, RAG) means there's a lot to verify.
Key files to read
Core runtime
src/agent/loop.zig (agentic loop, 646 lines),
src/agent/tools.zig (tool dispatch, 717 lines),
src/agent/config.zig (multi-backend config, 461 lines),
src/agent/storage.zig (SQLite persistence, 793 lines)
API clients
src/api/ollama.zig (NDJSON streaming, 484 lines),
src/api/deepseek.zig (universal OpenAI-compatible, 373 lines),
src/api/sse.zig (Anthropic SSE parser, 461 lines)
Unique features
src/agent/scheduler.zig (cron jobs, 756 lines),
src/tools/browser.zig (CDP automation, 895 lines),
src/tools/camera.zig (vision, 482 lines),
src/tools/tailscale.zig (mesh VPN, 160 lines),
src/agent/rag.zig (Pinecone RAG, 577 lines)
MCP and bridges
src/mcp/client.zig (MCP client, 421 lines),
src/mcp/server.zig (MCP server, 214 lines),
src/web/bridge.zig (WebSocket bridge, 1,062 lines),
src/menubar/bridge.zig (macOS menu bar, 314 lines)
Verdict
Best designed, if you value a portable binary
Wintermolt is the only agent here that can be cross-compiled to
ARM boards, embedded devices, or any Zig target. The no-runtime
philosophy is carried through every module — explicit
extern fn declarations, hand-written parsers, and
JSON-lines IPC for all sidecars.
Most ambitious feature set
No other agent in this set combines a coding CLI, cron scheduler, Tailscale mesh query, camera vision, browser automation, MCP bidirectional, multi-platform chat bot, macOS menu bar app, and an OpenAI-compatible gateway — all in one 3 MB binary.