Ein #
An AI agent for your terminal — self-hosted, plugin-driven, and yours.
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ ein │ gRPC │ eind │
│ │ (proto) │ │
│ Ratatui terminal UI │◄────────►│ Agent loop + tool executor │
│ Session picker on startup │ │ WASM plugin host │
│ Slash command autocomplete │ │ Pluggable model clients │
│ Animated thinking spinner │ │ Per-session sandboxing │
│ Syntax-highlighted diffs │ │ SQLite session persistence │
└─────────────────────────────┘ └──────────────────────────────┘
ein is the terminal UI you interact with; eind is the agent server that runs as a background service. On first launch, ein downloads eind automatically and registers it as a system service — no separate server setup required. Tools and model clients are sandboxed WASM plugins: choose from OpenRouter, Anthropic, OpenAI, or Ollama, or write your own.
Features #
- Works with OpenRouter, Anthropic, OpenAI, and Ollama — bring your own key or run locally with no API key
- Sessions persist to SQLite; resume any conversation where you left off
- Tools run as sandboxed WASM components with client-supplied workspace roots and server-owned network controls
- Extend with custom tools or model client backends
- Syntax-highlighted edit diffs shown inline as the agent works
- Server-owned provider profiles keep credentials out of clients and session records
Installation #
Install with cargo binstall:
cargo install cargo-binstall
cargo binstall --git https://github.com/mstallmo/ein ein
Or download pre-built archives directly from GitHub Releases.
Getting Started #
Before the first launch, create ~/.ein/eind.json with at least one provider
profile (see Configuration). Then run ein:
- Server setup —
eindis downloaded from GitHub Releases and registered as a background service automatically - Session picker — create a new session or resume an existing one
- Profile picker — choose one of the server's configured profile/model pairs for a new session
- Directory prompt — choose whether that session may access the current working directory
ein manages the local service. A separately managed or remote eind can use
the same protocol, though the service is unauthenticated and must not be exposed
to an untrusted network.
Configuration #
Configuration is split by owner:
~/.ein/eind.jsonbelongs to the server and contains provider profiles, credentials, embedding, and tool network policy. Edit it on the server and restarteindafter changes.~/.ein/ein.jsonbelongs to the TUI and contains reusable workspace roots./configopens this client file.
A minimal OpenRouter server configuration is:
{
"version": 1,
"default_profile": "personal",
"profiles": {
"personal": {
"display_name": "Personal models",
"plugin": "ein_openrouter",
"params": {
"base_url": "https://openrouter.ai/api/v1"
},
"secret_params": {
"api_key": "sk-or-..."
},
"default_model": "sonnet",
"models": {
"sonnet": {
"display_name": "Claude Sonnet",
"model": "anthropic/claude-sonnet-4-6",
"context_window": 200000,
"params": {
"max_tokens": 32000
}
}
}
}
},
"tool_policy": {
"plugins": {
"ein_webfetch": {
"allowed_hosts": ["docs.rs"]
}
}
}
}
Provider secrets remain on eind; profile listing reveals only stable profile
and model IDs plus display names. A session persists its selected IDs and
non-secret model settings, so changing defaults does not silently change an
existing session. Use /profiles for an explicit model change.
On upgrade, eind and ein independently import their fields from the legacy
~/.ein/config.json and leave that file untouched.
Usage #
Type a message and press Enter to send. Type / to see available slash commands with autocomplete hints.
| Key / Command | Action |
|---|---|
Enter |
Send message / run slash command |
↑ / ↓ |
Scroll conversation history |
Ctrl-C |
Cancel the active turn; quit when idle or on a second press |
/exit |
Exit the TUI |
/config |
Open ~/.ein/ein.json in $EDITOR |
/clear |
Wipe the agent's in-memory context (SQLite history preserved) |
/new |
Drop current session and start a fresh one |
/sessions |
Re-open the session picker to switch sessions |
/compact |
Summarise the conversation via the LLM and replace history with the summary |
/plugins |
Manage installed plugins |
/profiles |
Browse server profiles or change this session's model |
/uninstall |
Stop and remove the eind service and binary |
While the agent is working, an animated thinking spinner appears in the conversation pane. Tool invocations are shown inline as the agent uses them:
▸ Bash ls -la
▸ Read src/main.rs
▸ Write src/main.rs
▸ Edit src/main.rs
Edit calls display a syntax-highlighted diff showing removed and added lines (up to 5 each), with line numbers.
The status bar shows the active model and cumulative token usage. Use Shift+D on a session in the picker to permanently delete it.
Connection behaviour #
The TUI reconnects automatically every 3 seconds if the server is unavailable. Running /new or /sessions bypasses the retry delay and triggers an immediate reconnect attempt.
Tools #
Tools are WASM components loaded at startup. Six are included:
| Tool | Description |
|---|---|
Bash |
Execute shell commands (streams stdout in real time) |
Read |
Read a file from the filesystem |
Write |
Write content to a file |
Edit |
Replace a specific string in a file with new content |
Grep |
Search file contents by regex across a directory tree |
WebFetch |
Fetch a URL and return its content (HTML converted to markdown) |
Adding a tool #
- Create a new package under
plugins/implementing theToolPlugintrait fromplugins/ein_tool/ - Add it to
scripts/build_install_plugins.sh - Rebuild — the server picks it up automatically on next start
Architecture #
crates/
ein_agent/ Agent component (agent loop, tool call logic, extension interface)
ein_core/ Shared types and utilities between plugins and the harness
ein_http/ WASM-native HTTP client, shared by model client and tool plugins
ein_plugin/ WASM plugin interface
ein_proto/ Protocol Buffer definitions (gRPC service + message types)
ein/ Terminal UI client
eind/ gRPC server — WASM plugin host, session persistence
plugins/
ein_anthropic/ Anthropic model client plugin
ein_bash/ Bash tool plugin
ein_edit/ Edit tool plugin
ein_grep/ Grep tool plugin
ein_ollama/ Ollama model client plugin
ein_openai/ OpenAI model client plugin
ein_openrouter/ OpenRouter model client plugin
ein_read/ Read tool plugin
ein_webfetch/ WebFetch tool plugin
ein_write/ Write tool plugin
Protocol #
The protocol (crates/ein_proto/proto/ein.proto) defines a bidirectional
streaming AgentSession RPC plus profile and session discovery. A stream opens
with SessionInit, which either requests a server-defined profile/model for a
new session or names an existing session to resume, and always supplies the
current connection's SessionEnvironment.
Session persistence #
Sessions are persisted to ~/.ein/sessions.db. Resuming by session ID restores
the durable model snapshot and full transcript while using the workspace
environment supplied by the current connection.
An agent's memory lives beside it: core blocks in the same database, and the searchable tiers — facts it wrote down, and a log of what was said — in ~/.ein/memory.lance/. Those are searched by keyword and, when an embedding model is configured, by meaning as well.
Contributing #
Contributions are welcome. See CONTRIBUTING.md for how to build from source, run in development, and cut a release.
License #
Ein is licensed under the Apache License, Version 2.0.
Copyright 2026 Mason Stallmo.
By submitting a pull request, you agree that your contribution is licensed under the Apache License, Version 2.0.
- Rust 100%
- Shell <1%