ML

mazulo/leis-mcp

Developer tools
52 stars 0 forks Quality 65 Trend 37

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 fonte e 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 warm pré-carrega as ~40 normas dos apelidos, para que buscar_texto sem norma já 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 PATH do terminal. Se o cliente não achar o uvx, troque "uvx" pelo caminho absoluto que which uvx mostra.

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_texto sem norma procura só nas normas já em cache. Baixar as 1,2 M normas não é viável. Use warm para 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_norma lista 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.

View the full README on GitHub

Install

uvx leis-mcp serve
New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "leis": { "command": "uvx", "args": ["leis-mcp", "serve"] } } }