MCP-SPA-PMT
A read-only MCP server for natural-language access to SPA-PMT processes, deadlines, triage, and judicial documents.
List your caixas/fluxos with totals and browse/search processes in a caixa.
Search globally by CNJ number, party name, or CPF/CNPJ and open a process by internal id for header/timeline details.
Scan all caixas for urgent/overdue deadlines in the next N days, detecting the current deadline.
List recent entries in a caixa and run a one-call triage briefing across caixas with recent judicial document summaries.
Show SPA bell notifications.
Download the full administrative process PDF to a local folder.
List, download, or extract text from judicial case documents (PJe/TJPI Pasta do Processo), including paginated reading, caching, and PJe ID detection.
Perform only passive reads: no taking ciência, no workflow steps, no writing or changing SPA data.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP-SPA-PMT Quais são os prazos urgentes dos meus processos nos próximos 5 dias?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Servidor MCP que permite ao Claude Desktop consultar o SPA — Sistema de Processos Automatizados da Prefeitura Municipal de Teresina (spa.pmt.pi.gov.br, plataforma Rails/Devise da Coreplan) diretamente em linguagem natural.
⚡ Sem browser: o SPA não tem Cloudflare nem captcha, então tudo é feito em HTTP puro com Scrapling — login Devise, tabelas DataTables e PDFs. Rápido, leve e sem janela de Chrome abrindo.
✨ Funcionalidades
🔐 Login 100% automatizado: e-mail + senha do Keychain do macOS, com relogin transparente quando a sessão expira
📥 Caixas de processos (fluxos): listagem paginada com busca textual local
⏰ Prazos urgentes em todas as caixas, ordenados do mais urgente ao menos urgente — com detecção do prazo vigente (o campo do SPA acumula prazos históricos)
🆕 Entradas recentes: o que chegou numa caixa nos últimos N dias
🗞️ Triagem em uma chamada: briefing completo da banca — tudo que entrou nos últimos dias, já com o resumo dos documentos judiciais mais recentes de cada processo
⚖️ Pasta do Processo judicial: lista, lê (texto paginado, direto na conversa) e baixa os documentos que o SPA recebe do PJe por integração SOAP/MNI
🔍 Busca global por número CNJ, nome de parte ou CPF/CNPJ
📄 Download do PDF integral do processo administrativo
🔔 Notificações do sino do sistema
🛡️ Leitura passiva: nenhuma ferramenta toma ciência, executa passo de fluxo ou escreve no SPA
Related MCP server: MCP-PJe-TRF1
🛠️ As 12 ferramentas
Caixas e painel
Ferramenta | O que faz |
| as caixas (fluxos) do usuário com o total de processos em cada uma — o equivalente às abas de "Meus Processos" |
| processos de uma caixa, com paginação e busca textual (filtro aplicado no cliente — ver avisos) |
| varre TODAS as caixas e retorna os processos com prazo vigente nos próximos N dias (negativo = atrasado), com rótulo e hora do prazo |
| processos que ENTRARAM numa caixa nos últimos N dias, do mais recente ao mais antigo |
| briefing em uma chamada: entradas recentes de todas as caixas + resumo dos documentos judiciais mais novos de cada processo (paralelizado, leitura passiva) |
| notificações do sino do SPA |
Consulta e busca
Ferramenta | O que faz |
| busca global do topo do sistema: nº CNJ, nome de parte ou CPF/CNPJ |
| abre um processo pelo id interno: campos do cabeçalho (partes, classe, vara, responsável, status, prazos) + timeline de andamentos |
Documentos e autos
Ferramenta | O que faz |
| PDF integral do processo administrativo (todas as peças num único arquivo, como o SPA monta) |
| a "Pasta do Processo" judicial — documentos que o SPA baixa do tribunal por comunicação eletrônica (inicial, despachos, certidões, intimações...) |
| baixa UM documento da pasta judicial pelo id — ou, sem id, os autos completos num único PDF |
| extrai o TEXTO de um documento judicial direto na conversa, paginado, sem salvar arquivo — com cache (continuar a leitura não rebaixa o PDF) e detecção dos ids do PJe citados no texto |
🧰 Requisitos
macOS (credenciais no Keychain — em Linux/Windows funciona com backend
keyringequivalente)Python 3.12+ e uv
Claude Desktop instalado
Conta ativa no SPA da PMT (login por e-mail e senha)
📦 Instalação
1) Clone o repositório
git clone https://github.com/fxbarros/MCP-SPA-PMT.git spa-mcp
cd spa-mcp2) Instale as dependências
uv sync3) Salve as credenciais no Keychain
uv run setup_credenciais.pyO script pergunta o e-mail e a senha do SPA. Tudo fica criptografado no Keychain do macOS (service mcp-spa) — nunca em arquivo. Alternativa sem Keychain: exporte SPA_EMAIL e SPA_SENHA no ambiente do processo.
4) Teste o login (opcional mas recomendado)
uv run diagnostico_login.pyO diagnóstico faz o ciclo completo (CSRF → POST → rota autenticada) e imprime os módulos que a sua conta enxerga. Se o layout do login mudar um dia, há um fallback com Chrome real: uv run diagnostico_login_browser.py.
5) Registre o MCP no Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (ajuste o caminho):
{
"mcpServers": {
"spa-pmt": {
"command": "uv",
"args": [
"--directory", "/Users/SEU_USUARIO/spa-mcp",
"run", "spa-mcp"
]
}
}
}6) Reinicie o Claude Desktop
Cmd+Q e abra de novo — as ferramentas devem aparecer.
💬 Exemplos de uso
Faz a triagem da minha caixa no SPA
Quais meus prazos urgentes nos próximos 15 dias?
O que entrou na caixa de Processo Patrimonial nos últimos 7 dias?
Lista minhas caixas no SPA com os totais
Busca o processo 0000000-00.0000.0.00.0000 no SPA
Abre o processo 12345 e me resume o cabeçalho e a timeline
Lista os documentos judiciais do processo 0000000-00.0000.0.00.0000
Lê a última decisão da pasta judicial desse processo
Baixa os autos completos desse processo pra ~/Downloads
Tenho notificações no SPA?🏗️ Estrutura do projeto
spa-mcp/
├── README.md # este arquivo
├── pyproject.toml # dependências e entry point (uv)
├── setup_credenciais.py # setup inicial (rodar 1x)
├── diagnostico_login.py # diagnóstico de login HTTP puro
├── diagnostico_login_browser.py # fallback com Chrome real (patchright, headed)
├── docs/assets/banner.svg # arte do repositório
└── src/spa_mcp/
└── server.py # servidor MCP completo (sessão, parsers e as 12 tools)🔬 Como funciona por dentro
Detalhes de engenharia reversa do SPA que este MCP encapsula — úteis se o sistema mudar ou se você for adaptar para outra instalação da mesma plataforma:
Login e sessão — autenticação Devise clássica: GET /users/sign_in para extrair o token CSRF do form#new_user, depois POST com user[email]/user[password]. Os cookies persistem em ~/.mcp-spa-session.json (chmod 600) e são reaproveitados entre chamadas; quando qualquer requisição cai na tela de login, o servidor reloga automaticamente uma vez — com um lock de thread, porque ferramentas como a triagem rodam requisições em paralelo e dois relogins simultâneos disputariam a sessão.
Caixas = DataTables server-side — a página /procedures?flow_id=N não traz os dados: a tabela #procedures-box aponta o endpoint JSON no atributo data-url (/procedures/inbox?...). Esse endpoint devolve cada processo como uma lista de células HTML; o valor limpo vem no texto visível (o truncamento do SPA é só CSS) com o atributo title de fallback. Os nomes das colunas saem dos data-name dos <th>.
Dois bugs server-side contornados — enviar search[value] preenchido ou qualquer cláusula order[...] ao inbox responde HTTP 500 (bugs do próprio SPA). Por isso busca e ordenação são feitas 100% no cliente: com busca, o MCP baixa até 500 linhas da caixa e filtra localmente (substring case-insensitive em todos os campos; com 4+ dígitos, compara também só os dígitos — acha CNJ com ou sem pontuação).
Número CNJ nas caixas de expediente — a listagem dessas caixas não tem coluna de número de processo. A única fonte é o link de "Documentos Externos" na coluna Ações (/judicial_processes/<cnj>/documents?soap_setting_id=N), de onde o MCP extrai o CNJ (20 dígitos) e o soap_setting_id (origem da comunicação — ex.: TJPI 1º grau).
Prazo vigente — o campo de prazo do SPA acumula o histórico ("Ciência tácita 17/07/2026 - 01:00 | ..."). O MCP descarta datas administrativas ("Data da criação: ..."), escolhe a data futura mais próxima (ou, se todas passaram, a mais recente) e devolve data_prazo + dias_para_prazo (negativo = atrasado), mantendo o texto completo em prazo_completo para conferência.
Data de entrada na caixa — exata quando o tooltip traz a data por extenso ("03 de Julho de 2026, 17:28"); senão aproximada (±1 dia) a partir do texto relativo ("aproximadamente 23 horas", "3 meses").
Leitura de PDFs — ler_documento_judicial extrai o texto com PyMuPDF em páginas, trunca em max_chars e indica a próxima pagina_inicial; os últimos 5 PDFs ficam num cache LRU em memória, então continuar a leitura de um documento longo não rebaixa o arquivo do tribunal. PDFs escaneados sem camada de texto são detectados e a resposta orienta baixar para OCR externo.
Honestidade estatística — toda ferramenta que avalia uma amostra da caixa (busca, prazos, entradas recentes, triagem) avisa explicitamente quando a caixa tem mais processos do que os avaliados, para o modelo não concluir "não há nada" a partir de uma amostra parcial.
🔒 Segurança
Credenciais ficam no Keychain do macOS (service
mcp-spa), nunca em arquivo nem no códigoCookies de sessão em
~/.mcp-spa-session.jsoncom permissão600(só o seu usuário lê)Nenhuma ação de escrita no SPA: este MCP só lê — não toma ciência, não executa passos de fluxo, não protocola nem altera nada; os downloads gravam apenas no seu disco local
Nenhum dado de processo no repositório: o código não contém números de processo, nomes de parte nem credenciais
⚠️ Avisos importantes
Fragilidade de scraping — o projeto depende do HTML e dos endpoints atuais do SPA. Se a plataforma for atualizada: rode uv run diagnostico_login.py para ver onde trava, inspecione as páginas salvas em /tmp/spa_*.html e ajuste os seletores em src/spa_mcp/server.py. Para depurar visualmente há o fallback headed: uv run diagnostico_login_browser.py.
Busca e ordenação são locais — o endpoint de inbox do SPA responde HTTP 500 a search[value] e order[...] (bugs do sistema, não deste projeto). A busca baixa até 500 linhas da caixa e filtra no cliente; caixas maiores que isso retornam aviso de amostra parcial.
Datas aproximadas — quando o SPA só expõe texto relativo ("há 2 dias"), a data de entrada é aproximada em ±1 dia. A resposta indica quando a data é exata (tooltip por extenso) e quando é estimada.
Uso responsável — sistema interno de trabalho: use com a sua conta, para os seus processos, respeitando as normas do órgão. Nada de varredura massiva.
🔄 Adaptando para outras instalações
O SPA da Coreplan atende outros entes públicos. Para adaptar: mude BASE_URL em src/spa_mcp/server.py, confira o id do form de login (new_user) e da tabela de inbox (procedures-box) no DevTools, ajuste os flow_id de exemplo nas docstrings e renomeie o MCP (FastMCP("spa-pmt")).
🚧 Roadmap
OCR local para documentos judiciais escaneados sem camada de texto
soap_setting_iddeduzido do CNJ quando não informado (TJPI → 1, TRF1 → 11)Cache opcional em disco da listagem de caixas para triagens mais rápidas
📝 Licença e créditos
Uso pessoal e profissional, sem garantias — use por sua conta e risco, respeitando as regras do órgão. Construído por Fábio Ximenes Barros com ajuda do Claude, usando FastMCP, Scrapling, BeautifulSoup e PyMuPDF.
Available Tools
12 toolsbaixar_documento_judicialA
Baixa um documento da Pasta do Processo judicial (PJe/TJPI) pelo id
retornado por listar_documentos_judiciais — ou, sem documento_id,
baixa os autos completos num único PDF.
Inputs: numero_processo (required), pasta, documento_id, soap_setting_id. Returns: object
baixar_processoA
Baixa o PDF integral do processo do SPA-PMT (todas as peças num único arquivo, como o sistema monta) para a pasta indicada.
Inputs: id_processo (required), pasta. Returns: object
buscar_processoB
Busca processos no SPA-PMT por número CNJ, nome de parte ou CPF/CNPJ (a busca global do topo do sistema).
Inputs: termo (required). Returns: object
entradas_recentesA
Processos que ENTRARAM numa caixa do SPA nos últimos dias dias,
do mais recente ao mais antigo. A data de entrada é exata quando o SPA
expõe o tooltip por extenso; senão é aproximada (±1 dia) a partir do
texto relativo ("há 2 dias", "aproximadamente 1 mês").
Inputs: flow_id (required), dias, limite. Returns: object
ler_documento_judicialA
Extrai o TEXTO de um documento da Pasta do Processo judicial (despacho, decisão, sentença, petição...) direto na conversa, sem salvar arquivo. Use listar_documentos_judiciais para obter o id.
Documento longo: o texto é truncado em max_chars e a resposta indica a próxima pagina_inicial para continuar (o PDF fica em cache — continuar a leitura não rebaixa o arquivo). Também detecta os ids do PJe citados no texto (ids_pje_detectados), úteis para citar peças em minutas.
Anexo escaneado sem camada de texto vem vazio — a resposta avisa e o caminho é baixar_documento_judicial para OCR externo.
Inputs: documento_id (required), numero_processo (required), max_chars, pagina_inicial, +1 more. Returns: object
listar_caixaA
Lista os processos de uma caixa do SPA-PMT (fluxo).
Caixas conhecidas da Procuradoria Patrimonial (use listar_fluxos para a lista atualizada com totais): 12 = Processo Patrimonial 26 = Processo Patrimonial - Procurador(a)-Chefe 40 = TRF1 - Processos Judiciais 1º grau 41 = TRF1 - Processos Judiciais 2º grau 15 = Inventário e Partilha - Fiscal 22 = Solicitação ao(a) Assessor(a) da Patrimonial
Inputs: flow_id (required), busca, pagina, por_pagina. Returns: object
listar_documentos_judiciaisA
Lista os documentos externos do processo judicial — a "Pasta do Processo" que o SPA baixa do PJe/TJPI por comunicação eletrônica (petição inicial, despachos, certidões, intimações etc.).
Inputs: numero_processo (required), soap_setting_id. Returns: object
listar_fluxosA
Lista as caixas (fluxos) do usuário no SPA-PMT com o total de processos em cada uma — o equivalente às abas de "Meus Processos".
Inputs: no named parameters. Returns: object
notificacoesB
Notificações do sino do SPA (avisos ao procurador logado).
Inputs: no named parameters. Returns: object
obter_processoA
Abre um processo do SPA-PMT pelo id interno (ex.: 25615) e retorna os campos do cabeçalho (partes, classe, vara, responsável, status, prazos, observações) e a timeline de andamentos com seus documentos.
Inputs: id_processo (required). Returns: object
prazos_urgentesB
Varre todas as caixas do usuário no SPA-PMT e retorna os processos
com prazo VIGENTE nos próximos dias dias, ordenados do mais urgente
ao menos urgente (dias_restantes negativo = atrasado).
O campo de prazo do SPA acumula prazos históricos; considera-se vigente
a data futura mais próxima (ou, se todas passaram, a mais recente). O
texto completo do campo vai em prazo_completo para conferência.
Inputs: dias, por_fluxo, incluir_atrasados. Returns: object
triagemA
TRIAGEM em uma chamada — briefing da caixa do procurador: varre
todas as caixas, junta o que entrou nos últimos dias dias e, para
cada processo com integração judicial, resume os documentos mais
recentes da Pasta do Processo (descrição/data, sem baixar PDF).
Leitura passiva: não toma ciência nem executa passo de fluxo.
Inputs: dias, max_processos, max_documentos. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Most tools target distinct resources: boxes, processes, documents, notifications, and deadline summaries. The main overlap is between baixar_processo and baixar_documento_judicial (when called without an id), but their descriptions clarify different sources and purposes.
The set is split between verb_noun names (listar_caixa, buscar_processo, baixar_processo, etc.) and noun-only or noun-adjective names (notificacoes, prazos_urgentes, entradas_recentes, triagem). While mixed, the names remain readable and somewhat predictable.
With 12 tools, the server is well-scoped for legal process consultation. Each tool serves a distinct step in the workflow—listing, searching, retrieving, downloading, reading, and summarizing—without unnecessary bloat.
The toolset covers the core consultative lifecycle: list boxes, search and get processes, download full cases or individual documents, extract text, and generate deadline/recent-entry briefings. It lacks write operations like moving processes or taking official notice, but the read-only focus appears intentional, so gaps are minor.
Maintenance
Related MCP Connectors
Public lookup of Brazilian court cases (metadata + docket) via the CNJ/DataJud API. Free, no login.
Case law search, court decisions and súmulas, across indexed public sources (STF, STJ, TST, state co
Brazilian legal stack in one MCP: lawsuits, court publications, case law, tenders, certificates.
Simplified lookup of a person's or company's lawsuits from the CPF or CNPJ. Platform-hosted, no cred
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables querying the Brazilian PJe court system for TJMA (1st and 2nd degrees) via natural language, with automated login, expedient and deadline checks, document listing and download, and case searches.3-
- FlicenseNot gradedqualityCmaintenanceEnables natural language querying of Brazil's Federal Justice 1st Region electronic court system (PJe-TRF1) for both 1st and 2nd degrees, allowing users to check pending expedients, deadlines, case details, and download documents via an automated login and read-only MCP server.2-
- FlicenseAqualityDmaintenanceAllows querying the Diário Oficial do Estado do Piauí (DOE-PI) in natural language: list editions, search content, and read full texts without downloading PDFs.24-
- AlicenseNot gradedqualityDmaintenanceMCP server for querying case lists from the TJSP court (eproc) via official sources. It provides one read-only tool to consult court cases through natural language in any MCP-compatible client.MIT