CLI para consulta de processos judiciais via MCP - TecJustica
Project description
TecJustica MCP Server
MCP Server para consulta e analise de processos judiciais brasileiros.
Permite que agentes de IA (Claude, etc.) naveguem, busquem e analisem processos judiciais armazenados no Supabase usando o protocolo Model Context Protocol (MCP).
URL de Producao: https://mcp.tecjustica.com/mcp
Stack
| Camada | Tecnologia | Detalhes |
|---|---|---|
| Framework | FastMCP 2.14+ | Python 3.11, transport streamable-http |
| Database | Supabase (PostgreSQL) | RLS habilitado, views materializadas, RPCs |
| Auth | Supabase OAuth 2.1 (DCR) + API Keys | SupabaseProvider + DualTokenVerifier |
| LLM | OpenRouter | Gemini 2.5 Flash, Grok 4.1 Fast, Claude Haiku 4.5 |
| Deploy | Railway | Nixpacks, auto-deploy via git push |
| Linguagem | Python 3.11 | Type hints, async/await |
| Linting | Ruff + mypy | Configurado em pyproject.toml |
| Testes | pytest + pytest-asyncio | Coverage com pytest-cov |
Funcionalidades
- 13 Tools com padrao Deep Agent (metafora filesystem: ls, read, grep, glob)
- 2 Resources para acesso direto a dados via URI
- 6 Prompts profissionais guiados para analises juridicas
- Dual-source: dados da API (PJE) e segmentacao PDF, com filtro por
fonte - Processos civeis e criminais com deteccao automatica
- Busca de precedentes no Banco Nacional de Precedentes (BNP/CNJ)
- Auth dual: OAuth 2.1 via Supabase (DCR) + API keys (
tk_) via SHA-256 - LLM integrado via OpenRouter com selecao automatica de modelo
- Eviction inteligente: documentos grandes sao resumidos com LLM em vez de truncados
- Logging completo: uso de LLM e tool calls registrados em tabelas dedicadas
Configuracao Rapida
1. Claude Web (claude.ai) — Recomendado
- Va em Settings > Connectors
- Clique em Add
- URL:
https://mcp.tecjustica.com/mcp - O fluxo OAuth inicia automaticamente
- Faca login com sua conta TecJustica
- Autorize o acesso
2. Claude Code (CLI)
Adicione ao seu ~/.claude/settings.json:
{
"mcpServers": {
"tecjustica": {
"url": "https://mcp.tecjustica.com/mcp"
}
}
}
3. Desenvolvimento Local
# Clone e instale
git clone https://github.com/marcosmarf27/tecjustica-mcp.git
cd tecjustica-mcp
uv venv && uv pip install -r requirements.txt
# Configure .env
cp .env.example .env
# Edite .env com suas credenciais
# Execute
uv run python server.py
Arquitetura
server.py # FastMCP v4.0.0 — resources (2), prompts (6), DualTokenVerifier, main
auth.py # JWT verifier legado (SupabaseJWTVerifier, TrustingTokenVerifier)
tools/
__init__.py # Exporta 6 register_*_tools()
navegacao.py # 5 tools: listar_processos, visao_geral_processo, ls_documentos, ls_movimentacoes, read_documento
busca.py # 4 tools: grep_documentos, grep_movimentacoes, glob_documentos, localizar_no_documento
estatisticas.py # 1 tool: stats_documentos
analise.py # 1 tool: analisar (toda analise via LLM)
precedentes.py # 1 tool: buscar_precedentes (BNP/CNJ)
user.py # 1 tool: whoami
_helpers.py # Constantes, eviction inteligente, selecao de modelo, paginacao
services/
supabase_client.py # Cliente Supabase com RLS, deteccao civel/criminal
llm_service.py # OpenRouter integration (Gemini/Grok/Haiku)
usage_logger.py # Logging fire-and-forget (LLM + tool calls)
docs/ # OAuth flow, troubleshooting, integracao frontend
tests/ # pytest + pytest-asyncio
Fluxo de uma Request
Cliente MCP ──► FastMCP (server.py) ──► DualTokenVerifier ──► @mcp.tool
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
supabase_client.py llm_service.py precedentes.py
(PostgreSQL) (OpenRouter) (BNP API)
│ │
▼ ▼
usage_logger.py ◄──── fire-and-forget logging
(llm_usage_logs + tool_call_logs)
Padrao Deep Agent (Metafora Filesystem)
O agente consumidor segue o padrao: descobrir -> navegar -> buscar -> analisar.
listar_processos() → Descobrir processos, buscar por parte
visao_geral_processo(cnj) → Metadados + partes + stats + movs recentes
ls_documentos(cnj) → Listar docs sem conteudo (como `ls`)
ls_movimentacoes(cnj) → Timeline de movimentacoes (como `ls`)
read_documento(id) → Ler conteudo controlado (como `cat`)
grep_documentos(padrao) → Full-text search no conteudo (como `grep`)
grep_movimentacoes(padrao) → Full-text search em movimentacoes
glob_documentos(cnj, tipo) → Filtrar por nome/tipo/sigilo (como `glob`)
localizar_no_documento(id) → Posicoes exatas de um termo (bridge grep→read)
stats_documentos(cnj) → Contagens agregadas, zero texto
analisar(cnj, pergunta) → Analise com LLM
buscar_precedentes(busca) → Consulta ao BNP/CNJ
whoami() → Identidade do usuario autenticado
Tools (13)
Tools com
fonte?suportam filtro por origem:"api"(PJE) ou"segmentation"(PDF). Omitir retorna ambas.
Navegacao (5)
| Tool | Descricao | Parametros-chave |
|---|---|---|
listar_processos |
Descobrir processos ou buscar por parte | busca?, limite, offset |
visao_geral_processo |
Metadados + partes + stats + movs recentes | numero_processo |
ls_documentos |
Listar docs sem conteudo (metadados) | numero_processo, limite, offset, ordem, fonte? |
ls_movimentacoes |
Timeline de movimentacoes | numero_processo, limite, offset, ordem, fonte? |
read_documento |
Ler conteudo com controle de tamanho | document_id, max_chars, offset |
Busca (4)
| Tool | Descricao | Parametros-chave |
|---|---|---|
grep_documentos |
Full-text/regex/ilike no conteudo | padrao, modo, numero_processo?, tipo_nome?, fonte? |
grep_movimentacoes |
Full-text em movimentacoes | padrao, numero_processo?, tipo_nome?, fonte? |
glob_documentos |
Filtrar por nome/tipo/sigilo | numero_processo, padrao_nome?, padrao_tipo?, nivel_sigilo?, fonte? |
localizar_no_documento |
Posicoes exatas de um termo em 1 doc | document_id, termo, contexto_chars, max_ocorrencias |
Analise (1)
| Tool | Descricao | Parametros-chave |
|---|---|---|
analisar |
Analise com LLM (substitui todas as tools de analise) | numero_processo, pergunta?, document_ids?, perspectiva?, modelo? |
Estatisticas (1)
| Tool | Descricao | Parametros-chave |
|---|---|---|
stats_documentos |
Contagens agregadas, zero texto, breakdown por fonte | numero_processo, fonte? |
Precedentes (1)
| Tool | Descricao | Parametros-chave |
|---|---|---|
buscar_precedentes |
Busca no Banco Nacional de Precedentes (BNP/CNJ) | busca, orgaos?, tipos?, pagina, tamanho_pagina |
Usuario (1)
| Tool | Descricao | Parametros-chave |
|---|---|---|
whoami |
Identidade do usuario autenticado | — |
Resources (2)
Acesso direto via URI:
processo://1234567-89.2024.8.26.0100 → Dados completos do processo
documento://uuid-do-documento → Conteudo do documento
Prompts (6)
Prompts profissionais guiados para analises juridicas:
| Prompt | Descricao | Parametros |
|---|---|---|
analise_completa |
Analise sistematica em 4 fases | numero_processo |
parecer_tecnico |
Parecer juridico formal | numero_processo, questao |
due_diligence |
Analise para acordo/M&A | numero_processo |
preparar_audiencia |
Briefing para audiencia | numero_processo, tipo_audiencia |
estrategia_recursal |
Avaliacao de recursos | numero_processo |
guia_ferramentas |
Guia de todas as 13 tools | — |
Autenticacao
O MCP suporta dois metodos de autenticacao:
OAuth 2.1 via Supabase Auth (DCR)
Para clientes MCP (Claude Web, Claude Code). Registro automatico de clientes via Dynamic Client Registration — nao precisa de client_id ou client_secret.
Usuario → Claude Web → MCP Server → Supabase OAuth (DCR) → Login → Acesso
- Discovery:
GET https://mcp.tecjustica.com/.well-known/oauth-authorization-server - Provider:
SupabaseProviderdo FastMCP - Token verifier:
JWTVerifiervia JWKS (ES256)
API Keys (tk_)
Para integracao programatica. Validadas via hash SHA-256 na env var API_KEY_HASHES.
App → MCP Server (Authorization: Bearer tk_...) → Hash SHA-256 → Acesso
- Formato da env var:
sha256hash:user_id:email[,hash2:uid2:email2] - Gerar hash:
echo -n "tk_..." | sha256sum
Ambos os metodos sao gerenciados pelo DualTokenVerifier em server.py.
Banco de Dados (Supabase/PostgreSQL)
Tabelas
| Tabela | Descricao |
|---|---|
processos |
Processos judiciais (metadados, partes, classe, valor) |
documents |
Documentos do processo (conteudo, tipo, data, sigilo) |
movimentacoes |
Movimentacoes/timeline do processo |
jobs |
Jobs de sincronizacao com PJE |
admin_users |
Usuarios admin do dashboard |
llm_usage_logs |
Logs de uso de LLM (tokens, custo, modelo) |
tool_call_logs |
Logs de chamadas de tools (duracao, params) |
Dual-Source
documents e movimentacoes possuem coluna source (varchar, NOT NULL, default 'api'):
| Fonte | Descricao | Coluna |
|---|---|---|
api |
Dados vindos do PJE (default) | source = 'api' |
segmentation |
Dados de segmentacao de PDF | source = 'segmentation' |
- Documentos de segmentacao possuem
confianca(float, 0-1) indicando score de qualidade - Todas as tools com parametro
fonte?aceitam"api","segmentation", ou omitir para ambas
Views
| View | Descricao |
|---|---|
vw_processo_completo |
Join processo + partes + assuntos |
vw_documentos_preview |
Documentos com preview do conteudo |
vw_documentos_relevantes |
Documentos filtrados por relevancia |
vw_stats_processo |
Estatisticas agregadas por processo |
vw_timeline_processo |
Timeline formatada |
vw_movimentacoes_recentes |
Ultimas movimentacoes |
Todas incluem source (e confianca onde aplicavel).
RPCs (Stored Procedures)
| RPC | Descricao |
|---|---|
buscar_documentos(p_source?) |
Full-text search em documentos |
buscar_movimentacoes(p_source?) |
Full-text search em movimentacoes |
localizar_no_documento |
Posicoes de um termo em documento |
stats_documentos(p_source?) |
Estatisticas com breakdown por fonte |
buscar_processos_por_parte |
Busca por nome de parte |
RLS (Row Level Security)
admin_users: policyauth.uid() = user_idllm_usage_logsetool_call_logs:EXISTSemadmin_users- Logging usa
SUPABASE_SERVICE_KEY(service role, bypassa RLS)
Modelos LLM
Selecao automatica pelo tamanho do contexto (em tools/_helpers.py):
| Modelo | OpenRouter ID | Limite | Uso |
|---|---|---|---|
| Gemini 2.5 Flash | google/gemini-2.5-flash |
ate ~800K tokens | Default (contexto < 800K) |
| Grok 4.1 Fast | x-ai/grok-4.1-fast |
ate ~1.8M tokens | Contexto grande (800K-1.8M) |
| Claude Haiku 4.5 | anthropic/claude-haiku-4.5 |
ate 200K tokens | Disponivel via modelo= explicito |
Eviction Inteligente
Conteudo acima de 10.000 chars e resumido automaticamente via Gemini Flash em vez de truncar. Instrucoes adaptadas por tipo (documento, analise, lista). Metadata retornada: foi_resumido, tamanho_original, tamanho_final.
Custo por 1M tokens (USD)
| Modelo | Input | Output |
|---|---|---|
| Gemini 2.5 Flash | $0.15 | $0.60 |
| Grok 4.1 Fast | $2.00 | $10.00 |
| Claude Haiku 4.5 | $0.80 | $4.00 |
Deteccao Civel vs Criminal
detectar_tipo_processo() em services/supabase_client.py analisa a classe processual e adapta automaticamente o contexto para o LLM.
| Civel (CPC) | Criminal (CPP) | |
|---|---|---|
| Fases | Postulatoria > Saneadora > Instrutoria > Decisoria | Investigacao > Denuncia > Instrucao > Julgamento |
| Partes | Autor, Reu | Acusado, MP, Defensor |
| Pedidos | Tutelas, valores, merito | Tipificacao, penas, cautelares |
| Riscos | Procedencia, sucumbencia | Condenacao, pena, regime |
Perspectivas para analisar(perspectiva=...):
- Civel:
autor,reu,terceiro - Criminal:
acusado,ministerio_publico,defensor,vitima - Neutro:
juiz,assessor
Infraestrutura de Deploy
Railway
| Item | Valor |
|---|---|
| Projeto | TecJustica MCP |
| Service | web |
| URL | https://mcp.tecjustica.com |
| Builder | Nixpacks |
| Start command | python server.py |
| Restart policy | on_failure (max 3 retries) |
| Deploy trigger | git push origin master (automatico) |
Variaveis de Ambiente
| Variavel | Descricao | Onde encontrar |
|---|---|---|
SUPABASE_URL |
URL do projeto Supabase | Dashboard > Settings > API > Project URL |
SUPABASE_SERVICE_KEY |
Service role key (bypassa RLS) | Settings > API > service_role (secret) |
AUTH_ENABLED |
Habilitar auth (true/false) |
— |
MCP_BASE_URL |
URL publica do MCP | https://mcp.tecjustica.com |
OPENROUTER_API_KEY |
Chave API do OpenRouter | openrouter.ai > API Keys |
API_KEY_HASHES |
Hashes de API keys (opcional) | echo -n "tk_..." | sha256sum + user_id + email |
Arquivos de Configuracao
| Arquivo | Descricao |
|---|---|
railway.toml |
Config de build/deploy Railway (Nixpacks, start command, restart policy) |
Procfile |
Fallback: web: python server.py |
runtime.txt |
Versao Python: python-3.11 |
pyproject.toml |
Dependencias, configs de ruff/mypy/pytest/coverage |
requirements.txt |
Dependencias de producao (pip) |
requirements-dev.txt |
Dependencias de desenvolvimento |
.gitignore |
Ignora .venv, .env, __pycache__, .claude/, etc. |
Dependencias
Producao
| Pacote | Versao | Uso |
|---|---|---|
fastmcp |
>=2.14.0 | Framework MCP (transport, auth, tools) |
supabase |
>=2.0.0 | Cliente PostgreSQL com RLS |
openrouter |
>=0.1.0 | LLM via OpenRouter API |
pydantic |
>=2.0.0 | Validacao de dados e type hints |
python-jose[cryptography] |
>=3.3.0 | JWT decode/verify |
httpx |
>=0.27.0 | HTTP client async (BNP API) |
Desenvolvimento
| Pacote | Versao | Uso |
|---|---|---|
ruff |
>=0.8.0 | Linter + formatter |
mypy |
>=1.13.0 | Type checking |
types-python-jose |
>=3.3.0 | Type stubs para python-jose |
pytest |
>=8.0.0 | Framework de testes |
pytest-asyncio |
>=0.24.0 | Suporte async em testes |
pytest-cov |
>=6.0.0 | Coverage |
Limites e Otimizacoes
| Parametro | Valor | Descricao |
|---|---|---|
MAX_PROCESSOS |
50 | Processos por query |
MAX_DOCUMENTOS |
100 | Documentos por query |
MAX_MOVIMENTACOES |
100 | Movimentacoes por query |
LIMIAR_EVICTION |
10.000 chars | Acima disso, resume com Gemini |
LIMITE_GEMINI_TOKENS |
800K tokens | Limite seguro do Gemini Flash |
LIMITE_GROK_TOKENS |
1.8M tokens | Limite seguro do Grok Fast |
BNP_TIMEOUT |
30s | Timeout para API do BNP |
Desenvolvimento
# Setup
uv venv && uv pip install -r requirements.txt -r requirements-dev.txt
# Lint + Format + Type check (OBRIGATORIO antes de commit)
uv run ruff check --fix . && uv run ruff format . && uv run mypy .
# Testes
pytest --cov=. --cov-report=html
# Servidor local
uv run python server.py
Como Adicionar uma Nova Tool
Preferir estender tools existentes a criar novas.
- Criar funcao em
tools/<modulo>.pydentro deregister_<modulo>_tools(mcp):
def register_exemplo_tools(mcp: FastMCP) -> None:
@mcp.tool
async def minha_tool(param: str, ctx: Context) -> dict[str, Any]:
"""Descricao da tool."""
client = get_supabase_client()
# ... logica
return {"resultado": ...}
- Usar helpers de
_helpers.py:paginar_resultado(),_smart_response(),erro_instrutivo() - Exportar em
tools/__init__.py - Registrar em
server.py:register_exemplo_tools(mcp)
Convencoes
- Tipagem: Sempre usar type hints (
str | None,list[str]) from __future__ import annotations: OK em_helpers.pyeservices/, mas NAO em arquivos que registram@mcp.tool(conflita com Pydantic runtime)- Formato CNJ:
NNNNNNN-DD.AAAA.J.TR.OOOO - Valores: BRL (
R$ X.XXX,XX). Datas: ISO 8601. Idioma: pt-BR
Exemplos de Uso
Fluxo Deep Agent (linguagem natural)
> Liste meus processos
> Me de uma visao geral do processo 1234567-89.2024.8.26.0100
> Busque nos documentos por "dano moral"
> Leia o documento <id> encontrado
> Faca analise de risco na perspectiva do autor
> Busque precedentes sobre "dano moral" no STJ
Via Python
from fastmcp import Client
async with Client("https://mcp.tecjustica.com/mcp") as client:
# Listar processos
processos = await client.call_tool("listar_processos", {})
# Visao geral
visao = await client.call_tool(
"visao_geral_processo",
{"numero_processo": "1234567-89.2024.8.26.0100"}
)
# Buscar nos documentos
matches = await client.call_tool(
"grep_documentos",
{"padrao": "dano moral", "numero_processo": "1234567-89.2024.8.26.0100"}
)
# Analisar com LLM
analise = await client.call_tool(
"analisar",
{
"numero_processo": "1234567-89.2024.8.26.0100",
"pergunta": "Qual a situacao atual e os riscos?",
"perspectiva": "autor"
}
)
# Buscar precedentes
precedentes = await client.call_tool(
"buscar_precedentes",
{"busca": "dano moral", "orgaos": ["STJ", "STF"], "tipos": ["SUM", "SV"]}
)
Troubleshooting
Erro 401 "invalid_token"
Causa: Token nao e do Supabase Auth (ex: PJE/Keycloak ou token expirado), ou API key tk_ invalida.
Solucao:
- JWT: Obter token via endpoint Supabase
/auth/v1/tokencom ANON_KEY - API key: Verificar que o hash SHA-256 do
tk_...esta emAPI_KEY_HASHES - Verificar que o token nao expirou
OAuth funciona mas tools nao
- Remova o connector no Claude.ai
- Adicione novamente
- Faca login novamente
Servidor nao inicia
Verifique se todas as variaveis estao configuradas:
SUPABASE_URLSUPABASE_SERVICE_KEYOPENROUTER_API_KEYAUTH_ENABLEDMCP_BASE_URL
Deploy Railway retorna 502
Apos git push, o endpoint pode retornar 502 por ~60-90s durante o build. Aguarde e teste:
curl -s -o /dev/null -w "%{http_code}" https://mcp.tecjustica.com/.well-known/oauth-authorization-server
Observabilidade
Logging de Uso
Toda chamada de tool e de LLM e registrada automaticamente via fire-and-forget:
tool_call_logs: tool name, duracao (ms), user_id, params, success/errorllm_usage_logs: modelo, tokens (prompt/completion), custo (USD), duracao
Logging usa SUPABASE_SERVICE_KEY (service role) para bypassa RLS. Erros de logging sao silenciados para nao afetar a resposta ao usuario.
Metricas Disponiveis
- Custo total por periodo (USD)
- Chamadas por tool / por modelo
- Taxa de sucesso/falha
- Duracao media por operacao
- Breakdown por usuario
Links
Documentacao do Projeto
- Guia de Desenvolvimento de Agentes — guia completo para devs (tools, auth, banco, padroes, exemplos)
- Catalogo de Ferramentas (Referencia Rapida) — referencia rapida das 13 tools
- Documentacao Tecnica (CLAUDE.md)
- Integracao com Clientes MCP — Manus, Claude Code, LangChain
Auth
Externo
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tecjustica-0.1.0.tar.gz.
File metadata
- Download URL: tecjustica-0.1.0.tar.gz
- Upload date:
- Size: 362.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
777b8bff83065497276efa873e4d1209c99f42bb31ee013a1820604f95773a15
|
|
| MD5 |
de6acee80dd1b43509b08ee4b44cc2a1
|
|
| BLAKE2b-256 |
5ef8748ac85b92e76976e1d869fd3769d686300e1aa21e98ad140a24d223e018
|
File details
Details for the file tecjustica-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tecjustica-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca5d1e9d5866705555cd7bf5e52228508391e40007aaa8b74ed856987421b0b0
|
|
| MD5 |
819f9ef70bab7fc588c3710f5e39ec9a
|
|
| BLAKE2b-256 |
7250e856ccaf83706310d5fc8d3d06c39778373093d0e15084562d8b3af3fbdb
|