🔍 CPF Validador

April 24, 2026 · View on GitHub

Valide CPFs, descubra a quem pertencem e encontre o CPF correto a partir de dígitos parciais ou ilegíveis — com resolução automática de CAPTCHA via rede neural treinada localmente.

Expõe as mesmas operações como MCP tools (para agentes AI) e REST API (para integrações diretas), com interface web incluída.


💡 O que este projeto faz

Valida se um CPF é matematicamente correto
👤Confirma a quem um CPF pertence pelo nome
🔎Descobre o CPF completo a partir de dígitos parciais ou ilegíveis
👥Processa dezenas de CPFs em paralelo
🤖Integra com qualquer agente AI via protocolo MCP

Para confirmar a titularidade de um CPF, o sistema consulta o TRT3 — que emite certidões públicas associando CPF e nome. A resolução de CAPTCHA é feita por uma CRNN (Convolutional Recurrent Neural Network) treinada especificamente para isso, atingindo ~99% de acurácia sem depender de nenhum serviço externo.


🤖 MCP Tools

ToolDescrição
validate_cpfValida matematicamente um CPF pelo algoritmo módulo-11
generate_valid_variationsGera todas as variações válidas de um CPF com dígitos errados ou ilegíveis
check_feitos_trabalhistasConfirma titularidade de um CPF consultando o TRT3
find_cpf_by_maskDescobre o CPF completo a partir de uma máscara com * nos dígitos desconhecidos
find_cpf_by_variationsDado um CPF parcial ou errado, encontra o correto filtrando pelo nome
check_multiple_cpfsValida e confirma titularidade de uma lista de CPFs em paralelo

🌐 REST API

MétodoRotaRate limitDescrição
GET/Interface web
POST/cpf/validateValida um CPF matematicamente
POST/cpf/variationsGera variações válidas de um CPF
POST/trt3/feitos10/min por IPConfirma titularidade de um CPF via TRT3
POST/trt3/feitos-multiplos5/min por IPConfirma lista de CPFs em paralelo
POST/trt3/buscar-por-mascara3/min por IPDescobre CPF por máscara com *
POST/trt3/buscar-por-variacoes3/min por IPDescobre CPF correto a partir de variações
GET/history/Lista o histórico de consultas realizadas
POST/history/saveSalva ou atualiza uma entrada no histórico
DELETE/history/Limpa todo o histórico
DELETE/history/{cpf}Remove a entrada de um CPF específico
GET/healthHealth check — retorna {"status": "ok"}

Documentação interativa: http://localhost:8000/docs (disponível apenas em ENV=development).

📂 Histórico de consultas

O histórico é global e compartilhado — todas as consultas feitas pela interface web, pela REST API ou via MCP gravam no mesmo arquivo de histórico do servidor.

  • Interface web: o usuário pode ativar ou desativar o salvamento automático individualmente, através do toggle na aba Histórico. A preferência é salva no localStorage do navegador e não afeta outras interfaces.
  • REST API / MCP: toda consulta bem-sucedida é registrada no histórico global, independente do token utilizado.

Roadmap: no futuro está prevista a opção de múltiplos históricos isolados por token — permitindo que cada integração (web, API, MCP) mantenha seu próprio registro separado.


🏗️ Arquitetura

FastAPI com FastMCP 3.0 montado em /mcp (streamable-http). A camada services/ não tem dependência de framework — a mesma lógica é consumida pelos routers REST e pelo MCP server.

app/
├── main.py             # FastAPI — routers + mcp.http_app() em /mcp + rate limiter
├── config.py           # Lê todas as variáveis de ambiente com defaults
├── mcp_server.py       # FastMCP("cpf-validador") — 6 tools
├── auth.py             # TokenMiddleware — autenticação via API_TOKEN + controle prod/dev
├── services/
│   ├── cpf.py          # Validação, variações e geração por máscara (zero deps de framework)
│   └── trt3.py         # Consulta TRT3: curl_cffi + CAPTCHA solver + pypdf
├── routers/
│   ├── cpf.py          # POST /cpf/validate, POST /cpf/variations
│   ├── trt3.py         # POST /trt3/feitos, /feitos-multiplos, /buscar-por-mascara, /buscar-por-variacoes
│   ├── history.py      # GET/POST/DELETE /history/ — histórico de consultas
│   └── ui.py           # GET / — interface web
└── captcha/
    ├── model.py        # Arquitetura CRNN (CNN + BiLSTM + CTC Loss)
    ├── predictor.py    # Inferência: carrega captcha_model.pt e prediz
    ├── dataset.py      # CaptchaDataset com data augmentation
    ├── train.py        # Loop de treino com early stopping + AMP + registry
    ├── collector.py    # Coleta amostras rotuladas direto do TRT3
    ├── registry.py     # Versionamento de modelos (models/vN/model.pt + meta.json)
    └── models/         # Histórico de versões treinadas

Regras de camada:

  • services/ — zero imports de FastAPI ou FastMCP
  • routers/ e mcp_server.py — importam apenas de services/
  • I/O bloqueante em services/trt3.py é sempre executado via run_in_threadpool

⚙️ Configuração

Todas as opções são lidas de variáveis de ambiente ou do arquivo .env na raiz do projeto.

Referência completa de variáveis

VariávelPadrãoDescrição
API_TOKEN(vazio — sem auth)Token Bearer. Se vazio, todos os endpoints ficam abertos
ENVdevelopmentdevelopment ou production — controla quais rotas ficam abertas sem token
TRT3_BASE_URLhttps://certidao.trt3.jus.brURL base do site do TRT3
TRT3_FORM_PATH/certidao/feitosTrabalhistas/aba1.emissao.htmPath do formulário de consulta
HTTP_TIMEOUT30Timeout (segundos) para requisições HTTP ao TRT3
CAPTCHA_TIMEOUT15Timeout (segundos) para download da imagem CAPTCHA
MAX_CAPTCHA_ATTEMPTS20Tentativas máximas de resolver o CAPTCHA antes de desistir
RETRY_DELAY1.0Segundos de espera entre tentativas de CAPTCHA
DEFAULT_WORKERS8Threads paralelas padrão nas consultas em lote
MAX_WORKERS20Limite máximo de workers que o cliente pode solicitar
TASK_TIMEOUT60Timeout (segundos) por CPF individual em consultas paralelas
MAX_WILDCARDS_IN_MASK5Máximo de * na parte base da máscara (evita explosão combinatória)
RATE_LIMIT_FEITOS10/minuteRate limit de /trt3/feitos por IP
RATE_LIMIT_MULTIPLOS5/minuteRate limit de /trt3/feitos-multiplos por IP
RATE_LIMIT_MASK3/minuteRate limit de /trt3/buscar-por-mascara por IP
RATE_LIMIT_VARIACOES3/minuteRate limit de /trt3/buscar-por-variacoes por IP
CAPTCHA_MODEL_PATH(vazio — usa app/captcha/captcha_model.pt)Path absoluto para o modelo .pt (útil para montar modelo externo)
HISTORY_RETENTION_DAYS90Dias de retenção do histórico (LGPD). 0 = sem limite
APP_TIMEZONEAmerica/Sao_PauloTimezone para timestamps do histórico

🔒 Rotas abertas por ambiente

Rotadevelopmentproduction
/✅ aberta✅ aberta
/health✅ aberta✅ aberta
/docs✅ aberta🔒 token
/redoc✅ aberta🔒 token
/openapi.json✅ aberta🔒 token
/mcp🔒 token🔒 token
demais🔒 token🔒 token

Se API_TOKEN estiver vazio, o middleware ignora autenticação em qualquer ambiente.


🔐 Autenticação

Com API_TOKEN configurado, todas as requisições protegidas precisam enviar:

Authorization: Bearer meu-token-secreto

REST:

curl -X POST http://localhost:8000/trt3/feitos \
  -H "Authorization: Bearer meu-token-secreto" \
  -H "Content-Type: application/json" \
  -d '{"cpf": "529.982.247-25"}'

Claude Desktop / Claude Code (claude_desktop_config.json):

{
  "mcpServers": {
    "cpf-validador": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8000/mcp", "--allow-http"],
      "env": {
        "MCP_REMOTE_HEADER_AUTHORIZATION": "Bearer meu-token-secreto"
      }
    }
  }
}

A interface web (/) exibe um gate de autenticação quando API_TOKEN está definido — o token é validado contra o servidor e salvo no navegador.


🚀 Instalação

Docker (recomendado)

git clone https://github.com/opastorello/cpf-validador.git
cd cpf-validador
cp .env.example .env   # edite se quiser definir API_TOKEN
docker compose up --build -d

Local

pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

Após iniciar:

  • Interface web: http://localhost:8000/
  • REST docs: http://localhost:8000/docs (apenas em ENV=development)
  • MCP endpoint: http://localhost:8000/mcp

📋 Exemplos de uso

Validar um CPF

curl -X POST http://localhost:8000/cpf/validate \
  -H "Content-Type: application/json" \
  -d '{"cpf": "529.982.247-25"}'

Confirmar titularidade

curl -X POST http://localhost:8000/trt3/feitos \
  -H "Content-Type: application/json" \
  -d '{"cpf": "529.982.247-25"}'
{
  "cpf": "529.982.247-25",
  "encontrado": true,
  "nome_certidao": "JOAO DA SILVA",
  "valida_ate": "18/04/2026",
  "numero_certidao": "2026/123456"
}

Descobrir CPF por máscara

Quando você conhece apenas parte dos dígitos — substitua os desconhecidos por *:

curl -X POST http://localhost:8000/trt3/buscar-por-mascara \
  -H "Content-Type: application/json" \
  -d '{"mascara": "***.123.456-**", "nome": "João Silva"}'

O servidor gera todas as combinações válidas para as posições com *, consulta em paralelo e retorna apenas os matches com o nome informado.

Máximo de 5 wildcards na parte base (posições 0–8) = até 100.000 combinações. Configurável via MAX_WILDCARDS_IN_MASK.

Recuperar CPF com erros ou dígito faltando

curl -X POST http://localhost:8000/trt3/buscar-por-variacoes \
  -H "Content-Type: application/json" \
  -d '{"cpf_parcial": "5299824725", "nome": "joao"}'

Consulta em lote

curl -X POST http://localhost:8000/trt3/feitos-multiplos \
  -H "Content-Type: application/json" \
  -d '{"cpfs": ["529.982.247-25", "111.444.777-35"], "workers": 4}'

🧠 Modelo de CAPTCHA

Arquitetura CRNN

$ \text{Input} (1 \times 60 \times 160) → \text{Conv2D} \times 4 + \text{BatchNorm} + \text{ReLU} + \text{MaxPool} (\text{extra}çã\text{o} \text{de} \text{features} \text{visuais}) → \text{BiLSTM} \times 2 (128 \text{hidden}, \text{bidirectional}) (\text{modelagem} \text{de} \text{sequ}ê\text{ncia}) → \text{Linear} → \text{CTC} \text{Loss} (\text{decode} \text{sem} \text{segmenta}çã\text{o}) \text{Output}: \text{string} \text{de} 5 \text{caracteres} [0-9\text{a}-\text{z}] $

Bootstrapping em 3 rodadas

RodadaAmostrasRotuladorAcurácia dos labelsAcurácia do modelo
115.000ddddocr (OCR genérico)~43%98.70%
220.000Modelo R1~96%98.80%
320.000Modelo R2~99.3%98.55%

Total: 55.000 amostras. O modelo final (v1) convergiu na época 106/120 com val_loss=0.0072.

Hiperparâmetros

  • Optimizer: AdamW | LR: 1e-3 com CosineAnnealingLR
  • Epochs: 120 com early stopping (patience: 20)
  • Batch size: 128 | Treino: GPU com AMP float16 via torch.amp.autocast
  • Inferência: CPU-only (Docker)
  • Augmentation: rotação, shear, translate, color jitter, gaussian blur, random erasing

Treinar o modelo

1. Coletar amostras

python -m app.captcha.collector --cpf 000.000.000-00 --target 15000 --workers 4

2. Treinar

python -m app.captcha.train --epochs 120 --batch 128 --lr 1e-3

O melhor modelo (menor val_loss) é salvo em app/captcha/captcha_model.pt.

3. Bootstrap (melhora qualidade dos labels)

rm -rf app/captcha/data/
python -m app.captcha.collector --cpf 000.000.000-00 --target 20000 --workers 4
python -m app.captcha.train --epochs 120 --batch 128 --lr 1e-3

Repita 2–3 rodadas até a acurácia estabilizar. Para consultar o histórico de versões:

python -m app.captcha.registry

📦 Dependências principais

PacoteUso
FastMCPFramework MCP server
FastAPIREST API
slowapiRate limiting por IP
curl-cffiHTTP com impersonação TLS Chrome-124
PyTorchRede neural CRNN para CAPTCHA
torchvisionTransforms e augmentation de imagem
pypdfExtração de dados do PDF de certidão
PillowProcessamento de imagem
python-dotenvCarregamento de variáveis do .env

🗺️ Roadmap

Ideias e melhorias planejadas para versões futuras.

Escalabilidade

  • Worker distribuído — arquitetura de fila (Redis + worker nodes) onde cada nó é uma VPS com IP próprio contribuindo com slots de conexão ao TRT3. Escala horizontalmente: 1 worker = 20 slots, 5 workers = 100 slots, IPs diferentes reduzem risco de throttling.
  • Cache de resultados — CPFs já consultados recentemente retornam resultado armazenado sem nova requisição ao TRT3. Reduz latência e carga no tribunal.

Multi-usuário

  • Histórico isolado por token — cada integração (web, API, MCP) mantém seu próprio registro separado em vez do histórico global compartilhado atual.
  • Quota de consultas por token — cada token teria um limite mensal/diário de consultas configurável independentemente do rate limit por IP. Ex: token A = 1.000 consultas/dia, token B = 10.000/dia.
  • Workers por token — cada token teria um número máximo de workers simultâneos ao TRT3. Ex: token gratuito = 2 workers, token premium = 20 workers. Garante que um único cliente não monopoliza a capacidade do servidor enquanto outros aguardam.

Cobertura

  • Suporte a outros tribunais — expandir para TRT1 (RJ), TRT2 (SP) e demais regiões, consolidando resultados em uma única consulta.
  • Consulta à Receita Federal — validar situação cadastral do CPF diretamente na base da RF.

Observabilidade

  • Dashboard de uso — visualizar volume de consultas, taxa de acerto do CAPTCHA e latência média por endpoint.
  • Alerta de bloqueio — detectar automaticamente quando o TRT3 começa a retornar erros acima do normal e notificar.

⚖️ Responsabilidade de Uso

Este projeto consulta exclusivamente o sistema público do TRT3 (certidao.trt3.jus.br) — os mesmos dados acessíveis por qualquer pessoa pelo navegador, sem login ou cadastro. As certidões emitidas são documentos públicos por determinação legal.

Usos adequados:

  • Due diligence em processos de contratação
  • Verificação de titularidade em contextos jurídicos ou de compliance
  • Integração com agentes AI para automação de processos legítimos

O projeto não se destina a:

  • Varredura em massa sem finalidade específica
  • Coleta de dados para fins não autorizados pela LGPD
  • Qualquer uso que viole a legislação brasileira vigente

O código é aberto e auditável. A responsabilidade pelo uso é inteiramente do operador que implanta e utiliza o serviço. Rate limiting está configurado por padrão para desincentivar abuso.


📄 Licença

MIT © 2026 Nícolas Pastorello