Content
# Firecrawl Local
Firecrawl self-hosted no Mac via Docker (OrbStack ou Docker Desktop).
Zero RAM quando parado. Sobe on-demand em ~5 segundos.
Stack: 5 containers — API, Playwright, Redis, RabbitMQ, PostgreSQL.
## Quick Start
```bash
git clone https://github.com/raphaelmarcelo/firecrawl-local.git
cd firecrawl-local
./install.sh
```
O `install.sh` faz tudo automaticamente:
1. Verifica se OrbStack/Docker Desktop esta instalado
2. Abre o Docker se nao estiver rodando
3. Verifica `docker compose`, `curl`, `node`, `python3`
4. Baixa as imagens (~2-3 GB)
5. Cria os containers e testa um scrape
6. Para os containers (modo on-demand)
## Requisitos
- **macOS** (testado no macOS Sequoia)
- **OrbStack** (recomendado) ou **Docker Desktop**
- **curl** (vem com macOS)
- **Node.js + npx** (necessario para MCP com Claude Code/Codex)
### Instalar OrbStack
Mais leve que Docker Desktop, usa menos RAM e CPU:
```bash
brew install orbstack
```
Ou baixe direto: https://orbstack.dev
## Uso
### Comandos manuais
```bash
./scripts/firecrawl.sh start # Sobe containers
./scripts/firecrawl.sh stop # Para (libera RAM)
./scripts/firecrawl.sh status # Mostra se ta rodando + RAM
./scripts/firecrawl.sh test # Testa scrape rapido
./scripts/firecrawl.sh logs # Logs do API (tail -f)
./scripts/firecrawl.sh pull # Atualiza imagens Docker
./scripts/firecrawl.sh reset # Remove tudo (containers + volumes)
```
### Uso direto via curl
```bash
# Scrape uma URL
curl -s -X POST http://localhost:3002/v1/scrape \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-local' \
-d '{"url": "https://example.com", "formats": ["markdown"]}'
# Busca web
curl -s -X POST http://localhost:3002/v1/search \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-local' \
-d '{"query": "sua busca aqui", "limit": 5}'
# Mapear URLs de um site
curl -s -X POST http://localhost:3002/v1/map \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-local' \
-d '{"url": "https://example.com"}'
```
## Integracoes
### Claude Code (MCP)
1. Adicione o MCP server:
```bash
claude mcp add firecrawl -s user \
-e FIRECRAWL_API_URL=http://localhost:3002 \
-e FIRECRAWL_API_KEY=fc-local \
-- npx -y firecrawl-mcp
```
2. Configure os hooks de auto-start/stop no settings do projeto (`.claude/settings.local.json`):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__firecrawl__.*",
"hooks": [
{
"type": "command",
"command": "/CAMINHO/PARA/firecrawl-local/scripts/ensure-firecrawl.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "mcp__firecrawl__.*",
"hooks": [
{
"type": "command",
"command": "/CAMINHO/PARA/firecrawl-local/scripts/stop-firecrawl.sh"
}
]
}
]
}
}
```
Substitua `/CAMINHO/PARA/` pelo caminho real onde voce clonou o projeto.
Com isso, sempre que o Claude usar uma tool `mcp__firecrawl__*`:
- **Antes**: `ensure-firecrawl.sh` sobe o Docker automaticamente
- **Depois**: `stop-firecrawl.sh` agenda auto-stop em 10 minutos de inatividade
### Codex (OpenAI)
Use o wrapper MCP que ja faz ensure/stop automaticamente:
```json
{
"mcpServers": {
"firecrawl": {
"command": "/CAMINHO/PARA/firecrawl-local/scripts/codex-firecrawl-mcp.sh",
"env": {
"FIRECRAWL_API_URL": "http://localhost:3002",
"FIRECRAWL_API_KEY": "fc-local"
}
}
}
}
```
### Qualquer MCP client (Cline, Cursor, etc.)
Adicione ao `.mcp.json` do seu projeto:
```json
{
"mcpServers": {
"firecrawl": {
"command": "npx",
"args": ["-y", "firecrawl-mcp"],
"env": {
"FIRECRAWL_API_URL": "http://localhost:3002",
"FIRECRAWL_API_KEY": "fc-local"
}
}
}
}
```
Nesse caso, suba manualmente antes de usar: `./scripts/firecrawl.sh start`
## Como funciona
### Arquitetura
```
┌──────────────┐
Claude/Codex ───► │ API (:3002) │
(MCP) └──────┬───────┘
│
┌────────────┼────────────┐
│ │ │
┌──────┴──────┐ ┌─┴──┐ ┌─────┴─────┐
│ Playwright │ │Redis│ │ RabbitMQ │
│ (browser) │ └────┘ └───────────┘
└─────────────┘ │
┌─────┴──────┐
│ PostgreSQL │
└────────────┘
```
### Fluxo on-demand (com hooks)
1. Voce pede pro Claude scrape/search algo
2. Hook `PreToolUse` detecta que o Docker nao ta rodando
3. Abre OrbStack/Docker se necessario
4. Sobe os containers (~5s se ja existem, ~15s primeira vez)
5. Claude faz o scrape normalmente via MCP
6. Hook `PostToolUse` agenda auto-stop em 10 minutos
7. Se nao usar de novo, containers param e liberam RAM
### Consumo de RAM
| Estado | RAM |
|--------|-----|
| Parado | 0 |
| Rodando | ~2.5-3.5 GB |
Limites por container:
- API: 2 GB
- Playwright: 1 GB
- Redis: 128 MB
- RabbitMQ: 128 MB
- PostgreSQL: 256 MB
## API Reference
### POST /v1/scrape
Extrai conteudo de uma URL.
| Parametro | Tipo | Default | Descricao |
|-----------|------|---------|-----------|
| `url` | string | (obrigatorio) | URL para scrape |
| `formats` | string[] | `["markdown"]` | Formatos: `markdown`, `html` |
| `onlyMainContent` | boolean | `true` | Remove headers/footers/sidebars |
| `waitFor` | number | 0 | Espera X ms antes de capturar (SPAs) |
| `timeout` | number | 30000 | Timeout em ms |
### POST /v1/search
Busca na web e retorna conteudo.
| Parametro | Tipo | Default | Descricao |
|-----------|------|---------|-----------|
| `query` | string | (obrigatorio) | Termo de busca |
| `limit` | number | 5 | Max resultados |
| `lang` | string | — | Idioma (ex: `pt-br`) |
| `country` | string | — | Pais (ex: `br`) |
### POST /v1/map
Descobre todas as URLs de um site.
| Parametro | Tipo | Default | Descricao |
|-----------|------|---------|-----------|
| `url` | string | (obrigatorio) | URL raiz |
| `search` | string | — | Filtrar URLs |
| `limit` | number | — | Max URLs |
## Troubleshooting
### "Connection refused" na porta 3002
O Firecrawl nao esta rodando:
```bash
./scripts/firecrawl.sh start
```
### Docker nao sobe
Verifique se OrbStack/Docker Desktop esta aberto:
```bash
docker info
```
Se nao estiver:
```bash
open -a OrbStack # ou: open -a Docker
```
### Scrape retorna vazio (site com JS pesado)
Aumente o `waitFor`:
```bash
curl -s -X POST http://localhost:3002/v1/scrape \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-local' \
-d '{"url": "https://spa-site.com", "formats": ["markdown"], "waitFor": 5000}'
```
### Timeout no scrape
Aumente o `timeout`:
```bash
-d '{"url": "...", "formats": ["markdown"], "timeout": 60000}'
```
### Sites com Cloudflare
Normal demorar mais na primeira tentativa. O Firecrawl faz waterfall: fetch direto -> Playwright (browser). Pode levar ~10-15s.
### Reset total
```bash
./scripts/firecrawl.sh reset # Remove tudo
./install.sh # Reinstala do zero
```
### Ver logs
```bash
./scripts/firecrawl.sh logs
```
## Atualizando
```bash
./scripts/firecrawl.sh pull # Baixa imagens mais recentes
./scripts/firecrawl.sh reset # Remove containers antigos
./install.sh # Recria tudo
```
## Estrutura do projeto
```
firecrawl-local/
├── install.sh # Instalador completo
├── README.md # Este arquivo
├── .gitignore
└── scripts/
├── docker-compose.yml # Stack de 5 containers
├── nuq-init.sql # Schema do PostgreSQL
├── firecrawl.sh # CLI (start/stop/status/test/logs/pull/reset)
├── ensure-firecrawl.sh # PreToolUse hook (auto-start)
├── stop-firecrawl.sh # PostToolUse hook (auto-stop 10min)
├── codex-firecrawl-mcp.sh # Wrapper MCP para Codex
└── codex-firecrawl-mcp.cjs # Node.js MCP proxy com hooks
```
## Licenca
MIT