Setup Guide
May 20, 2026 · View on GitHub
Full walkthrough for getting Lemon running on your machine.
Prerequisites
| Requirement | Version | Notes |
|---|---|---|
| Elixir | 1.19.5+ | See below for install |
| Erlang/OTP | 28.5+ | Bundled with asdf/Elixir install |
| Node.js | 24 LTS+ | TUI and Web clients only |
| Python | 3.10+ | Debug CLI only (optional) |
| Rust/Cargo | stable | WASM tool auto-build (optional) |
Installing Elixir
macOS (Homebrew):
brew install elixir
elixir -v
Linux (recommended — asdf for consistent versions):
# Install asdf, then:
asdf plugin add erlang
asdf plugin add elixir
asdf install erlang 28.5
asdf install elixir 1.19.5-otp-28
asdf global erlang 28.5
asdf global elixir 1.19.5-otp-28
elixir -v
Linux OS packages (faster, version varies)
Arch Linux:
sudo pacman -S elixir erlang
Ubuntu/Debian:
sudo apt-get install -y elixir erlang
Fedora:
sudo dnf install -y elixir erlang
Node.js (TUI/Web clients only):
# macOS
brew install node@24
# Linux (nvm)
nvm install 24
Clone and Build
git clone https://github.com/z80dev/lemon.git
cd lemon
mix local.hex --force
mix deps.get
mix compile
Optional — build the TUI client:
cd clients/lemon-tui
npm install
npm run build
cd ../..
Automated Setup
mix lemon.setup walks through the full setup interactively:
mix lemon.setup
Runs: dependency check → config scaffolding → secrets setup → gateway config → health check.
Individual sub-commands:
mix lemon.setup provider # Configure an AI provider
mix lemon.setup runtime # Configure runtime profile and port bindings
mix lemon.setup gateway # Configure Telegram/Discord gateway adapters
mix lemon.setup doctor # Run diagnostics
Configuration
Create ~/.lemon/config.toml manually or run mix lemon.setup for the full
interactive wizard:
# Provider keys (pick one or more)
[providers.anthropic]
api_key_secret = "llm_anthropic_api_key_raw"
# Or, for Claude Max / Claude Code subscription auth:
# auth_source = "oauth"
# oauth_secret = "llm_anthropic_api_key" # optional if this secret stores an Anthropic OAuth payload
# Lemon also detects ambient Claude Code credentials from ~/.claude/.credentials.json
# and CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_TOKEN when auth_source = "oauth".
# Refreshable Claude Code credentials win over a static env setup token.
[providers.openai]
api_key_secret = "llm_openai_api_key"
# OpenAI-compatible local or hosted endpoint:
# [providers.openai]
# api_key_secret = "llm_local_openai_api_key"
# base_url = "http://127.0.0.1:11434/v1"
#
# [defaults]
# provider = "openai"
# model = "openai:local-model-name"
# Other API-key onboarding targets include:
# [providers.zai]
# api_key_secret = "llm_zai_api_key"
#
# [providers.minimax]
# api_key_secret = "llm_minimax_api_key"
# Runtime defaults
[defaults]
provider = "anthropic"
model = "anthropic:claude-sonnet-4-20250514"
engine = "lemon"
# Telegram gateway
[gateway]
enable_telegram = true
auto_resume = true
default_engine = "lemon"
default_cwd = "~/"
[gateway.telegram]
bot_token = "123456:your-bot-token"
allowed_chat_ids = [123456789]
deny_unbound_chats = true
[[gateway.bindings]]
transport = "telegram"
chat_id = 123456789
agent_id = "default"
# Default assistant profile
[profiles.default]
name = "Lemon"
system_prompt = "You are my general assistant."
[profiles.default.tool_policy]
allow = "all"
deny = []
require_approval = ["bash", "write", "edit"]
See docs/config.md for the full configuration reference.
OpenAI-Compatible Endpoints
Lemon can point the openai provider at any endpoint that implements the
OpenAI-compatible chat/completions surface used by the configured model.
[providers.openai]
api_key_secret = "llm_local_openai_api_key"
base_url = "http://127.0.0.1:11434/v1"
[defaults]
provider = "openai"
model = "openai:local-model-name"
engine = "lemon"
Store the key expected by the endpoint. For local servers that ignore the key, store a harmless placeholder:
mix lemon.secrets.set llm_local_openai_api_key "local"
Provider-specific compatibility still matters: the endpoint must support the request and streaming shape Lemon sends for the selected model.
Telegram Setup
1. Create a bot token
- Message
@BotFatherin Telegram - Run
/newbotand follow the prompts - Copy the bot token
2. Find your chat ID
Send any message to your bot, then fetch updates:
export TOKEN="123456:your-bot-token"
curl -s "https://api.telegram.org/bot${TOKEN}/getUpdates" | python3 -m json.tool
Look for message.chat.id.
3. Update config
Set gateway.telegram.bot_token and allowed_chat_ids in ~/.lemon/config.toml.
Running Lemon
Telegram gateway
./bin/lemon-gateway
Prints the distributed node name on boot. Use it to attach a remote shell:
./bin/lemon-gateway-remsh
Development / TUI
# Starts Elixir backend + TUI
./bin/lemon-dev /path/to/your/project
# Custom model
./bin/lemon-dev /path/to/project --model anthropic:claude-sonnet-4-20250514
# Local model via OpenAI-compat API
./bin/lemon-dev /path --model openai:llama3.1:8b --base-url http://localhost:11434/v1
Web UI
The full runtime profile includes the Phoenix web interface. Start the runtime, then open the web port shown in the logs:
./bin/lemon
Default local routes:
/- session console/ops- operations dashboard for runtime health, active sessions, recent runs, pending approvals, and support-bundle commands/ops/runs/<run_id>- run detail with timeline events, tool events, failures, child runs, and support-bundle commands/healthz- web health check
Health Check
After setup, verify everything is working:
mix lemon.doctor
Checks: config files, secrets, provider configuration, runtime dependencies, system tools, and skills storage.
Generate a redacted support bundle when filing a bug or asking for help:
mix lemon.doctor --bundle
The bundle is written under tmp/lemon-support-bundles/ by default. It contains the doctor report, runtime metadata, selected environment shape, redacted Lemon config files, provider setup diagnostics, extension directory diagnostics, and browser automation diagnostics when available. Review it before sharing; it is designed to exclude provider keys, secret names, base URLs, environment variable names, tokens, passwords, private prompts, memory contents, page contents, source file contents, screenshot bytes, and tool outputs.
For release-runtime installs, run the same bundle writer through the release eval command:
./bin/lemon_runtime_full eval 'LemonCore.Doctor.CLI.bundle!()'
Secrets Store
API keys are stored in an encrypted keychain, not in config.toml in plaintext.
# Write a secret
mix lemon.secrets.set llm_anthropic_api_key_raw "sk-ant-..."
# List stored secrets
mix lemon.secrets.list
Config references secrets by name via api_key_secret = "key_name".
Anthropic raw API keys should live in llm_anthropic_api_key_raw.
Anthropic OAuth-backed plans use auth_source = "oauth" and optionally oauth_secret = "llm_anthropic_api_key".
mix lemon.onboard anthropic --auth oauth now runs the Claude Code login flow and writes the matching oauth_secret config for you.
Next Steps
| Topic | Where to look |
|---|---|
| Using skills | docs/user-guide/skills.md |
| Memory & search | docs/user-guide/memory.md |
| Adaptive routing | docs/user-guide/adaptive.md |
| Full config reference | docs/config.md |
| Architecture | docs/architecture/overview.md |
Last reviewed: 2026-03-16