Setup Guide

May 20, 2026 · View on GitHub

Full walkthrough for getting Lemon running on your machine.


Prerequisites

RequirementVersionNotes
Elixir1.19.5+See below for install
Erlang/OTP28.5+Bundled with asdf/Elixir install
Node.js24 LTS+TUI and Web clients only
Python3.10+Debug CLI only (optional)
Rust/CargostableWASM 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

  1. Message @BotFather in Telegram
  2. Run /newbot and follow the prompts
  3. 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

TopicWhere to look
Using skillsdocs/user-guide/skills.md
Memory & searchdocs/user-guide/memory.md
Adaptive routingdocs/user-guide/adaptive.md
Full config referencedocs/config.md
Architecturedocs/architecture/overview.md

Last reviewed: 2026-03-16