A secure, self-hosted proxy that connects Telegram, WhatsApp, and Slack to your local AI CLI tools — Claude Code, Codex, and Gemini CLI.
No database. No cloud. No accounts. A single Rust binary and one YAML config file, running entirely on your machine.
Telegram ─┐ ┌─ Claude Code
WhatsApp ─┼──► SecurityGate ► Router ► Executor (local) ─┼─ Codex
Slack ─┘ │ └─ Gemini CLI
│
Formatter ► back to chat
Your prompt goes in. The model's response comes out. Your CLI tool owns its configuration and governs the agent. RustifyMyClaw never touches your commands or runs commands on your behalf. Nothing is stored, modified, or logged.
AI CLI tools are powerful but locked to your terminal. Existing bridges require cloud hosting, databases, and trusting a third party with your prompts.
RustifyMyClaw runs locally. Messages in -> directly to your Agent, responses out -> directly back to you - zero tinkering with your requests. One binary, one YAML file, and your Agent's own config.
- No database. The only state is
is_active: bool— whether the conversation has an ongoing session (so the backend knows to pass--continueor not). Restart = clean slate. - No prompt modification. Messages pass to the CLI as-is.
- No agent override. Your CLI tool's own config governs what the agent can do. RustifyMyClaw doesn't touch it.
- No cloud. No telemetry. Talks to your messaging platform's API. Everything else is local.
- Message arrives on your channel (Telegram, WhatsApp, or Slack).
- SecurityGate checks the sender against your allowlist. Unauthorized = silent drop.
- Router parses commands (
/new,/use,/status,/help). Everything else is a prompt. - Executor spawns your CLI tool locally. Prompt passed through unmodified.
- Formatter chunks the output respecting code blocks and UTF-8 boundaries, sends it back.
- Demo: Install via Cargo — install, configure, and run.
- Single binary, no dependencies.
- Env var interpolation for all secrets, zero hardcoded tokens.
- Per-workspace process timeout to prevent runaway sessions.
- 140+ tests, zero clippy warnings, trait-based extensibility.
- Block-aware output chunking/formatting - natural chat feeling.
- Graceful shutdown with 30s in-flight message drain.
Linux / macOS:
curl -fsSL https://raw.githubusercontent.com/Escoto/RustifyMyClaw/main/scripts/install.sh | bashSpecific version:
curl -fsSL https://raw.githubusercontent.com/Escoto/RustifyMyClaw/main/scripts/install.sh | bash -s -- v0.1.0Windows (PowerShell script):
irm https://raw.githubusercontent.com/Escoto/RustifyMyClaw/main/scripts/install.ps1 | iexWindows (Chocolatey):
choco install rustifymyclawcrates.io (any platform with Rust installed):
cargo install rustifymyclawGenerate a starter config with config init:
rustifymyclaw config init # writes to default platform location
rustifymyclaw config init -d . # writes config.yaml in current directory
rustifymyclaw config init -f my.yaml # writes to a specific file pathDefault locations:
- Linux / macOS:
~/.rustifymyclaw/config.yaml - Windows:
%APPDATA%\RustifyMyClaw\config.yaml
RustifyMyClaw auto-discovers config.yaml in the current directory, so config init -d . followed by rustifymyclaw just works. See docs/configuration.md for the full resolution chain.
Minimal example:
workspaces:
- name: "my-project"
directory: "/home/user/projects/my-project"
backend: "claude-cli"
channels:
- kind: telegram
token: "${TELEGRAM_BOT_TOKEN}"
allowed_users:
- "@your_handle"
output:
max_message_chars: 600
file_upload_threshold_bytes: 51200
chunk_strategy: "natural"Tokens are never hardcoded — use ${ENV_VAR} interpolation. Full reference: docs/configuration.md
Use default config location OR current directory when config.yaml is present:
rustifymyclawOr with a custom config path:
rustifymyclaw -f /path/to/config.yamlValidate your config without starting the daemon:
rustifymyclaw --validateImportant
1 - Requires explicit workspace write permissions (otherwise your workspaces are readonly).
2 - As a daemon, rustifymyclaw defaults to /etc/rustifymyclaw/config.yaml. To use a different config file, set the RUSTIFYMYCLAW_CONFIG var and ensure the file is world-readable with chmod 644 so the daemon can access it.
curl -fsSL https://raw.githubusercontent.com/Escoto/RustifyMyClaw/main/scripts/install.sh | sudo bash -s -- --systemThis places the binary in /usr/local/bin/, config in /etc/rustifymyclaw/, and installs a hardened systemd unit. Then:
sudo nano /etc/rustifymyclaw/config.yaml # configure workspaces/channels
sudo nano /etc/rustifymyclaw/env # add API tokens and/or RUSTIFYMYCLAW_CONFIG to overwrite default config location.
sudo systemctl enable --now rustifymyclaw
journalctl -u rustifymyclaw -f # check logsTo allow your CLI Agent to write, use the built-in command:
sudo rustifymyclaw config allow-path /home/user/projects/my-projectSee docs/configuration.md for full setup details and security hardening options.
RustifyMyClaw proxies to whichever AI CLI tool you have installed locally. Adding a new backend is one file and one trait implementation — see How to Add a New Backend.
| Backend | Binary | Status |
|---|---|---|
| Claude Code | claude |
Stable |
| Codex | codex |
Stable |
| Gemini CLI | gemini |
Stable |
Each channel connects using the platform's native protocol. No webhooks required for Telegram or Slack.
| Channel | Mode | Status |
|---|---|---|
| Telegram | Long-polling | Stable |
| Webhook | Stable | |
| Slack | Socket Mode | Stable |
| Command | Description |
|---|---|
/new |
Reset the current session |
/use <workspace> |
Switch to a different workspace |
/status |
Show current workspace, backend, and session state |
/help |
List available commands |
- Architecture — system design, data flow, and extension points
- Configuration — full field reference and examples
- Building from Source — build instructions and requirements
Contributions welcome. See CONTRIBUTING.md.
Licensed under Apache-2.0.