Skip to main content
§ leis-mcp: a lei exata, direto no seu assistente de IA

Busque e cite o texto oficial de mais de 1,2 milhão de normas brasileiras sem sair do seu assistente.

PyPI CI Python 3.12+ MCP Normas uv Docker License: MIT

Início rápido · Ferramentas · Clientes · Como funciona · Limitações


Demonstração do leis-mcp em vídeo (25 s): o assistente devolve o texto exato da Lei do Inquilinato, art. 23, III

Clique na imagem para ver a demonstração (25 s, com música).


leis-mcp é um servidor MCP que dá ao Claude Code, ao Claude Desktop 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;"

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 em ~6 s, 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

Requisitos: uv e git. O ripgrep (rg) é recomendado.

uvx leis-mcp index                          # clone leve + índice (~1 min 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."

A partir do código-fonte
git clone https://github.com/mazulo/leis-mcp && cd leis-mcp
uv sync
uv run leis-mcp index
claude mcp add leis -- uv --directory "$PWD" run leis-mcp serve

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.
Exemplo de resposta de ler_artigo("8245/1991", "23", inciso="III")
{
  "norma": {"titulo": "Lei nº 8.245 de 18/10/1991", "ementa": "Dispõe sobre as locações dos imóveis urbanos…",
            "revogada": false, "versao_texto": "compilada (texto vigente)",
            "caminho": "federal/leis-ordinarias/1991/lei-8245-1991-10-18.md"},
  "dispositivo": {"citacao": "art. 23, III",
                  "texto": "III - restituir o imóvel, finda a locação, no estado em que o recebeu, salvo as deteriorações decorrentes do seu uso normal;",
                  "caput": "**Art. 23.** O locatário é obrigado a:"},
  "avisos": [],
  "fonte": "https://normas.leg.br/?urn=urn:lex:br:federal:lei:1991-10-18;8245",
  "aviso_legal": "Texto convertido automaticamente das fontes oficiais (…). Não substitui a publicação no Diário Oficial."
}
Apelidos aceitos
  • Constituição: constituição/CF, ADCT
  • Códigos: código civil/CC, CPC, código penal/CP, CPP, CLT, CDC, CTN, CTB, código eleitoral, código florestal
  • Estatutos: ECA, estatuto do idoso, estatuto da OAB, estatuto da cidade, estatuto do desarmamento, LBI
  • Leis: lei do inquilinato, lei dos juizados, LGPD, marco civil da internet, maria da penha, nova lei de licitações, lei de improbidade administrativa, lei de drogas, LEP, lei de falências, LINDB, lei do mandado de segurança, lei da ação civil pública, LAI, LRF, simples nacional, lei anticorrupção, lei de arbitragem, lei de abuso de autoridade

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

Claude Code

claude mcp add leis -- uvx leis-mcp serve

Use -s user para disponibilizar em todos os projetos e -s project para gravar em .mcp.json.

Claude Desktop

Em claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/):

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

Se o Desktop não achar o uvx, use o caminho absoluto (which uvx).

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["Assistente<br>cliente MCP"] -- "stdio ou HTTP" --> server["leis-mcp"]
    server --> index[("Índice SQLite<br>1,2 M normas")]
    server --> cache[("Cache por blob")]
    cache -. "sob demanda,<br>fixado no commit" .-> raw["raw.githubusercontent.com<br>ctresb/leis"]
    index -. "git ls-tree" .-> clone["Clone leve<br>só árvores"]
Peça O que faz
Clone leve 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). Não usa rede.
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/<blob>. Se a rede falhar, 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.

Variações que o parser reconhece
  • Artigos: **Art. 1º**, Art. 1o, Art. 1.º, Art. 10., Art. 1.000., Art. 4º-A, Art. 359-M-A, artigo sem negrito e Art. l97. (OCR que troca 1 por l).
  • Parágrafos: § 2º, § 2°, §2º, § 3º-A, Parágrafo único.
  • Incisos e alíneas: incisos com -, –, — (com ou sem espaço) e alíneas a).
  • Fim do artigo: o artigo termina no próximo artigo, num título (#) ou na assinatura (Brasília, ...).
  • Numeração reiniciada: quando a numeração recomeça na mesma norma (CF + ADCT, o decreto-lei que aprova a CLT), o texto é dividido em blocos. Por padrão vale o maior bloco, e bloco="transitórias" escolhe outro.
Estrutura do código
src/leis_mcp/
  config.py, models.py, errors.py, text.py
  messages.py        todo texto devolvido ao usuário (pt-BR)
  catalog/           GitRepository, PathParser, IndexBuilder / NormIndex (SQLite)
  references/        ReferenceParser + tabelas de apelidos
  content/           FrontMatterParser, ContentStore (cache por blob)
  legal_text/        labels (Art., §, inciso, alínea), DocumentParser, ProvisionExtractor, notices
  search/            AccentInsensitivePattern, RipgrepEngine / PythonEngine, TextSearch
  services/          NormResolver, NormLoader, NormPresenter, LegislationService (fachada)
  server/            LeisServer: adaptador MCP (nomes de ferramentas e parâmetros em pt-BR)
  cli.py             Cli: serve, index, update, status, warm, read

O código é em inglês; só o que chega ao usuário (respostas, erros, descrições das ferramentas) é pt-BR.

CLI

Rode com uvx leis-mcp <comando> ou, no código-fonte, com uv run leis-mcp <comando>:

leis-mcp index                         # clone leve + índice
leis-mcp update                        # 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 gera o índice antes de iniciar. Ainda assim, rode index antes para o cliente não esperar.

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.

Metadata

Release files for leis-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for leis-mcp 0.1.0
File Size Uploaded Provenance Actions
leis_mcp-0.1.0.tar.gz 43.0 kB With provenance Details for leis_mcp-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for leis-mcp 0.1.0
File Interpreter ABI Platform Actions
leis_mcp-0.1.0-py3-none-any.whl Python 3 none any Details for leis_mcp-0.1.0-py3-none-any.whl

Total release size: 96.5 kB

Release files / leis_mcp-0.1.0.tar.gz

Download URL leis_mcp-0.1.0.tar.gz
Size 43.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d9718258016a0ec209517f80a14d8a290bfbd9e2235d9baffa0592afcec499eb
BLAKE2b-256 checksum
How to use checksums
8a046514863109512d4598c805b529b05ce50b70c9c8ec98231d89348e1336c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / leis_mcp-0.1.0-py3-none-any.whl

Download URL leis_mcp-0.1.0-py3-none-any.whl
Size 53.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1916cf8a58bead1606576d6d4da8c6e5a51887ac53a9582d7dfb652f0a7279c3
BLAKE2b-256 checksum
How to use checksums
667e9009a97faaa2e249fd0444e6610aca79c60ccd95ba19881e0817a0c34524
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for leis-mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for leis_mcp-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page