
🦀 OpenCrabs
The autonomous, self-improving AI agent. Single Rust binary. Every channel.
Autonomous, self-improving multi-channel AI agent built in Rust. Inspired by Open Claw.
___ ___ _
/ _ \ _ __ ___ _ _ / __|_ _ __ _| |__ ___
| (_) | '_ \/ -_) ' \ | (__| '_/ _` | '_ \(_-<
\___/| .__/\___|_||_| \___|_| \__,_|_.__//__/
|_|
🦀 The autonomous, self-improving AI agent. Single Rust binary. Every channel.
Author: Adolfo Usier
⭐ Star us on GitHub if you like what you see!
Why OpenCrabs?
OpenCrabs runs as a single binary on your terminal — no server, no gateway, no infrastructure. It makes direct HTTPS calls to LLM providers from your machine. Nothing else leaves your computer.
OpenCrabs vs Node.js Agent Frameworks
|
OpenCrabs (Rust) |
Node.js Frameworks (e.g. Open Claw) |
| Binary size |
26–29 MB single binary, zero dependencies |
1 GB+ node_modules with hundreds of transitive packages |
| Runtime |
None — runs natively |
Requires Node.js runtime + npm install |
| Attack surface |
Zero network listeners. Outbound HTTPS only |
Server infrastructure: open ports, auth layers, middleware |
| API key security |
Keys on your machine only. zeroize clears them from RAM on drop, [REDACTED] in all debug output |
Keys in env vars or config. GC doesn’t guarantee memory clearing. Heap dumps can leak secrets |
| Data residency |
100% local — SQLite DB, embeddings, brain files, all in ~/.opencrabs/ |
Server-side storage, potential multi-tenant data, network transit |
| Supply chain |
Single compiled binary. Rust’s type system prevents buffer overflows, use-after-free, data races at compile time |
npm ecosystem: typosquatting, dependency confusion, prototype pollution |
| Memory safety |
Compile-time guarantees — no GC, no null pointers, no data races |
GC-managed, prototype pollution, type coercion bugs |
| Concurrency |
tokio async + Rust ownership = zero data races guaranteed |
Single-threaded event loop, worker threads share memory unsafely |
| Native TTS/STT |
Built-in local speech-to-text (whisper.cpp) and text-to-speech — ~130 MB total stack, fully offline |
No native voice. Requires external APIs (Google, AWS, Azure) or heavy Python dependencies (PyTorch, ~5 GB+) |
| Telemetry |
Zero. No analytics, no tracking, no remote logging |
Server infra typically includes monitoring, logging pipelines, APM |
What stays local (never leaves your machine)
- All chat sessions and messages (SQLite)
- Tool executions (bash, file reads/writes, git)
- Memory and embeddings (local vector search)
- Voice transcription in local STT mode (whisper.cpp, on-device)
- Brain files, config, API keys
What goes out (only when you use it)
- Your messages to the LLM provider API (Anthropic, OpenAI, GitHub Copilot, etc.)
- Web search queries (optional tool)
- GitHub API via
gh CLI (optional tool)
- Browser automation (optional,
browser feature — auto-detects Chromium-based browsers via CDP, not Firefox)
- Dynamic tool HTTP requests (only when you define HTTP tools in
tools.toml)
Table of Contents
🎬 Full onboard
https://github.com/user-attachments/assets/833dd5e9-3bcc-432a-96ac-3a5bb97b5966
🎬 Demo
https://github.com/user-attachments/assets/7f45c5f8-acdf-48d5-b6a4-0e4811a9ee23
🎯 Core Features
AI & Providers
| Feature |
Description |
| Multi-Provider |
Xiaomi (default — free, no key during the launch window), Anthropic Claude, OpenAI, GitHub Copilot (uses your Copilot subscription), OpenRouter (400+ models), MiniMax, Google Gemini, z.ai GLM (General API + Coding API), Claude CLI, OpenCode CLI, Codex CLI (uses your ChatGPT/Codex subscription), Qwen Native (free OAuth with multi-account rotation), Qwen Code CLI (1k free req/day), and any OpenAI-compatible API (Ollama, LM Studio, LocalAI). Model lists fetched live from provider APIs — new models available instantly. Custom provider dialog: paste-by-default for API keys, Enter-to-load live models, typed-not-in-list models accepted and merged. Each session remembers its provider + model and restores it on switch |
| Fallback Providers |
Configure a chain of fallback providers — if the primary fails, each fallback is tried in sequence automatically. Any configured provider can be a fallback. Config: [providers.fallback] providers = ["openrouter", "anthropic"] |
| Per-Provider Vision |
Set vision_model per provider — the LLM calls analyze_image as a tool, which uses the vision model on the same provider API to describe images. The chat model stays the same and gets vision capability via tool call. Gemini vision takes priority when configured. Auto-configured for known providers (e.g. MiniMax) on first run |
| Prompt Caching |
Caches the stable context prefix (system prompt, brain files, earlier turns) on every caching-capable provider — Anthropic native (default), OpenAI/OpenRouter (cache_enabled), Qwen/Alibaba (zero-config auto), Xiaomi (server-side). Averaging ~87% cache efficiency in real use; watch it live in the Cache Efficiency card of /usage. Big reason a larger context window stays affordable |
| Context Window & Auto-Compaction |
Per-provider context_window override (default 200k, works on every provider); transparent auto-compaction at 65% (soft, background) / 90% (hard) of the window gives effectively unlimited session memory with no manual clearing |
| Real-time Streaming |
Character-by-character response streaming with animated spinner showing model name and live text |
| Local LLM Support |
Run with LM Studio, Ollama, or any OpenAI-compatible endpoint — 100% private, zero-cost |
| Usage Dashboard |
Per-message token count and cost displayed in header; /usage opens an interactive dashboard with daily activity charts, cost breakdowns by project/model/activity, core tool usage stats, and period filtering (Today/Week/Month/All-Time). Sessions are auto-categorized on startup (Development, Bug Fixes, Features, Refactoring, Testing, Documentation, CI/Deploy, etc.). Estimated costs for historical sessions shown as ~$X.XX |
| Context Awareness |
Live context usage indicator showing actual token counts (e.g. ctx: 45K/200K (23%)); auto-compaction at 70% with tool overhead budgeting; accurate tiktoken-based counting calibrated against API actuals |
| 3-Tier Memory |
(1) Brain MEMORY.md — user-curated durable memory loaded every turn, (2) Daily Logs — auto-compaction summaries at ~/.opencrabs/memory/YYYY-MM-DD.md, (3) Hybrid Memory Search — FTS5 keyword search + vector embeddings combined via Reciprocal Rank Fusion. Three modes: Local (embeddinggemma-300M, 768-dim, no API key, works offline), API (any OpenAI-compatible /v1/embeddings endpoint: OpenAI, Ollama, Jina, etc.), or FTS5-only (no embeddings, VPS-friendly, ~0 RAM overhead). Auto-detects VPS environments and disables local embeddings |
| Dynamic Brain System |
System brain assembled from workspace MD files (SOUL, USER, AGENTS, TOOLS, MEMORY) — all editable live between turns |
| Multi-Agent Orchestration |
Spawn typed child agents (General, Explore, Plan, Code, Research) for parallel task execution. Five tools: spawn_agent, wait_agent, send_input, close_agent, resume_agent. Each type gets a role-specific system prompt and filtered tool registry. Configurable subagent provider/model. Children run in isolated sessions with auto-approve — no recursive spawning |
| Recursive Self-Improvement |
⚠️ Experimental. Automatic feedback ledger tracks every tool execution, user correction, and provider error. Three tools: feedback_record (log observations), feedback_analyze (query patterns), self_improve (autonomously apply brain file changes — no human approval). Changes logged to ~/.opencrabs/rsi/improvements.md with daily archives. Startup digest injects performance summary into system prompt. Upstream template sync — automatically detects new releases, fetches updated brain file templates from the repo, diffs against local files, and appends only new sections (never overwrites user customizations). Backups created before every merge. Zero tokens spent when version unchanged. Zero setup — works out of the box via auto-migration |
| Feature |
Description |
| Image Attachments |
Paste image paths or URLs into the input — auto-detected and attached as vision content blocks for multimodal models. Also supports pasting raw image data from the clipboard (copied from a browser, screenshot tool, or any app) — on macOS via the clipboard as PNG, on Linux via wl-paste/xclip. The bytes are written to a temp file and routed through the existing image pipeline |
| Video Attachments |
Send a video on any channel (mp4, m4v, mov, webm, mkv, avi, 3gp, flv) or paste a video path in the TUI — the agent calls the analyze_video tool, which routes through Google Gemini’s multimodal video API (inline ≤18 MB, resumable Files API for larger). Requires image.vision.enabled = true with a Gemini API key in config.toml. Phase 1 is Gemini-native; a frame-extraction fallback for non-Gemini providers (ffmpeg → analyze_image per frame) is on the roadmap |
| PDF Support |
Attach PDF files by path — native Anthropic PDF support; for other providers, text is extracted locally via pdf-extract |
| Document Parsing |
Built-in parse_document tool extracts text from PDF, DOCX, HTML, TXT, MD, JSON, XML |
| Voice (STT) |
Voice notes transcribed via Groq Whisper API (whisper-large-v3-turbo), any OpenAI-compatible STT endpoint (set stt_base_url + stt_model — works with self-hosted Whisper, Deepgram-compatible proxies, etc.), Voicebox STT (self-hosted open-source voice stack — point voicebox_stt_base_url at your instance; 2s liveness probe runs before each request so a dead voicebox fails fast), or Local whisper.cpp via whisper-rs (runs on-device, Tiny 75 MB / Base 142 MB / Small 466 MB / Medium 1.5 GB, zero API cost). All dispatched through a single entry point so every channel gets the same provider priority chain — and an optional [providers.stt].fallback_chain lets the user codify “if my local voicebox is down, try Groq, then OpenAI” so transient outages auto-route to the next provider with zero user action. Choose mode in /onboard:voice. Included by default |
| Voice (TTS) |
Agent replies to voice notes with audio via OpenAI TTS API (gpt-4o-mini-tts), any OpenAI-compatible TTS endpoint (set tts_base_url + tts_model + tts_voice — works with self-hosted Coqui/Bark, ElevenLabs-compatible proxies, etc.), Voicebox TTS (async /generate → poll /generate/{id}/status → fetch audio; set voicebox_tts_base_url + voicebox_tts_profile_id), or Local Piper TTS (runs on-device via Python venv, Ryan / Amy / Lessac / Kristin / Joe / Cori, zero API cost). All outputs normalised to OGG/Opus via ensure_opus before delivery — consistent format across every channel regardless of backend. [providers.tts].fallback_chain provides the same auto-failover behaviour as the STT side. Falls back to text if disabled |
| Attachment Indicator |
Attached images show as [IMG1:filename.png] in the input title bar |
| Image Generation |
Agent generates images via Google Gemini (gemini-3.1-flash-image-preview “Nano Banana”) using the generate_image tool — enabled via /onboard:image. Returned as native images/attachments in all channels |
Vision setup — two paths, pick one
Path A (preferred, simpler). Set vision_model = "<model>" on your active [providers.<name>] block in config.toml. Works for every built-in and custom provider — the agent calls the vision model on the same provider endpoint via the analyze_image tool, so no second API key is needed. Pick a vision-capable model on that provider (DeepSeek chat models like deepseek-v4-flash reject image_url content, so point vision_model at a vision-capable variant of the same family — every provider has at least one).
[providers.opencode]
enabled = true
vision_model = "mimo-v2-omni" # any vision-capable model on this provider
Path B (fallback). Enable Gemini globally. Use this only when your active provider has no vision-capable model. Easiest way: run /onboard:image and the wizard walks you through. Manual setup:
# config.toml
[image.vision]
enabled = true
model = "gemini-3.1-flash-image-preview"
# keys.toml ← the Gemini key MUST live here, NOT in config.toml
[image]
api_key = "YOUR_GEMINI_KEY"
Gotcha: [image.vision] api_key = "..." in config.toml is silently ignored — the field carries #[serde(skip)] for security. Use keys.toml [image] section, or [providers.image.gemini] in config.toml + the key in keys.toml.
Diagnostic: when vision is unavailable for any reason, is_vision_available logs the exact cause at INFO level in ~/.opencrabs/logs/opencrabs.YYYY-MM-DD — search for target=vision.
Context window & auto-compaction (effectively unlimited memory)
OpenCrabs never makes you start a fresh session to “clear context.” Instead it auto-compacts: as a session’s history approaches the model’s context window, it summarizes the older turns in place and keeps going. Two tiers:
- 65% — soft trigger: spawns a background LLM compaction that summarizes history back down to ~65% of the budget. Non-blocking — the conversation keeps streaming.
- 90% — hard trigger: synchronous compaction before the next request, so a single turn can never overflow the window.
The triggers are percentages of the effective window, so they scale to whatever you set: at the 200k default compaction kicks in around 130k; at a 1M window, around 650k.
It’s transparent — most of the time you won’t notice it happen at all. Occasionally you’ll catch a brief inline notice while it summarizes (the agent tends to mention it dynamically, in its own voice), then the conversation carries on with the older turns condensed. You never have to start over or manually clear anything.
The budget defaults to 200,000 tokens — the battle-tested sweet spot: large enough for long sessions, small enough to keep each request fast and cheap. Override it per provider in config.toml:
[providers.xiaomi]
context_window = 1000000 # raise the budget; compaction still triggers at 65% / 90% of it
[providers.anthropic]
context_window = 1000000 # native providers too — Anthropic, Gemini, and the CLI providers
This override works for every provider — OpenAI-compatible (custom, xiaomi, qwen, openrouter, minimax, …) and the native Anthropic, Gemini, and CLI providers. A provider with no override inherits the 200k default.
Sizing guidance. 200k is the battle-tested sweet spot for essentially every cloud model. Going bigger has two real downsides — cost and context loss:
- Cost is the lesser one, and it’s softened by caching: OpenCrabs uses prompt caching across every caching-capable provider (currently averaging ~87% efficiency), and a long context is mostly an unchanged prefix served from cache — so a bigger window costs far less than the raw token count suggests.
- Context loss is the one to watch: most models degrade as the window fills — they lose track of the middle and recall less reliably. Only the latest SOTA models hold large context robustly: closed (Opus 4.7 / 4.8, Fable 5, GPT-5.5, Gemini 3.1, …) or open (Qwen 3.7, Kimi K2.7, MiMo V2.5, GLM 5.2, DeepSeek V4, and the newer releases that keep coming from these and other labs). So raise
context_window mainly on those frontier models; on anything older or smaller, staying near 200k keeps answers sharper.
Local models want less: 128k is a good sweet spot — go lower if your machine is tight on resources or you start noticing hallucinations/fabrications, and higher only if you have more than 32GB of RAM and have tested your model at a larger window. Not sure what fits your setup? Reach out to Adolfo for suggestions/support, or open a GitHub discussion.
Leave auto-compaction on — it’s been battle-tested over months and needs no babysitting. Only run a manual compaction (the /compact command) if you have a specific, strong reason to summarize early; otherwise let it manage itself.
Prompt caching (every caching-capable provider)
A long context is mostly a stable prefix — system prompt, brain files, earlier turns rarely change between requests. OpenCrabs caches that prefix wherever the provider supports it, so you pay full price for it once and a fraction on every reuse. Across real usage it’s currently averaging ~87% cache efficiency, which you can watch live in the Cache Efficiency card of /usage. This is the main reason a larger context_window costs far less than its raw token count suggests.
How it turns on depends on the provider:
- Anthropic — native prompt caching, on by default: the
cache_control: ephemeral markers and the caching beta header are added automatically to the system prompt and tools.
- OpenAI / OpenAI-compatible — OpenAI caches automatically server-side. OpenRouter caches by default too — OpenCrabs enables it automatically, so there’s no flag to discover; set
cache_enabled = false only if you specifically want to opt out.
- Qwen / Alibaba — auto-enabled, zero-config (detected by endpoint or a
qwen- model name; unlocks Alibaba’s explicit context cache, ~90% off on hits). See the Qwen note further below.
- Xiaomi (MiMo) — caches automatically server-side; nothing to configure.
[providers.openrouter]
enabled = true
# Caching is ON by default — uncomment only to opt out:
# cache_enabled = false
About the TTL — it’s system-controlled. The prompt-prefix caching that drives that ~87% (Anthropic native, Qwen/Alibaba, Xiaomi) uses a provider-fixed 5-minute TTL that OpenCrabs does not expose — you can’t change it, and you don’t need to. It renews on every cache hit, so in an active session each message keeps the prefix warm and it survives the whole session, however long, as long as you’re not idle for more than 5 minutes; only an idle gap longer than that expires it, and the next message simply re-creates it once. The short TTL is the safeguard: a long TTL would keep the cache alive on the provider’s servers during idle time, which you pay to keep stored — exactly how caching bills run away (an idle cache left alive for days can rack up serious charges). Keeping it fixed protects everyone, especially non-technical users, by default.
The one user-settable TTL is cache_ttl (default 300s, range 1-86400), which sets OpenRouter’s cache TTL via the X-OpenRouter-Cache-TTL header. OpenRouter caching is on by default with this conservative 300s; it does not touch the prompt-prefix caches above. Leave it at the default unless you specifically understand the cost tradeoff of a longer TTL (a longer one keeps the cache alive longer at standing cost).
Changing provider settings: edit the file, or just ask
vision_model, context_window, provider keys, allowlists — any setting — can be changed two ways, and neither needs a restart:
- Edit
config.toml / keys.toml directly. A file watcher hot-reloads on save, so the running TUI and the headless daemon both pick the change up on the next message — provider swap, tool re-registration, context budget, commands, and skills all update live.
- Ask OpenCrabs in natural language — e.g. “set my context window to 1M”, “use mimo-v2-omni for vision on xiaomi”, “add my OpenRouter key”. It writes the change through the
config_manager tool (write_config), and if the automatic hot-reload doesn’t pick the save up for any reason, it can run config_manager reload to force a fresh load from disk on the spot.
Messaging Integrations
| Feature |
Description |
| Telegram Bot |
Full-featured Telegram bot — owner DMs share TUI session, groups get isolated per-group sessions (keyed by chat ID). Photo/voice support (STT transcribes incoming voice notes; TTS replies as OGG/Opus voice notes via send_voice when input was audio). Allowed user IDs, allowed chat/group IDs, respond_to filter (all/dm_only/mention). Passive group message capture — all messages stored for context even when bot isn’t mentioned |
| WhatsApp |
Connect via QR code pairing at runtime or from onboarding wizard. Text + image + voice (STT transcribes incoming voice notes; TTS replies as voice notes when input was audio and tts_enabled=true). Shared session with TUI, phone allowlist (allowed_phones), session persists across restarts |
| Discord |
Full Discord bot — text + image + voice. Owner DMs share TUI session, guild channels get isolated per-channel sessions. Allowed user IDs, allowed channel IDs, respond_to filter. Full proactive control via discord_send (17 actions): send, reply, react, unreact, edit, delete, pin, unpin, create_thread, send_embed, get_messages, list_channels, add_role, remove_role, kick, ban, send_file. Generated images sent as native Discord file attachments |
| Slack |
Full Slack bot via Socket Mode — owner DMs share TUI session, channels get isolated per-channel sessions. Text + image + voice (STT transcribes incoming audio attachments; TTS replies upload an OGG/Opus audio file via files.upload — renders inline with waveform UI — when input was audio and tts_enabled=true). Allowed user IDs, allowed channel IDs, respond_to filter. Full proactive control via slack_send (17 actions): send, reply, react, unreact, edit, delete, pin, unpin, get_messages, get_channel, list_channels, get_user, list_members, kick_user, set_topic, send_blocks, send_file. Generated images sent as native Slack file uploads. Bot token + app token from api.slack.com/apps (Socket Mode required). Required Bot Token Scopes: chat:write, channels:history, groups:history, im:history, mpim:history, users:read, files:read, files:write, reactions:write, app_mentions:read |
| Trello |
Tool-only by default — the AI acts on Trello only when explicitly asked via trello_send. Opt-in polling via poll_interval_secs in config; when enabled, only @bot_username mentions from allowed users trigger a response. Full card management via trello_send (22 actions): add_comment, create_card, move_card, find_cards, list_boards, get_card, get_card_comments, update_card, archive_card, add_member_to_card, remove_member_from_card, add_label_to_card, remove_label_from_card, add_checklist, add_checklist_item, complete_checklist_item, list_lists, get_board_members, search, get_notifications, mark_notifications_read, add_attachment. API Key + Token from trello.com/power-ups/admin, board IDs and member-ID allowlist configurable |
When users send files, images, or documents across any channel, the agent receives the content automatically — no manual forwarding needed. Example: a user uploads a dashboard screenshot to a Trello card with the comment “I’m seeing this error” — the agent fetches the attachment, passes it through the vision pipeline, and responds with full context.
| Channel |
Images (in) |
Text files (in) |
Documents (in) |
Audio (in) |
Audio reply (out) |
Image gen (out) |
| Telegram |
✅ vision pipeline |
✅ extracted inline |
✅ / PDF note |
✅ STT |
✅ TTS via send_voice (OGG/Opus) |
✅ native photo |
| WhatsApp |
✅ vision pipeline |
✅ extracted inline |
✅ / PDF note |
✅ STT |
✅ TTS via upload + audio_message (OGG/Opus, ptt=true) |
✅ native image |
| Discord |
✅ vision pipeline |
✅ extracted inline |
✅ / PDF note |
✅ STT |
✅ TTS as response.ogg attachment |
✅ file attachment |
| Slack |
✅ vision pipeline |
✅ extracted inline |
✅ / PDF note |
✅ STT |
✅ TTS via files.upload (OGG/Opus, inline waveform) |
✅ file upload |
| Trello |
✅ card attachments → vision |
✅ extracted inline |
— |
— |
— |
✅ card attachment + embed |
| TUI |
✅ paste path → vision |
✅ paste path → inline |
— |
✅ STT |
— (terminal has no native audio) |
✅ [IMG: name] display |
Images are passed to the active model’s vision pipeline if it supports multimodal input, or routed to the analyze_image tool (Google Gemini vision) otherwise. Text files (.txt, .md, .json, .csv, source code, etc.) are extracted as UTF-8 and included inline up to 8 000 characters — in the TUI simply paste or type the file path.
Videos uploaded on any channel (mp4, m4v, mov, webm, mkv, avi, 3gp, flv) auto-route to analyze_video when image.vision.enabled = true with a Gemini API key. The TUI also detects pasted video paths and labels them Video #N in the attachment indicator. Provider-side limits to keep in mind: Gemini’s inline-bytes mode caps at ~20 MB (we use ≤18 MB), and the resumable Files API supports up to 2 GB / ~1 hour videos. Channel-side limits are tighter — Telegram’s Bot API hard-caps getFile downloads at 20 MB even though chats accept larger uploads, so videos over that size will get a friendly “compress to under 20 MB and resend” reply. Slack file downloads use the bot token (files:read scope) and inherit the workspace’s per-file upload cap. Frame-extraction fallback for non-Gemini providers is not yet wired — without a Gemini key, video uploads return an “unsupported” notice.
When a Telegram reply carries structured Markdown (tables, headings, lists, - [ ] task lists, fenced code, or math), OpenCrabs renders it natively using Telegram’s rich messages (Bot API 10.1) instead of plain text or basic HTML. Tables come out as real tables, headings as real section headings, and task items as checkboxes. This is automatic, with no configuration or toggle to enable.
It applies to the agent’s streamed reply (only the final completed message is converted, so live token streaming stays smooth) and to proactive telegram_send messages. Plain-prose replies are left exactly as before, so incidental characters like a stray * or # are never reinterpreted. If the rich API is unavailable for any reason, OpenCrabs falls back silently to its HTML formatting, so a message is never dropped.
Terminal UI
| Feature |
Description |
| Cursor Navigation |
Full cursor movement: Left/Right arrows, Ctrl+Left/Right word jump, Home/End, Delete, Backspace at position |
| Input History |
Persistent command history (~/.opencrabs/history.txt), loaded on startup, capped at 500 entries |
| Inline Tool Approval |
Claude Code-style ❯ Yes / Always / No selector with arrow key navigation |
| Inline Plan Approval |
Interactive plan review selector (Approve / Reject / Request Changes / View Plan) |
| Session Management |
Create, rename, delete sessions with persistent SQLite storage; each session remembers its provider + model — switching sessions auto-restores the provider (no manual /models needed); token counts and context % per session. New sessions auto-generate a meaningful title from the first user message (no more “New Chat”) |
| Split Panes |
Horizontal (| in sessions) and vertical (_ in sessions) pane splitting — tmux-style. Each pane runs its own session with independent provider, model, and context. Run 10 sessions side by side, all processing in parallel. Tab to cycle focus, Ctrl+X to close pane |
| Parallel Sessions |
Multiple sessions can have in-flight requests to different providers simultaneously. Send a message in one session, switch to another, send another — both process in parallel. Background sessions auto-approve tool calls; you’ll see results when you switch back |
| Scroll While Streaming |
Scroll up during streaming without being yanked back to bottom; auto-scroll re-enables when you scroll back down or send a message |
| Path Normalization |
Home paths (/home/user/...) automatically collapsed to ~ in system prompt, tool call display, and brain files — keeps context lean and readable |
| Recent File Memory |
Agent remembers recently accessed file paths across sessions — no need to re-specify paths you were just working on |
| Compaction Summary |
Auto-compaction shows the full summary in chat as a system message — see exactly what the agent remembered |
| Syntax Highlighting |
100+ languages with line numbers via syntect |
| Markdown Rendering |
Rich text formatting with code blocks, headings, lists, and inline styles |
| Tool Context Persistence |
Tool call groups saved to DB and reconstructed on session reload — no vanishing tool history |
| Multi-line Input |
Alt+Enter / Shift+Enter for newlines; Enter to send |
| Abort Processing |
Escape×2 within 3 seconds to cancel any in-progress request |
| Clipboard Image Paste |
Copy an image from a browser, screenshot tool, or any app and paste it directly into the input. Raw image bytes are read from the OS clipboard (macOS: osascript, Linux: wl-paste/xclip), written to a temp file, and attached through the existing image pipeline. No need to save to disk first |
Bang Operator (!cmd) |
Run any shell command directly from the input — no LLM round-trip. Output is shown as a system message in the working directory context |
| Auto-Update |
Checks GitHub for new releases on startup and once every 24h in the background. When a new version is found it silently installs and hot-restarts. Disable via [agent] auto_update = false in config.toml to be prompted instead |
Agent Capabilities
| Feature |
Description |
| Full Terminal Access |
30+ built-in tools (file I/O, glob, grep, web search, code execution, image gen/analysis, memory search, cron jobs) plus any CLI tool on your system via bash — GitHub CLI, Docker, SSH, Python, Node, ffmpeg, curl, and everything else just work |
| RTK Token Savings |
Automatic bash output optimization via RTK integration — enabled by default, zero config. Prepends rtk to supported commands (git, cargo, npm, pnpm, yarn, docker, kubectl, grep, find, ls, tree, curl, and 100+ more) to filter noise from command output. Reduces token usage on bash commands by 60-90% without losing critical information. Check savings with /rtk command. RTK binary bundled with prebuilt OpenCrabs releases and installed by /evolve on update; if it is ever missing, OpenCrabs auto-downloads the right binary for your platform on first use |
| Per-Session Isolation |
Each session is an independent agent with its own provider, model, context, and tool state. Sessions can run tasks in parallel against different providers — ask Claude a question in one session while Kimi works on code in another |
| Self-Healing |
Detects and recovers from phantom tool calls, gaslighting preambles, text repetition loops, XML tool call failures, and provider errors. Short-circuits repeated failing bash commands and rejects interactive commands that would hang. Automatic context compaction at 65% (soft) and 90% (hard). Sticky fallback promotion when primary recovers |
| Self-Sustaining |
Agent can modify its own source, build, test, and hot-restart via Unix exec() |
| Self-Improving |
Learns from experience — saves reusable workflows as custom commands, writes lessons learned to memory, updates its own brain files. All local, no data leaves your machine |
| Dynamic Tools |
Define custom tools at runtime via ~/.opencrabs/tools.toml — the agent can call them autonomously like built-in tools. HTTP and shell executors, template parameters ({{param}}), enable/disable without restart. The tool_manage meta-tool lets the agent create, remove, and reload tools on the fly |
| Skills (cross-harness) |
Multi-stage workflow templates in the de-facto SKILL.md format used by Claude Code, Anthropic managed agents, and OpenClaw. Drop a SKILL.md under ~/.opencrabs/skills/<name>/ and it auto-registers as /<name> — no commands.toml entry needed. Works in the TUI and every connected channel (Telegram, Discord, Slack, WhatsApp). Built-ins ship with the binary (always version-matched); user skills override by file presence. Two built-ins out of the box: /security-audit (language-agnostic CVE & static-analysis audit, scores 0-100) and /cost-estimate (codebase valuation with AI-assisted ROI). Same SKILL.md is portable across harnesses |
| Mission Control |
Full-screen /mission-control dialog showing every actionable artifact in one place: pending RSI proposals (inbox cards), recent RSI activity (improvements log feed), the schedule queue (cron jobs + paused/active state), and a live Analytics panel (brain file sizes, tool usage with proportional bars, failure rates, RSI applied by dimension). Apply or reject inbox proposals inline with a / r — same machinery as the agent’s rsi_proposals tool, byte-identical install. Tab between panels, j/k to navigate, Enter for the detail popup, Esc to close. Cron paused jobs flag in orange, active in teal — at-a-glance state |
| Skills picker |
Full-screen /skills dialog with a live filter input — start typing to narrow the list (case-insensitive on name + description), Tab / Shift-Tab cycle the filtered cards (wraps at the edges), Enter runs the selected skill (sends its body as a prompt to the agent), Esc closes. Built-in skills badge orange; user-installed skills badge teal. When the filter narrows to a single match, Enter just fires it — fastest path to launch a skill |
| Browser Automation |
Native browser control via CDP (Chrome DevTools Protocol). Auto-detects your default Chromium-based browser (Chrome, Brave, Edge, Arc, Vivaldi, Opera, Chromium) and uses its profile — your logins, cookies, and extensions carry over. 7 browser tools: navigate, click, type, screenshot, eval JS, extract content, wait for elements. Headed or headless mode with display auto-detection. Note: Firefox is not supported (no CDP) — if Firefox is your default, OpenCrabs falls back to the first available Chromium browser. Feature-gated under browser (included by default) |
| Natural Language Commands |
Tell OpenCrabs to create slash commands — it writes them to commands.toml autonomously via the config_manager tool |
| Live Settings |
Agent can read/write config.toml at runtime; Settings TUI screen (press S) shows current config; approval policy persists across restarts. Default: auto-approve (use /approve to change) |
| Web Search |
DuckDuckGo (built-in, no key needed) + EXA AI (neural, free via MCP) by default; Brave Search optional (key in keys.toml) |
| Debug Logging |
--debug flag enables file logging; DEBUG_LOGS_LOCATION env var for custom log directory |
| Agent-to-Agent (A2A) |
HTTP gateway implementing A2A Protocol RC v1.0 — peer-to-peer agent communication via JSON-RPC 2.0. Supports message/send, message/stream (SSE), tasks/get, tasks/cancel. Built-in a2a_send tool lets the agent proactively call remote A2A agents. Optional Bearer token auth. Includes multi-agent debate (Bee Colony) with confidence-weighted consensus. Task persistence across restarts |
| Profiles |
Run multiple isolated instances from the same installation. Each profile gets its own config, keys, memory, sessions, and database. Create with opencrabs profile create <name>, switch with -p <name>. Migrate config between profiles with profile migrate. Export/import for sharing. Token-lock isolation prevents two profiles from using the same bot credential |
CLI
| Command |
Description |
opencrabs |
Launch interactive TUI (default) |
opencrabs chat |
Launch TUI with optional --session <id> to resume, --onboard to force wizard |
opencrabs run <prompt> |
Execute a single prompt non-interactively. --auto-approve / --yolo for unattended. --format text|json|markdown |
opencrabs agent |
Interactive CLI agent — multi-turn conversation in your terminal, no TUI. -m <msg> for single-message mode |
opencrabs status |
System overview: version, provider, channels, database, brain, cron, dynamic tools |
opencrabs doctor |
Full diagnostics: config, provider connectivity, database, brain, channels, CLI tools in PATH |
opencrabs init |
Initialize configuration (--force to overwrite) |
opencrabs config |
Show current configuration (--show-secrets to reveal keys) |
opencrabs onboard |
Run the onboarding setup wizard |
opencrabs channel list |
List all configured channels with enabled/disabled status |
opencrabs channel doctor |
Run health checks on all enabled channels |
opencrabs memory list |
List brain files and memory entries |
opencrabs memory get <name> |
Show contents of a specific memory or brain file |
opencrabs memory stats |
Memory statistics: file count, total size, entry count |
opencrabs session list |
List all sessions with provider, model, token count (--all includes archived) |
opencrabs session get <id> |
Show session details and recent messages |
opencrabs db init |
Initialize database |
opencrabs db stats |
Show database statistics |
opencrabs db clear |
Clear all sessions and messages (--force to skip confirmation) |
opencrabs cron add|list|remove|enable|disable|test |
Manage scheduled cron jobs |
opencrabs logs status|view|clean|open |
Log management |
opencrabs service install|start|stop|restart|status|uninstall |
OS service management (launchd on macOS, systemd on Linux) |
opencrabs daemon |
Run in headless daemon mode — channels only, no TUI |
opencrabs completions <shell> |
Generate shell completions (bash, zsh, fish, powershell) |
opencrabs migrate <source> |
Migrate from OpenClaw or Hermes. Scans the system, shows interactive picker, spawns agent to handle migration. --dry-run to preview |
opencrabs version |
Print version and exit |
Global flags: --debug (enable file logging), --config <path> (custom config file), --profile <name> / -p <name> (run as a named profile).
Profiles — Multi-Instance Crab Agents
Run multiple isolated OpenCrabs instances from the same installation. Each profile gets its own config, brain files, memory, sessions, database, and gateway service.
| Command |
Description |
opencrabs profile create <name> |
Create a new profile with fresh config and brain files |
opencrabs profile list |
List all profiles with last-used timestamps |
opencrabs profile delete <name> |
Delete a profile and all its data |
opencrabs profile export <name> -o profile.tar.gz |
Export a profile as a portable archive |
opencrabs profile import profile.tar.gz |
Import a profile from an archive |
opencrabs profile migrate --from <name> --to <name> |
Copy config and brain files between profiles (no DB or sessions) |
opencrabs -p <name> |
Launch OpenCrabs as the specified profile |
Default profile: ~/.opencrabs/ — works exactly as before. No migration needed. Users who never touch profiles see zero difference.
TUI footer: when you launch with -p <name> (or OPENCRABS_PROFILE set), the bottom status bar adds a profile: <name> chip so multi-profile users can tell at a glance which instance a given pane is bound to. Without -p, no chip is shown — the agent is using the base ~/.opencrabs/ directory and there is no real profile by that name to label.
Named profiles live at ~/.opencrabs/profiles/<name>/ with full isolation:
~/.opencrabs/
├── config.toml # default profile
├── opencrabs.db
├── profiles.toml # profile registry
├── locks/ # token-lock files
└── profiles/
├── hermes/ # named profile
│ ├── config.toml
│ ├── keys.toml
│ ├── opencrabs.db
│ ├── SOUL.md
│ └── memory/
└── scout/
└── ...
Token-lock isolation: Two profiles cannot use the same bot credential (Telegram token, Discord token, etc.). On startup, each profile acquires a lock on its channel tokens. If another profile already holds the lock, the channel refuses to start — preventing two instances from fighting over the same bot.
Profile migration: Use opencrabs profile migrate --from default --to hermes to copy all .md brain files, .toml config files, and memory/ entries to a new profile. Sessions and database are not copied — the new profile starts clean. Add --force to overwrite existing files in the target profile. After migrating, customize the new profile’s SOUL.md, IDENTITY.md, and config.toml to give it a different personality and provider setup.
Daemon & Service
Run profiles as background services:
# Install as system service (macOS launchd / Linux systemd)
opencrabs -p hermes service install
opencrabs -p hermes service start
# Each profile gets its own service
# macOS: com.opencrabs.daemon.hermes
# Linux: opencrabs-hermes.service
# Manage independently
opencrabs -p hermes service status
opencrabs -p hermes service stop
opencrabs -p hermes service uninstall
Multiple profiles can run as simultaneous daemon services with full isolation.
Environment variable: Set OPENCRABS_PROFILE=hermes to select a profile without the -p flag. Useful for systemd services, cron jobs, and daemon mode.
Troubleshooting — daemon stays down after a restart: the daemon is meant to auto-recover (Linux Restart=always, macOS KeepAlive). If you installed the service on an older build, its unit file may still use Restart=on-failure, which does not restart after a clean exit and can leave the daemon down. Re-generate the unit with opencrabs -p <name> service install (then service start) to pick up the always-restart policy. Config, keys, commands, and tools hot-reload at runtime, so editing ~/.opencrabs/config.toml (or keys.toml) never needs a daemon restart — if a change isn’t taking effect, check the logs for a ConfigWatcher: reloaded line rather than restarting.
Switching to OpenCrabs from another AI agent tool? There are two ways to do it.
Option 1: CLI Command (automated)
The migrate command scans your system for existing tool instances, shows an interactive picker if it finds multiple, then spawns an agent to handle the actual migration:
# Migrate from OpenClaw
opencrabs migrate openclaw
# Migrate from Hermes
opencrabs migrate hermes
# Preview what would be migrated without making changes
opencrabs migrate openclaw --dry-run
What it migrates:
The agent reads each source file, maps it to OpenCrabs format, and writes the result. If a brain file already has content, it merges rather than overwrites. After the agent finishes, a verification summary shows exactly which files were created, updated, or left unchanged.
Use -p <name> to migrate into a specific profile instead of the default:
opencrabs -p my-openclaw-setup migrate openclaw
Option 2: Just Ask the Agent
No CLI command needed. Once OpenCrabs is running, tell it:
“I’m migrating from [tool name]. Research what files I have, audit the config structure, and report what I need to move over for a seamless migration.”
The agent will use its tools (read_file, web_search, grep) to inspect the source tool’s directory, understand the config format, and either do the migration directly or give you a step-by-step plan. This works for any tool, not just OpenClaw and Hermes. Claude Code, Cursor, Aider, Windsurf, whatever. If it has config files and brain/personality files, OpenCrabs can figure out the mapping.
The agent-native approach handles edge cases that hardcoded parsers can’t: custom configs, non-standard setups, partial installations, format changes across versions.
Supported Sources
| Source |
Directory |
Config Format |
Status |
| OpenClaw |
~/.openclaw/ |
JSON5 (openclaw.json) |
CLI + agent |
| Hermes |
~/.hermes/ |
YAML (config.yaml) + .env |
CLI + agent |
| Claude Code |
~/.claude/ |
JSON |
Agent only |
| Anything else |
varies |
varies |
Agent only |
The CLI migrate command currently supports OpenClaw and Hermes. For everything else, the agent handles it via chat. Both approaches use the same underlying mechanism: read source files, map to OpenCrabs format, write the result.
🌐 Supported AI Providers
| Provider |
Auth |
Models |
Streaming |
Tools |
Notes |
| Xiaomi ⭐ |
Free, no key* |
mimo-v2.5-pro (1M ctx), v2-pro, v2.5, omni, flash |
✅ |
✅ |
Default provider. opencrabs × Xiaomi collab — free inference, no API key needed during the launch window (until 2026-06-25). New users land almost straight in chat |
| Anthropic Claude |
API key |
Claude Opus 4.6, Sonnet 4.5, Haiku 4.5+ |
✅ |
✅ |
Cost tracking, automatic retry |
| OpenAI |
API key |
GPT-5 Turbo, GPT-5 |
✅ |
✅ |
|
| GitHub Copilot |
OAuth |
GPT-4o, Claude Sonnet 4+ |
✅ |
✅ |
Uses your Copilot subscription — no API charges |
| OpenRouter |
API key |
400+ models |
✅ |
✅ |
Free models available (DeepSeek-R1, Llama 3.3, etc.) |
| Google Gemini |
API key |
Gemini 2.5 Flash, 2.0, 1.5 Pro |
✅ |
✅ |
1M+ context, vision, image generation |
| MiniMax |
API key |
M2.7, M2.5, M2.1, Text-01 |
✅ |
✅ |
Competitive pricing, auto-configured vision |
| z.ai GLM |
API key |
GLM-4.5 through GLM-5 Turbo |
✅ |
✅ |
General API + Coding API endpoints |
| Claude CLI |
CLI auth |
Via claude binary |
✅ |
✅ |
Uses your Claude Code subscription |
| OpenCode CLI |
None |
Free models (Mimo, etc.) |
✅ |
✅ |
Free — no API key or subscription needed |
| Codex CLI |
CLI auth |
GPT-5.5, 5.4, 5.4-mini, 5.3-codex |
✅ |
✅ |
Uses your ChatGPT/Codex subscription |
| Qwen (Native) |
OAuth |
Qwen3.6-Plus, Qwen3.5-Plus, Qwen3-Max |
✅ |
✅ |
Free tier (60 req/min, 1k/day). Multi-account rotation multiplies quota |
| Qwen Code CLI |
OAuth / API key |
Qwen3-Coder-Plus, Qwen3.5-Plus, Qwen3.6-Plus |
✅ |
✅ |
1k free req/day via Qwen OAuth — no API key needed |
| Ollama |
Optional |
Any pulled model |
✅ |
✅ |
Local-first, zero API cost. Auto-detects localhost:11434 |
| Custom |
Optional |
Any |
✅ |
✅ |
LM Studio, Groq, NVIDIA, any OpenAI-compatible API |
Anthropic Claude
Models: claude-opus-4-6, claude-sonnet-4-5-20250929, claude-haiku-4-5-20251001, plus legacy Claude 3.x models
Setup in keys.toml:
[providers.anthropic]
api_key = "sk-ant-api03-YOUR_KEY"
OAuth tokens no longer supported. Anthropic disabled OAuth (sk-ant-oat) for third-party apps as of Feb 2026. Only console API keys (sk-ant-api03-*) work. See anthropics/claude-code#28091.
Features: Streaming, tools, cost tracking, automatic retry with backoff
Claude Code CLI
Use your Claude Code CLI. OpenCrabs spawns the local claude CLI for completion.
Setup:
- Install Claude Code CLI and authenticate (
claude login)
- Enable in
config.toml:
[providers.claude_cli]
enabled = true
OpenCrabs handles all tools, memory, and context locally — the CLI is just the LLM backend.
OpenAI
Models: GPT-5 Turbo, GPT-5
Setup in keys.toml:
[providers.openai]
api_key = "sk-YOUR_KEY"
GitHub Copilot
Use your GitHub Copilot subscription — no API charges, no tokens to manage. OpenCrabs authenticates via the same OAuth device flow used by VS Code and other Copilot tools.
Setup — select GitHub Copilot in the onboarding wizard and press Enter. You’ll see a one-time code to enter at github.com/login/device. Once authorized, models are fetched from the Copilot API automatically.
Requirements: An active GitHub Copilot subscription (Individual, Business, or Enterprise).
Manual config (without wizard)
The OAuth token is saved automatically during onboarding. If you need to re-authenticate, run /onboard:provider and select GitHub Copilot.
Enable in config.toml:
[providers.github]
enabled = true
default_model = "gpt-4o"
base_url = "https://api.githubcopilot.com/chat/completions"
Features: Streaming, tools, OpenAI-compatible API at api.githubcopilot.com. Copilot-specific headers (copilot-integration-id, editor-version) are injected automatically. Short-lived API tokens are refreshed in the background every ~25 minutes.
OpenRouter — 400+ Models, One Key
Setup in keys.toml — get a key at openrouter.ai/keys:
[providers.openrouter]
api_key = "sk-or-YOUR_KEY"
Access 400+ models from every major provider through a single API key — Anthropic, OpenAI, Google, Meta, Mistral, DeepSeek, Qwen, and many more. Includes free models (DeepSeek-R1, Llama 3.3, Gemma 2, Mistral 7B) and stealth/preview models as they drop.
Model list is fetched live from the OpenRouter API during onboarding and via /models — no binary update needed when new models are added.
Google Gemini
Models: gemini-2.5-flash, gemini-2.0-flash, gemini-1.5-pro — fetched live from the Gemini API
Setup in keys.toml — get a key at aistudio.google.com:
[providers.gemini]
api_key = "AIza..."
Enable and set default model in config.toml:
[providers.gemini]
enabled = true
default_model = "gemini-2.5-flash"
Features: Streaming, tool use, vision, 1M+ token context window, live model list from /models endpoint
Image & video generation & vision: Gemini also powers the separate [image] section for generate_image, analyze_image, and analyze_video agent tools. See Image Generation & Vision below.
MiniMax
Models: MiniMax-M2.7, MiniMax-M2.5, MiniMax-M2.1, MiniMax-Text-01
Setup — get your API key from platform.minimax.io. Add to keys.toml:
[providers.minimax]
api_key = "your-api-key"
MiniMax is an OpenAI-compatible provider with competitive pricing. It does not expose a /models endpoint, so the model list comes from config.toml (pre-configured with available models).
Models: glm-4.5, glm-4.5-air, glm-4.6, glm-4.7, glm-5, glm-5-turbo — fetched live from the z.ai API
Setup — get your API key from open.bigmodel.cn. Add to keys.toml:
[providers.zhipu]
api_key = "your-api-key"
Enable and choose endpoint type in config.toml:
[providers.zhipu]
enabled = true
default_model = "glm-4.7"
endpoint_type = "api" # "api" (General API) or "coding" (Coding API)
z.ai GLM (Zhipu AI) offers two endpoint types selectable during onboarding or via /models:
- General API (
api) — standard chat completions at open.bigmodel.cn/api/paas/v4
- Coding API (
coding) — code-optimized endpoint at codeapi.bigmodel.cn/api/paas/v4
Both use the same API key and model names. The endpoint type can be toggled in the onboarding wizard or /models dialog.
Features: Streaming, tools, OpenAI-compatible API, live model list from /models endpoint
OpenCode CLI
Use the OpenCode CLI as a free LLM backend — no API key or subscription needed. OpenCrabs spawns the local opencode binary for completions.
Setup:
- Install OpenCode CLI (
go install github.com/opencode-ai/opencode@latest or download from releases)
- Enable in
config.toml:
[providers.opencode_cli]
enabled = true
default_model = "opencode/mimo-v2-pro-free"
Models are fetched live from opencode models. Free models like mimo-v2-pro-free work without any authentication.
Features: Streaming, tools, extended thinking support, NDJSON event protocol
Codex CLI
Use your ChatGPT/Codex subscription — no API key, no API charges. OpenCrabs spawns the local codex binary for completions and piggybacks on the auth stored in ~/.codex/auth.json.
Setup:
- Install Codex CLI:
npm install -g @openai/codex
- Run
codex once and sign in with your ChatGPT account (or paste an API key).
- Enable in
config.toml:
[providers.codex_cli]
enabled = true
default_model = "gpt-5.5" # falls back to gpt-5.4 if 5.5 isn't in your account yet
Models (per developers.openai.com/codex/models):
gpt-5.5 — newest frontier model (ChatGPT-auth only during rollout)
gpt-5.4 — recommended fallback when 5.5 isn’t available; supports API access
gpt-5.4-mini — fast, lower-cost option for lighter coding work
gpt-5.3-codex — coding-optimized model that powers GPT-5.4 underneath
gpt-5.3-codex-spark — research preview for ChatGPT Pro (real-time iteration)
gpt-5.2 — alternative tier for hard debugging
OpenCrabs handles all tools, memory, and context locally; codex is just the LLM backend. The CLI runs codex exec --json --ephemeral --dangerously-bypass-approvals-and-sandbox so each turn is a fresh session driven by OpenCrabs’ conversation state.
Features: Streaming, tools (codex executes its own shell commands and they’re surfaced to the TUI for display), JSONL event protocol
Qwen (Native)
Direct integration with Qwen’s API via OAuth device flow — no API key needed. Free tier gives 60 req/min and 1,000 req/day per account.
Setup: Select Qwen in /onboard or /models and follow the browser OAuth flow.
Multi-account rotation: Multiply your free quota by authenticating multiple Qwen accounts. When one account hits rate limits, OpenCrabs automatically rotates to the next — only falling to the fallback provider when all accounts are exhausted.
To enable rotation during setup:
- Select Qwen in
/onboard or /models
- Press
Space to toggle rotation
- Press
2-9 to set the number of accounts (1 = 10)
- Press
Enter — authenticate each account in sequence (sign out in your browser between accounts)
Adding more accounts later (e.g. 3→5) is incremental — only the new accounts need authentication. Configured providers show a green ✓ in the provider list.
Rotation accounts are stored in keys.toml:
[[providers.qwen_accounts]]
api_key = "..."
refresh_token = "..."
expiry_date = 1234567890
resource_url = "portal.qwen.ai"
[[providers.qwen_accounts]]
api_key = "..."
refresh_token = "..."
expiry_date = 1234567891
resource_url = "portal.qwen.ai"
With 3 accounts you get 180 req/min and 3,000 req/day before fallback kicks in.
Qwen Code CLI
Use the Qwen Code CLI as a free LLM backend — 1,000 free requests/day via Qwen OAuth. OpenCrabs spawns the local qwen binary for completions.
Setup:
- Install Qwen Code CLI (
npm install -g @qwen-code/qwen-code or brew install qwen-code)
- Authenticate: run
qwen and follow the OAuth flow (or set DASHSCOPE_API_KEY for API key auth)
- Enable in
config.toml:
[providers.qwen_code_cli]
enabled = true
default_model = "qwen3-coder-plus"
Available models: qwen3-coder-plus, qwen3.5-plus, qwen3.6-plus, qwen3-coder-480a35, qwen3-coder-30ba3b, qwen3-max-2026-01-23
Features: Streaming, tools, 256K context window, NDJSON event protocol (Gemini CLI fork)
Ollama
Native built-in provider for Ollama — no custom config needed. OpenCrabs auto-detects localhost:11434 and lists your pulled models via /models.
Setup:
- Install Ollama and pull a model:
ollama pull qwen2.5-coder:7b
- Enable in
config.toml:
[providers.ollama]
enabled = true
default_model = "qwen2.5-coder:7b"
Features: Streaming, tools, zero API cost, local-first. Optional api_key for cloud Ollama (api.ollama.com). Models fetched live from Ollama API.
Custom (OpenAI-Compatible)
Use for: LM Studio, Groq, or any OpenAI-compatible API.
Setup in config.toml — every custom provider needs a name (the label after custom.):
[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1" # or your endpoint
default_model = "qwen2.5-coder-7b-instruct"
# Optional: list your available models — shows up in /models and /onboard
# so you can switch between them without editing config
models = ["qwen2.5-coder-7b-instruct", "llama-3-8B", "mistral-7B-instruct"]
Local LLMs (Ollama, LM Studio): No API key needed — just set base_url and default_model.
Remote APIs (Groq, Together, etc.): Add the key in keys.toml using the same name:
[providers.custom.groq]
api_key = "your-api-key"
Note: /chat/completions is auto-appended to base URLs that don’t include it.
Local reasoning models (enable_thinking): when a custom provider’s base_url points at a local host (localhost, 127.0.0.1, *.local, or an RFC1918 private IP like 192.168.x.x / 10.x.x.x / 172.16.x.x–172.31.x.x), OpenCrabs injects chat_template_kwargs: {"enable_thinking": true} into every request. This mirrors llama-server --jinja --chat-template-kwargs '{"enable_thinking":true}' — what Unsloth Studio launches with by default — so Qwen3 / Kimi / DeepSeek-R1 templates render <tool_call> tags and reasoning blocks correctly, and tool calls actually execute instead of being hallucinated as text. Set enable_thinking = false in the provider block to disable (falls back to fast, non-thinking mode). Cloud providers are unaffected.
[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen3-30b-a3b"
enable_thinking = false # optional — default is true for local providers
Qwen / Alibaba cache (zero-config): when a custom provider’s base_url points at a known Qwen / Alibaba endpoint (dashscope.aliyuncs.com, dashscope-intl.aliyuncs.com, aliyun.com, dialagram.me) or the request model name starts with qwen-, OpenCrabs auto-injects cache_control: {"type": "ephemeral"} markers on the system message, the last message (streaming), and the last tool definition. This unlocks Alibaba’s explicit context cache — cache hits bill input tokens at 10% of the standard price (≈90% off), with a 25% surcharge on first creation and a 5-minute TTL auto-renewed on every hit. The detection runs per-request so a provider routing between Qwen and non-Qwen models only marks the Qwen ones. Non-Qwen backends ignore the marker (it’s an unknown JSON field), so the only cost on a mismatch is a few wasted bytes per request.
[providers.custom.dashscope]
enabled = true
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
default_model = "qwen3-max"
# No cache flags needed — auto-enabled on URL match.
Multiple custom providers coexist — define as many as you need with different names and switch between them via /models:
[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen2.5-coder-7b-instruct"
[providers.custom.ollama]
enabled = false
base_url = "http://localhost:11434/v1"
default_model = "mistral"
The name after custom. is a label you choose (e.g. lm_studio, nvidia, groq). The one with enabled = true is active. Keys go in keys.toml using the same label. All configured custom providers persist — switching via /models just toggles enabled.
Free Prototyping with NVIDIA API + Kimi K2.5
Kimi K2.5 is a frontier-scale multimodal Mixture-of-Experts (MoE) model available for free on the NVIDIA API Catalog — no billing setup or credit card required. It handles complex reasoning and image/video understanding, making it a strong free alternative to paid models like Claude or Gemini for experimentation and agentic workflows.
Tested and verified with OpenCrabs Custom provider setup.
Quick start:
- Sign up at the NVIDIA API Catalog and verify your account
- Go to the Kimi K2.5 model page and click Get API Key (or “View Code” to see an auto-generated key)
- Configure in OpenCrabs via
/models or config.toml:
[providers.custom.nvidia]
enabled = true
base_url = "https://integrate.api.nvidia.com/v1"
default_model = "moonshotai/kimi-k2.5"
# keys.toml
[providers.custom.nvidia]
api_key = "nvapi-..."
Provider priority: Claude CLI > OpenCode CLI > Codex CLI > OpenCode > Qwen > Anthropic > OpenAI > GitHub Copilot > Gemini > OpenRouter > MiniMax > z.ai GLM > Ollama > Custom. The first provider with enabled = true is used on new sessions. Each provider has its own API key in keys.toml — no sharing or confusion.
Per-session provider: Each session remembers which provider and model it was using. Switch to Claude in one session, Kimi in another — when you /sessions switch between them, the provider restores automatically. No need to /models every time. New sessions inherit the current provider.
Fallback Providers
If your primary provider goes down, fallback providers are tried automatically in sequence. Any provider with API keys already configured can be a fallback:
[providers.fallback]
enabled = true
providers = ["openrouter", "anthropic"] # tried in order on failure
At runtime, if
README 内容过长,已截取部分内容。完整内容请前往 GitHub 仓库查看。
评论