Servidor MCP para buscar e citar a legislação brasileira no Claude e em qualquer assistente de IA: texto exato de 1,2 milhão de normas (CF, CLT, CDC, Código Civil, LGPD…
Overview
Clique na imagem para ver a demonstração (25 s, com música). é um servidor MCP que dá ao Claude Code, ao Claude Desktop, ao Cursor, ao VS Code, ao Codex e a qualquer cliente MCP acesso à legislação brasileira do repositório público ctresb/leis. Em vez de parafrasear de memória, o assistente busca a norma, lê o dispositivo e cita o texto exato, com a fonte oficial e os avisos de revogação. O texto é convertido automaticamente das fontes oficiais e pode conter erros de conversão ou OCR. Ele não substitui a publicação no Diário Oficial. Toda resposta do servidor traz o link fonte e esse aviso. - 📜 Artigo, parágrafo, inciso e alínea, com o caput como contexto e a citação pronta (art. 23, III). - 🔗 Cada resposta traz o link oficial (normas.leg.br, LexML) e o caminho no acervo. - ⚠️ Norma revogada, texto não compilado, dispositivo revogado ou vetado, trecho tachado.
README
leis-mcp é um servidor MCP que dá ao Claude Code, ao Claude Desktop, ao Cursor, ao VS Code, ao Codex e a qualquer cliente MCP acesso à legislação brasileira do repositório público ctresb/leis. Em vez de parafrasear de memória, o assistente busca a norma, lê o dispositivo e cita o texto exato, com a fonte oficial e os avisos de revogação.
ler_artigo("8245/1991", "23", inciso="III")
→ "III - restituir o imóvel, finda a locação, no estado em que o recebeu, salvo as deteriorações decorrentes do seu uso normal;"
[!IMPORTANT] O texto é convertido automaticamente das fontes oficiais e pode conter erros de conversão ou OCR. Ele não substitui a publicação no Diário Oficial. Toda resposta do servidor traz o link
fontee esse aviso.
Destaques
- 📜 Texto exato. Artigo, parágrafo, inciso e alínea, com o caput como contexto e a citação pronta (
art. 23, III). - 🔗 Sempre com fonte. Cada resposta traz o link oficial (
normas.leg.br, LexML) e o caminho no acervo. - ⚠️ Avisos automáticos. Norma revogada, texto não compilado, dispositivo revogado ou vetado, trecho tachado.
- 🗂️ Acervo inteiro. Normas federais, estaduais, municipais e de reguladores, com mais de 40 apelidos (
CLT,CDC,LGPD,lei do inquilinato…). - ⚡ Rápido e local. Índice SQLite pronto, atualizado toda semana, e conteúdo baixado sob demanda e conferido pelo hash do blob. O que está em cache funciona offline.
- 🔒 Só leitura. O repositório de origem nunca é alterado.
Início rápido
[!TIP] Usa o Claude Desktop e não quer mexer no terminal? Baixe o leis-mcp.mcpb e abra o arquivo. O Claude Desktop mostra a tela de instalação e cuida do resto, inclusive do Python.
Requisito: uv. O ripgrep (rg) é recomendado.
uvx leis-mcp index # baixa o índice pronto (~100 MB, só na primeira vez)
claude mcp add leis -- uvx leis-mcp serve
Pronto. Pergunte ao Claude: “O inquilino é obrigado a devolver o imóvel como recebeu? Cite a lei.”
[!TIP]
uvx leis-mcp warmpré-carrega as ~40 normas dos apelidos, para quebuscar_textosemnormajá tenha onde procurar.
Ferramentas
| Ferramenta | Para quê |
|---|---|
buscar_norma(referencia?, numero?, ano?, tipo?, esfera?, uf?, limite) |
Acha a norma e devolve os metadados do cabeçalho (título, ementa, data, revogada, versao_texto), o caminho, o link do GitHub e a fonte. Aceita "8.245", "8245/1991", "Lei 8.245/91", "Lei nº 8.245, de 18 de outubro de 1991", "LC 123/2006", "DL 5.452" e apelidos. |
ler_artigo(norma, artigo, paragrafo?, inciso?, alinea?, bloco?) |
Devolve o texto exato do dispositivo, o caput como contexto, a citação e os avisos. |
buscar_texto(consulta, norma?, esfera?, tipo?, ano?, uf?, limite) |
Procura uma palavra ou trecho numa norma (baixada na hora) ou em todas as normas já em cache. Ignora acentos e maiúsculas e indica o artigo de cada ocorrência. |
listar_normas(esfera?, tipo?, ano?, uf?, municipio?, orgao?, limite, offset) |
Navegação em níveis: esfera, depois tipo, UF ou órgão, depois ano, depois a lista de normas. |
Recurso leis://apelidos |
Lista os apelidos aceitos. |
Exemplos de perguntas
| Pergunta ao Claude | O que o servidor faz |
|---|---|
| “O inquilino é obrigado a devolver o imóvel como recebeu? Cite a lei.” | ler_artigo("lei do inquilinato", "23", inciso="III") |
| “A caução do aluguel pode ficar em poupança?” | ler_artigo("8245/1991", "38", paragrafo="2") |
| “Serviço mal feito: o que o CDC garante?” | ler_artigo("CDC", "20") |
| “Preciso de advogado no juizado especial?” | ler_artigo("9099/1995", "9") |
| “O que diz o ADCT, art. 10?” | ler_artigo("ADCT", "10") |
| “Onde a CLT fala em grupo econômico?” | buscar_texto("grupo econômico", norma="CLT") |
Clientes
Funciona em qualquer cliente MCP. Todos rodam o mesmo comando, uvx leis-mcp serve, depois de um uvx leis-mcp index. A maioria aceita esta configuração padrão:
{
"mcpServers": {
"leis": {
"command": "uvx",
"args": ["leis-mcp", "serve"]
}
}
}
[!NOTE] Apps de interface gráfica no macOS (Claude Desktop, Cursor, Windsurf) nem sempre herdam o
PATHdo terminal. Se o cliente não achar ouvx, troque"uvx"pelo caminho absoluto quewhich uvxmostra.
Docker
docker compose build
docker compose run --rm leis-mcp index
docker compose run --rm leis-mcp warm
docker compose run --rm -i leis-mcp serve # stdio
docker compose --profile http up leis-mcp-http # HTTP: http://localhost:8000/mcp
Os dados ficam no volume leis-data. Para registrar no Claude Code:
claude mcp add leis -- docker compose -f /caminho/para/leis-mcp/docker-compose.yml run --rm -i leis-mcp serve
No Claude Desktop, troque o comando por "command": "docker", "args": ["compose", "-f", "/caminho/para/leis-mcp/docker-compose.yml", "run", "--rm", "-i", "leis-mcp", "serve"].
HTTP
uvx leis-mcp serve --transport streamable-http --port 8000 # servido em /mcp
claude mcp add --transport http leis http://localhost:8000/mcp
Como funciona
flowchart LR
client["Assistentecliente MCP"] -- "stdio ou HTTP" --> server["leis-mcp"]
server --> index[("Índice SQLite1,2 M normas")]
server --> cache[("Cache por blob")]
cache -. "sob demanda,fixado no commit" .-> raw["raw.githubusercontent.comctresb/leis"]
index -. "download semanal" .-> release["Release 'index'deste repositório"]
index -. "--from-git" .-> clone["Clone levesó árvores"]
| Peça | O que faz |
|---|---|
| Índice pronto | Toda segunda-feira o workflow Index monta o índice e publica no release index (~100 MB em gzip). leis-mcp index baixa esse arquivo e confere o sha256 e o commit, sem precisar de git. |
| Clone leve | Com --from-git, git clone --depth 1 --filter=blob:none --sparse baixa só as árvores (~250 MB), sem o conteúdo das normas. |
| Índice SQLite | git ls-tree sobre o commit gera uma tabela com caminho, blob, esfera, tipo, ano, número, data, UF, município e órgão (~1,2 M linhas em ~6 s, ~350 MB). |
| Primeira execução | Sem índice, serve responde ao cliente na hora e prepara o índice em segundo plano. Até terminar, as ferramentas pedem para tentar de novo em instantes. |
| Conteúdo sob demanda | Cada norma é baixada do raw.githubusercontent.com fixada no commit indexado (~0,4 s), conferida contra o hash do blob git e guardada em cache/objects/. Se a rede falhar e houver clone, o fallback é git cat-file, lento na primeira vez (~30 s). |
| Parser | Encontra artigos, parágrafos, incisos e alíneas e tolera as variações reais do acervo. |
| Busca textual | Usa ripgrep nos arquivos em cache, ou Python puro se o rg não estiver instalado. |
Os dados ficam em ~/.cache/leis-mcp, configurável com LEIS_MCP_HOME.
CLI
Rode com uvx leis-mcp ou, no código-fonte, com uv run leis-mcp :
leis-mcp index # baixa o índice pronto (usa git se o download falhar)
leis-mcp index --from-git # clone leve + índice montado localmente
leis-mcp update # baixa o índice novo, se o commit mudou
leis-mcp update --from-git # git fetch + reindexação
leis-mcp status # commit indexado, total, itens em cache
leis-mcp warm # pré-carrega as leis dos apelidos
leis-mcp warm --no-aliases --sphere federal --kind leis-complementares
leis-mcp read "Lei 8.245/91" 23 -c III # testa sem cliente MCP (-p parágrafo, -c inciso, -s alínea, -b bloco)
leis-mcp serve # stdio (padrão)
Se o índice não existir, serve inicia na hora e prepara o índice em segundo plano. Rodar index antes evita que as primeiras perguntas recebam o aviso de “preparando”.
Testes
uv run pytest -m "not integration" # unitários, sem rede (fixtures pequenas)
uv run pytest # tudo, incluindo integração com conteúdo real e e2e MCP via stdio
Os testes de integração usam o índice de LEIS_MCP_HOME e são pulados se ele não existir. Eles cobrem a Lei 8.245/91 (art. 23, III e art. 38, § 2º), o CDC (art. 20, I), o CC (arts. 422 e 1.000), a Lei 9.099/95 (art. 9º), a CLT, a CF e o ADCT, e todos os apelidos. O teste e2e sobe o servidor por stdio com o cliente MCP oficial e chama todas as ferramentas.
Limitações
- Busca textual sem o acervo inteiro:
buscar_textosemnormaprocura só nas normas já em cache. Baixar as 1,2 M normas não é viável. Usewarmpara ampliar o cache. Não há busca semântica nem embeddings. - Ementas e títulos: só aparecem para normas já baixadas. O índice tem apenas o que se deduz do caminho.
- Referências ambíguas: sem ano (por exemplo,
"decreto 5452"), o servidor pede o ano.buscar_normalista as opções. - Qualidade do texto: a conversão automática e o OCR podem ter erros (por exemplo,
servir - se). O texto é devolvido como está e o parser não o corrige. - Revogação: o aviso depende do cabeçalho (
revogada,versao_texto) e das notas no próprio texto. Não há verificação independente de vigência. - Metadados de normas não federais: o número e a data de normas estaduais, municipais e de reguladores vêm de heurísticas sobre o nome do arquivo.
- Rede: o conteúdo vem do
raw.githubusercontent.com, que pode impor limite de requisições. O que já está em cache funciona offline.
Créditos
O acervo é o ctresb/leis, que converte as normas das fontes oficiais para Markdown. O leis-mcp só lê esse repositório. A trilha do vídeo é Intergalactic, de Alex Jones / Xander Jones, da Biblioteca de áudio do YouTube.
Install
uvx leis-mcp serveConfiguration
{
"mcpServers": {
"leis": {
"command": "uvx",
"args": ["leis-mcp", "serve"]
}
}
}