Are you the author? Sign in to claim
MCP server + REST API para validacao de CPFs e consulta ao TRT3 com solver de CAPTCHA CRNN
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.
| ✅ | 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.
| Tool | Descrição |
|---|---|
validate_cpf | Valida matematicamente um CPF pelo algoritmo módulo-11 |
generate_valid_variations | Gera todas as variações válidas de um CPF com dígitos errados ou ilegíveis |
check_feitos_trabalhistas | Confirma titularidade de um CPF consultando o TRT3 |
find_cpf_by_mask | Descobre o CPF completo a partir de uma máscara com * nos dígitos desconhecidos |
find_cpf_by_variations | Dado um CPF parcial ou errado, encontra o correto filtrando pelo nome |
check_multiple_cpfs | Valida e confirma titularidade de uma lista de CPFs em paralelo |
| Método | Rota | Rate limit | Descrição |
|---|---|---|---|
GET | / | — | Interface web |
POST | /cpf/validate | — | Valida um CPF matematicamente |
POST | /cpf/variations | — | Gera variações válidas de um CPF |
POST | /trt3/feitos | 10/min por IP | Confirma titularidade de um CPF via TRT3 |
POST | /trt3/feitos-multiplos | 5/min por IP | Confirma lista de CPFs em paralelo |
POST | /trt3/buscar-por-mascara | 3/min por IP | Descobre CPF por máscara com * |
POST | /trt3/buscar-por-variacoes | 3/min por IP | Descobre CPF correto a partir de variações |
GET | /history/ | — | Lista o histórico de consultas realizadas |
POST | /history/save | — | Salva 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 | /health | — | Health check — retorna {"status": "ok"} |
Documentação interativa: http://localhost:8000/docs (disponível apenas em ENV=development).
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.
localStorage do navegador e não afeta outras interfaces.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.
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 FastMCProuters/ e mcp_server.py — importam apenas de services/services/trt3.py é sempre executado via run_in_threadpoolTodas as opções são lidas de variáveis de ambiente ou do arquivo .env na raiz do projeto.
| Variável | Padrão | Descrição |
|---|---|---|
API_TOKEN | (vazio — sem auth) | Token Bearer. Se vazio, todos os endpoints ficam abertos |
ENV | development | development ou production — controla quais rotas ficam abertas sem token |
TRT3_BASE_URL | https://certidao.trt3.jus.br | URL base do site do TRT3 |
TRT3_FORM_PATH | /certidao/feitosTrabalhistas/aba1.emissao.htm | Path do formulário de consulta |
HTTP_TIMEOUT | 30 | Timeout (segundos) para requisições HTTP ao TRT3 |
CAPTCHA_TIMEOUT | 15 | Timeout (segundos) para download da imagem CAPTCHA |
MAX_CAPTCHA_ATTEMPTS | 20 | Tentativas máximas de resolver o CAPTCHA antes de desistir |
RETRY_DELAY | 1.0 | Segundos de espera entre tentativas de CAPTCHA |
DEFAULT_WORKERS | 8 | Threads paralelas padrão nas consultas em lote |
MAX_WORKERS | 20 | Limite máximo de workers que o cliente pode solicitar |
TASK_TIMEOUT | 60 | Timeout (segundos) por CPF individual em consultas paralelas |
MAX_WILDCARDS_IN_MASK | 5 | Máximo de * na parte base da máscara (evita explosão combinatória) |
RATE_LIMIT_FEITOS | 10/minute | Rate limit de /trt3/feitos por IP |
RATE_LIMIT_MULTIPLOS | 5/minute | Rate limit de /trt3/feitos-multiplos por IP |
RATE_LIMIT_MASK | 3/minute | Rate limit de /trt3/buscar-por-mascara por IP |
RATE_LIMIT_VARIACOES | 3/minute | Rate 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_DAYS | 90 | Dias de retenção do histórico (LGPD). 0 = sem limite |
APP_TIMEZONE | America/Sao_Paulo | Timezone para timestamps do histórico |
| Rota | development | production |
|---|---|---|
/ | ✅ aberta | ✅ aberta |
/health | ✅ aberta | ✅ aberta |
/docs | ✅ aberta | 🔒 token |
/redoc | ✅ aberta | 🔒 token |
/openapi.json | ✅ aberta | 🔒 token |
/mcp | 🔒 token | 🔒 token |
| demais | 🔒 token | 🔒 token |
Se
API_TOKENestiver vazio, o middleware ignora autenticação em qualquer ambiente.
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.
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
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
Após iniciar:
http://localhost:8000/http://localhost:8000/docs (apenas em ENV=development)http://localhost:8000/mcpcurl -X POST http://localhost:8000/cpf/validate \
-H "Content-Type: application/json" \
-d '{"cpf": "529.982.247-25"}'
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"
}
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.
curl -X POST http://localhost:8000/trt3/buscar-por-variacoes \
-H "Content-Type: application/json" \
-d '{"cpf_parcial": "5299824725", "nome": "joao"}'
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}'
Input (1×60×160)
→ Conv2D ×4 + BatchNorm + ReLU + MaxPool (extração de features visuais)
→ BiLSTM ×2 (128 hidden, bidirectional) (modelagem de sequência)
→ Linear → CTC Loss (decode sem segmentação)
Output: string de 5 caracteres [0-9a-z]
| Rodada | Amostras | Rotulador | Acurácia dos labels | Acurácia do modelo |
|---|---|---|---|---|
| 1 | 15.000 | ddddocr (OCR genérico) | ~43% | 98.70% |
| 2 | 20.000 | Modelo R1 | ~96% | 98.80% |
| 3 | 20.000 | Modelo R2 | ~99.3% | 98.55% |
Total: 55.000 amostras. O modelo final (v1) convergiu na época 106/120 com val_loss=0.0072.
torch.amp.autocast1. 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
| Pacote | Uso |
|---|---|
| FastMCP | Framework MCP server |
| FastAPI | REST API |
| slowapi | Rate limiting por IP |
| curl-cffi | HTTP com impersonação TLS Chrome-124 |
| PyTorch | Rede neural CRNN para CAPTCHA |
| torchvision | Transforms e augmentation de imagem |
| pypdf | Extração de dados do PDF de certidão |
| Pillow | Processamento de imagem |
| python-dotenv | Carregamento de variáveis do .env |
Ideias e melhorias planejadas para versões futuras.
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:
O projeto não se destina a:
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.
MIT © 2026 Nícolas Pastorello
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows