Rewriting H2s does not tell you if ChatGPT, Perplexity, Gemini, Claude, Copilot, Grok, or Google AI Overviews actually name your brand. Elmo v0.4.4 is the open-source tracker built to run those checks on a schedule you control – not another on-page AEO checklist.
MIT license. Docker Compose stack. A CLI so day one is not hand-rolled YAML. Elmo Cloud starts at $29/mo if you want zero ops; this guide is the free self-host path from the Quick Start and the GitHub repo.
System requirements for answer engine optimization tracking
Per Elmo’s docs (as of late 2026):
- Docker Engine 24+ with Docker Compose v2
- Node.js 18+ for the CLI
- At least one LLM provider key (OpenAI, Anthropic, Mistral, or OpenRouter)
- Scrapers recommended when you care about live ChatGPT / Google AI Mode-style surfaces, not only raw model APIs
Official pages list software only – no hard RAM, CPU, or disk floor. Plan a small always-on host yourself; leave headroom for images, PostgreSQL 18 on new installs, logs, and run history. Linux, macOS (Docker Desktop or Colima), and Windows (Docker Desktop or WSL2) all work in practice.
Download and official source
Skip random forks for anything you will keep online.
| Artifact | Where |
|---|---|
| Platform + releases | github.com/elmohq/elmo/releases – latest tag v0.4.4 (2 Oct 2026) |
| CLI | npm install -g @elmohq/cli – package 0.4.4 matches the platform release |
| Docs | elmohq.com/docs/getting-started |
| Managed option | Elmo Cloud from $29/mo on elmohq.com |
Ever notice how many “install guides” never say which tag they actually tested? Pin v0.4.4 and the matching CLI; floating latest is how silent drift starts.
Install Elmo v0.4.4 step by step
Docker first. If the daemon is down, Compose will not save you.
docker version
docker compose version
node -v # 18+
npm install -g @elmohq/cli
elmo init
elmo compose up -d
elmo init is interactive: config directory (often ./elmo or ~/.elmo), Postgres in Compose versus your own DATABASE_URL, provider keys, scraper keys if you use them, localhost versus a public domain. It writes Compose config and .env.
Pro tip: Hitting the UI through Caddy, Nginx, or Traefik? Set the public URL during init to the exact browser origin (scheme + host). Mismatched origins break sign-in cookies and redirects more often than bad passwords do.
Stack shape after init: web (dashboard/API), worker (pg-boss jobs), PostgreSQL. That split is why “UI is up” can still mean “no prompt ever finishes.”
First-time configuration
After containers look healthy:
- Open http://localhost:1515 (or your domain).
- Create the first admin account.
- Add a brand – name, domain, aliases. Aliases count as mentions in reports.
- Paste buyer-style prompts, not bare head terms. Schedule only what provider pricing can absorb.
- Optional from Settings: external
/api/v1and/api/mcp(available since v0.4.0) for Claude Code, Cursor, or your scripts. Issue org-scoped read or read-write keys there.
Direct provider keys alone answer from the model API. Live product UIs need a scraper path the docs list as recommended – different cost, different fidelity. Pick one story for reporting; mixing them without labeling confuses stakeholders.
Keys change later without a full re-init:
elmo edit env
elmo compose down
elmo compose up -d
Verify the install works
elmo compose ps
elmo compose logs -f web
elmo compose logs -f worker
Healthy services are necessary, not sufficient. Real smoke test: UI loads, you submit one prompt, the worker log shows completion, the dashboard shows a mention or citation row. Missing env vars usually show up in worker logs at startup – fix .env, bounce the stack, rerun one prompt before you trust schedules.
Common install errors and fixes
Docker not running or Compose v1 only. Start the engine (sudo systemctl start docker or Docker Desktop). Confirm docker compose version reports v2. Init and compose up both depend on it.
Port 1515 already bound. Change the published port with elmo edit compose, or free 1515, then elmo compose up -d.
Sign-in loops on a custom domain. Public URL must match the origin in the browser, including https. Edit env, restart, retry in a clean session.
“Live” answers look empty or off on API-only setups. Expected. OpenAI/Anthropic/OpenRouter calls are not the ChatGPT web app or Google AI Mode. Add a supported scraper when product-UI fidelity is the point of the report.
Upgrade and uninstall
npm install -g @elmohq/cli@latest
elmo upgrade
As of the 0.4.x CLI docs, elmo upgrade runs migrations, re-pins image tags to the CLI version, and restarts the stack. Prefer that over hand-editing tags.
elmo compose down
# full data wipe only if you mean it:
elmo compose down -v
npm uninstall -g @elmohq/cli
rm -rf ~/.elmo # or the config dir from init
Care about history? Dump Postgres while it is still up, confirm the dump looks complete, then tear volumes down.
Watching a blank dashboard after a clean install feels anticlimactic. Measurement only starts when prompts actually hit engines – schedules beat another landing-page rewrite.
FAQ
Is Elmo the same as “doing AEO” on my website?
No. Elmo tracks visibility in answer engines. On-page copy, crawl access, and entity work still live in your CMS and PR. Use both.
Can I run Elmo without paid scrapers?
Yes – OpenAI, Anthropic, or OpenRouter keys are enough for model-side runs. You will not mirror ChatGPT’s product UI or Google AI Mode without a scraper. Run a tiny prompt set for a week. Compare token spend versus scraper invoices before you scale the schedule.
How is self-hosted Elmo different from Elmo Cloud?
Self-hosted is free under MIT: your metal, your keys, unlimited prompts within what those keys allow, code you can audit. You own Docker, backups, and rotation. Cloud starts at $29/mo with managed updates and seats; white-label is custom. Docs describe one codebase, two ops models – choose where you want the pager to ring.
Next: npm install -g @elmohq/cli && elmo init on a box that already runs Docker. One brand. Five real buyer prompts. One daily schedule. See if you are cited before you rewrite the hero again.