Two humps, zero runtime.
An unofficial, independent terminal AI coding assistant written in OCaml. Inspired by the UX patterns of modern AI CLI tools. Uses the Anthropic Messages API with your own API key.
This project is not affiliated with, endorsed by, or associated with Anthropic in any way. "Claude" is a trademark of Anthropic. This is a personal hobby project.
https://github.com/pookieclaw/camel-code/raw/main/docs/demo.mov
Version check, diagnostics, single-shot query, file write/read with tools, bash execution, file editing, and interactive REPL with slash commands.
- 14 built-in tools + dynamic MCP tools
- Prompt cache optimization — deterministic payload ordering for 90% input token savings
- Tooled subagents — Agent tool gets Read/Grep/Glob for actual codebase research
- Provider failover — automatic retry with fallback model/key on rate limits
- Lazy MCP — server connections deferred until first tool invocation
- Pre/post query hooks — run shell commands before/after each API call
- Session enrichment — sessions tagged with git repo, branch, and labels
- Daemon mode — Unix socket server for editor/web integration
- Doctor --fix — auto-repair common environment issues
- Vim mode, permissions, skills, hooks, MCP, sessions
# Open in VS Code → Reopen in Container
# Then in the devcontainer terminal:
# Set your API key
echo '{"api_key": "sk-ant-..."}' > ~/.camel/config.json
# Install the binary
dune install
# Run it
camel# Interactive REPL (like claude)
camel
# Single-shot prompt (like claude -p)
camel -p "What is OCaml?"
# Auto-approve tool execution (like claude --yes)
camel --yes
# Pick a model
camel --model claude-opus-4-20250514
# Resume last conversation
camel --continue
# Resume a specific session
camel --resume <session-id>
# Run diagnostics
camel doctor
# Auto-fix common issues (missing dirs, bad permissions, corrupt sessions)
camel doctor --fix
# Start as a background server (Unix socket for editor plugins)
camel daemon
# Show version
camel --versionInside the REPL:
| Command | Description |
|---|---|
/help |
Show available commands |
/clear |
Clear conversation history |
/cost |
Show token usage and cost |
/model |
Show or change model |
/config |
Show current settings |
/compact |
Compact conversation history |
/resume |
List and resume past sessions |
/doctor |
Run diagnostic checks |
/vim |
Toggle vim mode |
/exit |
Exit camel |
Camel Code has 14 built-in tools, matching Claude Code's core set:
| Tool | Description |
|---|---|
| Bash | Execute shell commands |
| Read | Read file contents with line numbers |
| Write | Write/create files |
| Edit | Search and replace in files |
| Glob | Find files by pattern (fff-accelerated) |
| Grep | Search file contents with regex (fff-accelerated) |
| MultiGrep | Multi-pattern OR search (fff-accelerated) |
| Agent | Spawn subagents with Read/Grep/Glob tools |
| WebFetch | Fetch URL content |
| AskUserQuestion | Prompt user for input |
| Sleep | Pause execution |
| TaskCreate | Create a task to track work |
| TaskList | List all tasks |
| TaskUpdate | Update task status |
Plus dynamic tools from MCP servers configured in ~/.camel/settings.json.
Glob, Grep, and MultiGrep can be accelerated by fff (Freakin Fast File Finder), a Rust-based fuzzy search engine with frecency ranking, typo-tolerant matching, and definition-aware grep. Enable with:
export CAMEL_FFF=1The devcontainer builds libfff_c.so automatically. When the library isn't found, tools fall back to shell (find/grep). Path and glob constraints (e.g. Grep pattern path:lib/ or Grep pattern glob:*.ml) are forwarded to fff as inline query constraints, so scoped searches stay fast. Only paths outside the project root fall back to shell. Benchmarks show ~100-200x speedup on indexed repos.
~/.camel/
config.json API key
settings.json Preferences (model, theme, vim mode, MCP servers, hooks)
keybindings.json Custom key bindings
sessions/ Saved conversation sessions
skills/ Custom skills (.md with YAML frontmatter)
Add to ~/.camel/settings.json:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["path/to/server.js"]
}
}
}Set a fallback model or API key in ~/.camel/config.json:
{
"api_key": "sk-ant-primary...",
"fallback_model": "claude-haiku-4-5-20251001",
"fallback_api_key": "sk-ant-backup..."
}Or via environment: CAMEL_FALLBACK_MODEL, CAMEL_FALLBACK_API_KEY.
On rate limits or overload, camel automatically retries with the fallback.
{
"hooks": {
"PreToolUse": [
{ "command": "./my-hook.sh", "matcher": "Bash" }
],
"PreQuery": [
{ "command": "./log-query.sh" }
],
"PostQuery": [
{ "command": "./track-usage.sh" }
]
}
}Hook events: PreToolUse, PostToolUse, PreQuery, PostQuery, SessionStart, UserPromptSubmit, Notification.
{
"permissions": {
"allow": [{ "tool": "Read" }, { "tool": "Glob" }],
"deny": [{ "tool": "Bash", "path": "/etc/*" }]
}
}Run camel as a background server that accepts JSON commands over a Unix socket:
camel daemon
# Listening on ~/.camel/daemon.sock
# From another terminal:
echo '{"method": "query", "params": {"prompt": "What is OCaml?"}}' | socat - UNIX-CONNECT:~/.camel/daemon.sock
echo '{"method": "status"}' | socat - UNIX-CONNECT:~/.camel/daemon.sock
echo '{"method": "shutdown"}' | socat - UNIX-CONNECT:~/.camel/daemon.sockMethods: query (send a prompt), status (check server), shutdown (stop daemon).
This is the foundation for editor plugins (Neovim, VS Code), web UIs, and multi-terminal shared sessions.
API request payloads are structured for maximum Anthropic prompt cache hits:
- System prompt (stable across turns) — cached prefix
- Model config (stable per session)
- Tools (sorted alphabetically, stable per session)
- Messages (changes every turn) — always last, never cached
This means the first ~90% of each request is identical turn-to-turn, so Anthropic can serve it from cache at 1/10th the input token cost.
| Layer | Approach |
|---|---|
| TUI | ANSI direct rendering |
| State | Mutable refs |
| Concurrency | Unix processes |
| Types | Algebraic data types |
| Tools | First-class modules |
| Build | dune |
| Binary | Native (zero runtime) |
# Unit + integration tests (75 tests)
dune test
# Live demo of all phase-8 features (runs tests, shows payload structure)
./scripts/demo.sh
# End-to-end with real API calls (query, tool use, daemon, sessions)
./scripts/e2e.sh
# Full developer workflow (explore → implement → debug → review → refactor)
./scripts/workflow.shThe e2e and workflow scripts require an API key in ~/.camel/config.json.
A hobby project to explore building an AI coding assistant in OCaml — leveraging algebraic data types, first-class modules, and native compilation for fast startup.
This project is not affiliated with, endorsed by, or associated with Anthropic, PBC. It is an independent, open-source project that uses the publicly documented Anthropic Messages API. "Claude" is a trademark of Anthropic. All trademarks belong to their respective owners.
MIT