17 MB
idle RAM
12 MB
browser binary
~89%
pages need no browser
Open a session. Run anything.
Type ember and you get a persistent session. Or run one-shot commands directly from your terminal.
$ ember ███████╗███╗ ███╗██████╗ ███████╗██████╗ ██╔════╝████╗ ████║██╔══██╗██╔════╝██╔══██╗ █████╗ ██╔████╔██║██████╔╝█████╗ ██████╔╝ ██╔══╝ ██║╚██╔╝██║██╔══██╗██╔══╝ ██╔══██╗ ███████╗██║ ╚═╝ ██║██████╔╝███████╗██║ ██║ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ v0.1.0 lightweight headless browser for AI agents url <url> scrape a page to markdown search <query> web search crawl <url> crawl a whole website interact <url> control with natural language extract <url> pull structured data with an LLM ember › url https://news.ycombinator.com fetching... tier 1 (trafilatura) ✓ scraped 47 items in 340ms ember › search "open source AI agents" -n 5 searching... ✓ 5 results ember › save results.md ✓ saved to results.md
ember decides. You don't have to.
Most pages don't need a browser. ember checks the content and only launches Lightpanda when the page requires JavaScript.
trafilatura
handles ~89% of the web
Blogs, docs, news, GitHub. Pure HTTP, no browser process, no RAM overhead. Near-instant.
Lightpanda
SPAs + JS-heavy sites
A real browser engine written in Zig. 12 MB binary, auto-downloaded on first use. Only runs when a page needs JavaScript.
Crawl4AI imports at 171 MB before you scrape anything. Firecrawl needs 4-8 GB in Docker.
Six commands. One install.
All commands work standalone or inside the interactive session. Pass -o to any command to save the output.
Scrape any page
Returns clean markdown. Static pages use trafilatura. JS-heavy SPAs fall back to Lightpanda automatically.
ember url https://example.comWeb search, no API key
DuckDuckGo search built in. No account, no credits. Returns titles, URLs, and descriptions.
ember search "AI agents python" -n 10Crawl entire sites
Depth-first crawler with sitemap support. Fetches every page once, respects robots.txt, follows internal links.
ember crawl https://docs.example.com --max-pages 50Discover all URLs
Reads sitemaps, follows robots.txt, and extracts links to build a full URL map of any domain.
ember map https://example.comNatural language control
Describe what to do. ember opens the page in Lightpanda and executes the task using your LLM.
ember interact https://amazon.com --prompt "find a keyboard under $100"Structured extraction
Scrapes the page, passes it to an LLM with your prompt, returns structured JSON. Works with any provider.
ember extract https://example.com/pricing --prompt "list all plans as JSON"How it stacks up.
| ember | Crawl4AI | Firecrawl OSS | Playwright | |
|---|---|---|---|---|
| Setup | pip install | pip install | Docker + Redis + Node | pip + browser install |
| Idle RAM | ~17 MB | ~171 MB | 4-8 GB (Docker) | ~47 MB |
| Browser binary | Lightpanda 12 MB | Chromium 281 MB | Chromium 281 MB | Chromium 281 MB |
| Docker required | No | No | Yes | No |
| API key required | No | No | No | No |
| MCP server | Yes | No | Yes | Yes |
| Search built-in | Yes | No | Yes | No |
CLI. Python. MCP.
One-shot from the terminal. Import into Python. Connect to any MCP host.
ember # interactive session ember url https://example.com # one-shot scrape ember search "AI agents" -n 5 # web search ember crawl https://docs.example.com --max-pages 20 ember serve # REST API on port 51251
from emb.scrape import scrape_url
from emb.search import search
result = scrape_url("https://example.com")
print(result.markdown) # full page as markdown
print(result.title)
results = search("python asyncio", limit=5)
for r in results:
print(r.title, r.url)pip install "ember-browser[mcp]"
# mcp config:
{
"mcpServers": {
"ember": {
"command": "ember",
"args": ["mcp"]
}
}
}
# tools: scrape, search_web, crawl_site,
# map_site, batch_scrape, interact_page, extract_dataOpen source. MIT licensed.
Built for agents that run on VPS, laptops, and Raspberry Pis. Not just machines with 8 GB to spare.