MCP público (Workers):
docs/DEPLOY_WORKERS_MCP.md. FastAPI interno (VPS + gVisor + Tailscale):docs/DEPLOY_GVISOR.md.
Meta (este doc): expor o FastAPI no seu PC via Cloudflare Tunnel — não é o caminho de produção. Produção pública é o Worker.
Meta: expor o Dados Financeiros Abertos como servidor MCP público — acessível via HTTPS, com TLS, rate limit, e sem abrir porta no roteador nem pagar nada.
Stack: Windows + WSL2 + Docker + Cloudflare Tunnel. Custo: R$ 0. Tempo: ~20 minutos do zero ao
https://findata.seudominio.com.brpúblico.
| Alternativa | Problema |
|---|---|
| Deixar porta 8000 aberta no roteador | NAT, IP dinâmico, sem TLS, alvo de bots |
| VPS (DigitalOcean, Hetzner) | R$ 40-100/mês fixo |
| ngrok free | URL muda a cada restart, limite de conexões |
| Cloudflare Tunnel | Grátis, URL fixa, TLS automático, DDoS protegido, WAF incluído |
O cloudflared faz um túnel saindo do seu PC pra Cloudflare (outbound, nunca
inbound). Qualquer firewall/NAT funciona. A Cloudflare vira seu edge: termina
TLS, filtra bots, serve a URL *.seudominio.com.br.
- Windows 10/11 com WSL2 habilitado (
wsl --install) - Ubuntu (ou outra distro) dentro do WSL —
wsl --install -d Ubuntu - Docker Desktop com integração WSL ativa (opcional — dá pra rodar sem Docker também)
- Um domínio registrado e apontando pra Cloudflare (qualquer .com/.br funciona; a Cloudflare oferece conta grátis com DNS gerenciado)
# dentro do WSL
cd ~
git clone https://github.com/robertoecf/openfindata.git
cd openfindata
docker compose -f deploy/docker-compose.prod.yml build- Entre em https://one.dash.cloudflare.com → Networks → Tunnels → Create a tunnel.
- Escolha Cloudflared, dê um nome (ex.:
openfindata). - Copie o Tunnel Token (string longa começando com
ey...). - Na aba Public Hostname configure uma rota:
- Subdomain:
findata - Domain:
seudominio.com.br - Service:
http://findata:8000
- Subdomain:
# cria .env ao lado do compose
cat > deploy/.env <<EOF
CF_TUNNEL_TOKEN=ey...seu-token-aqui
EOF
docker compose -f deploy/docker-compose.prod.yml --profile tunnel \
--env-file deploy/.env up -dPronto. Em ~30s:
curl https://findata.seudominio.com.br/health
# {"status":"ok","version":"0.3.1"}
curl https://findata.seudominio.com.br/stats
# { ... uptime, cache, rate limits ... }
curl https://findata.seudominio.com.br/bcb/series/name/selic?n=3
# dados reais vindo do BCBUse se quiser menos overhead ou se Docker Desktop te irrita.
sudo useradd --system --create-home --home-dir /opt/openfindata findata
sudo mkdir -p /var/log/openfindata
sudo chown findata:findata /var/log/openfindatasudo -u findata bash <<'EOF'
cd /opt/openfindata
git clone https://github.com/robertoecf/openfindata.git .
python3 -m venv .venv
. .venv/bin/activate
pip install -e .
EOFsudo cp /opt/openfindata/deploy/openfindata.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now openfindata
sudo systemctl status openfindata# Ubuntu/Debian
curl -L https://pkg.cloudflare.com/install.sh | sudo bash
sudo apt install cloudflared
# Autentica (abre browser no Windows)
cloudflared tunnel login
# Cria o tunnel e anota o UUID
cloudflared tunnel create openfindata
# Config em ~/.cloudflared/config.yml:
cat > ~/.cloudflared/config.yml <<EOF
tunnel: openfindata
credentials-file: /home/$USER/.cloudflared/<UUID>.json
ingress:
- hostname: findata.seudominio.com.br
service: http://localhost:8000
- service: http_status:404
EOF
# DNS automático
cloudflared tunnel route dns openfindata findata.seudominio.com.br
# Instala como serviço systemd
sudo cloudflared service install
sudo systemctl start cloudflared| Variável | Default | O que faz |
|---|---|---|
FINDATA_RATE_LIMIT_ENABLED |
true |
Liga/desliga o rate limiting |
FINDATA_RATE_LIMIT_DEFAULT |
60/minute;1000/day |
Bucket por IP (;-separated) |
Formato dos buckets: <N>/<period> com period ∈ {second, minute, hour, day}.
Exemplos:
- Mais permissivo:
FINDATA_RATE_LIMIT_DEFAULT="120/minute;5000/day" - Mais restritivo:
FINDATA_RATE_LIMIT_DEFAULT="20/minute;500/day" - Sem limite (deploy interno):
FINDATA_RATE_LIMIT_ENABLED=false
Depois que a URL pública estiver respondendo, adicione em
~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) ou o equivalente no seu cliente MCP:
Reinicie o cliente. Ele vai enumerar todas as ~27 ferramentas
(bcb_get_series_by_name, ipea_search, cvm_list_companies, etc.) e
usá-las automaticamente quando você perguntar coisas como:
"Qual a Selic atual e como ela se compara com a expectativa do Focus pra 2027?"
GET /health— liveness probe (usar pra uptime monitors tipo BetterStack/UptimeRobot).GET /stats— snapshot (uptime, cache, versão, se rate-limit ativo).GET /docs— Swagger UI interativo pro endpoint público.- Logs:
docker compose logs -f findataoujournalctl -u openfindata -f.
- https://uptimerobot.com → add monitor.
- Type: HTTP(s).
- URL:
https://findata.seudominio.com.br/health. - Intervalo: 5 min.
No painel da Cloudflare → Security → WAF → Custom Rules:
(http.request.uri.path matches "^/cvm/financials/") and (cf.threat_score gt 20)
→ Challenge
Bloqueia bots em endpoints pesados.
Rules → Cache Rules:
If hostname == "findata.seudominio.com.br" and URI path matches "^/(bcb|ibge)/"
→ Cache eligibility: Eligible for cache
→ Edge TTL: 10 minutes
Cacheia na borda. Sua casa recebe ~10% do tráfego mesmo com uso público.
Quando você estiver pronto pra divulgar:
- Tweet com
https://findata.seudominio.com.br/docs(Swagger é auto-demo). - LinkedIn BR dev/fintech: comunidade grande, ROI alto.
- Awesome lists (awesome-brazilian-opensource, awesome-mcp-servers) — PR direto.
- Hacker News Show HN.
- Discord: Claude Developers, Python Brasil.
O endpoint /mcp é plug-and-play no Claude Desktop — esse é seu melhor demo.
Tunnel não conecta:
docker compose logs cloudflared
# ou
sudo journalctl -u cloudflared -fDados Financeiros Abertos caiu silenciosamente:
curl http://localhost:8000/health # local
# se local OK mas público não, problema é no tunnelRate limit mal calibrado:
curl -I https://findata.seudominio.com.br/bcb/series
# Olhe os headers X-RateLimit-Limit / Remaining / ResetWSL parando de rodar quando fecho o terminal:
Ative WSL2 service mode no wsl.conf:
# /etc/wsl.conf dentro do WSL
[boot]
systemd=truewsl --shutdown no Windows, reabre.
| Item | Custo |
|---|---|
| WSL + Ubuntu | R$ 0 |
| Docker Desktop (uso pessoal/open source) | R$ 0 |
| Cloudflare Tunnel + DNS + edge + WAF | R$ 0 |
Domínio .com.br |
~R$ 40/ano |
| Energia elétrica do PC Gamer ligado 24/7 | ~R$ 30-60/mês |
Total: ~R$ 40/mês no pior caso.
Mantendo o PC ligado só algumas horas por dia (com UptimeRobot só avisando): < R$ 10/mês.
{ "mcpServers": { "openfindata": { "url": "https://findata.seudominio.com.br/mcp" } } }