Skip to main content
Glama

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

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;"
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 linkfonte 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 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.

Related MCP server: Advogado PT MCP Server

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."

TIP

uvx leis-mcp warm pré-carrega as ~40 normas dos apelidos, para que buscar_texto sem norma já tenha onde procurar.

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.

{
  "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."
}
  • 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.

  • 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.

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.

Available Tools

4 tools
buscar_normaA
Read-onlyIdempotent

Localiza uma norma e devolve metadados do cabeçalho (título, ementa, data, revogada, versão do texto), caminho no repositório e link oficial da fonte.

NameRequiredDescriptionDefault
ufNoUF, para normas estaduais (ex.: 'SP').
anoNoAno (4 dígitos).
tipoNoTipo: 'lei', 'lei complementar', 'decreto-lei', 'decreto', 'medida provisória', 'emenda constitucional' ou nome do diretório ('leis-ordinarias').
esferaNofederal, estaduais, municipais, reguladores, jurisprudencia ou tratados.
limiteNoMáximo de resultados (1 a 50).
numeroNoNúmero da norma (alternativa a `referencia`).
referenciaNoReferência livre: 'Lei 8.245/91', '8245/1991', '8.245', 'LC 123/2006', 'DL 5.452', ou apelido ('CDC', 'CLT', 'código civil', 'constituição').

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and openWorld, so the safety profile is covered. The description adds genuine value by disclosing the exact return payload (header metadata including 'revogada' and 'versão do texto', repository path, official link), which tells the agent what it will get back.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that packs the action and the return contents with no filler. Slightly dense but every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full parameter coverage, the description need only frame the tool's role, which it does. The return-value enumeration is mildly redundant with the output schema but harmless, and nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (uf, ano, tipo, esfera, limite, numero, referencia) is already documented in the schema. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Localiza') and resource ('uma norma') and enumerates what is returned (cabeçalho metadata, repository path, official source link). It is clearly distinct from ler_artigo and buscar_texto by implication, though it never names the siblings to sharpen the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the verb 'Localiza' and the returned metadata; there is no explicit statement of when to prefer this over listar_normas or buscar_texto, nor guidance on choosing between the 'referencia' and 'numero' lookup paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

buscar_textoA
Read-onlyIdempotent

Busca um termo dentro de uma norma, ou nas normas já em cache local, indicando o artigo de cada ocorrência.

NameRequiredDescriptionDefault
ufNoFiltro de UF.
anoNoFiltro de ano.
tipoNoFiltro de tipo.
normaNoRestringe a uma norma (baixada sob demanda). Sem isso, busca só nas normas já em cache local.
esferaNoFiltro de esfera.
limiteNoMáximo de ocorrências (1 a 100).
consultaYesPalavra ou trecho (ignora maiúsculas e acentos).

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety and idempotency are covered. The description adds the cache vs. on-demand scope distinction and the fact that results are annotated with the article number, but omits behavioral traits like accent/case normalization and the on-demand download side effect (which the schema, not the description, carries).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the scope ('dentro de uma norma, ou nas normas já em cache local') front-loaded before the result-shape clause. No filler, nothing repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 7 documented parameters, annotations and an output schema, the description only needs to convey purpose and scope, which it does. The remaining gap is the absence of any sibling routing or pagination/limit expectation, minor given the structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (uf, ano, tipo, norma, esfera, limite, consulta) is already documented with its filter semantics and defaults. The description contributes no additional parameter meaning such as filter combination behavior or how empty filters interact, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (busca) and resource (um termo dentro de uma norma / nas normas em cache), and adds the output shape (indica o artigo de cada ocorrência). That distinguishes it reasonably from buscar_norma and listar_normas, but it never names a sibling explicitly, so differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'dentro de uma norma, ou nas normas já em cache local' implicitly tells the agent there are two modes (targeted vs. cache-only), which is useful context. However, there is no explicit when-to-use guidance and no routing against buscar_norma or ler_artigo for overlapping intent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ler_artigoA
Read-onlyIdempotent

Devolve o texto exato de um artigo (ou parágrafo, inciso, alínea), com o caput como contexto, link da fonte e avisos de revogação ou texto não compilado.

NameRequiredDescriptionDefault
blocoNoQuando a numeração reinicia na norma (ex.: ADCT na CF), trecho do título do bloco ('transitórias') ou índice.
normaYesNorma: '8245/1991', 'Lei 8.245/91', apelido ('CDC', 'CLT', 'CF', 'ADCT') ou caminho no repositório.
alineaNoAlínea: 'a', 'b'...
artigoYesArtigo: '23', '9º', '4-A', '1.000'.
incisoNoInciso em romano ('III') ou número (3).
paragrafoNoParágrafo: '2', '2º' ou 'único'.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld), and the description adds genuinely new behavioral context: results include the caput as context, a source link, and warnings when the text is revoked or not yet compiled. The missing piece is failure behavior (what happens for a nonexistent article or ambiguous norma), but the added warnings materially change how an agent should interpret output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the core action and packs scope, hierarchy, and return context without waste. No preamble, no restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 6 parameters, 100% schema coverage, an output schema, and readOnly/idempotent annotations, the description covers purpose plus the notable return traits (caput context, source link, revocation/uncompiled warnings). It falls short only on error/ambiguity behavior and on routing guidance relative to the three sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the property descriptions are already rich (norma accepts '8245/1991', 'CDC', 'CF', repository path; inciso accepts roman or numeral; bloco covers numbering restarts like ADCT). The description only echoes the hierarchy ('artigo, parágrafo, inciso, alínea') without adding format or composition rules, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Devolve o texto exato') and resource (artigo, with paragraph/inciso/alinea granularity), plus what accompanies it (caput context, source link, revocation warnings). It is clear what the tool does, but it never contrasts itself with siblings like buscar_texto or buscar_norma, so an agent must infer whether this is a lookup by exact article or a search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the description's emphasis on 'texto exato' plus the artigo/paragrafo/inciso/alinea hierarchy signals it is for fetching one known provision, not for searching. There is no explicit when-to-use/when-not or pointer to buscar_texto for discovery, which is exactly the distinction an agent needs most here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listar_normasA
Read-onlyIdempotent

Navega pelo acervo: sem filtros devolve contagens por esfera; com esfera, por tipo; com tipo, por ano; com ano, lista as normas.

NameRequiredDescriptionDefault
ufNoUF (estaduais/municipais).
anoNoAno. Vazio: contagem por ano.
tipoNoTipo (ex.: 'leis-ordinarias'). Vazio: contagem por tipo/UF/órgão.
orgaoNoÓrgão regulador ou tribunal (ex.: 'anvisa', 'stf').
esferaNofederal, estaduais, municipais, reguladores, jurisprudencia, tratados. Vazio: contagem por esfera.
limiteNoItens por página (1 a 200).
offsetNoDeslocamento para paginação.
municipioNoMunicípio (slug, ex.: 'rio-branco').

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds genuine value beyond them by disclosing that the RESPONSE SHAPE changes with the parameters (counts vs. a listed set), which is the single most important behavioral fact for this tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that conveys the entire drill-down contract with zero filler. Nothing could be removed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover safety, so the description's main job is the drill-down logic, which it delivers. The remaining gap is that the uf/orgao/municipio filters and pagination are never mentioned in prose, leaving the agent to discover them from the schema alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description goes further by explaining the conditional semantics of esfera/tipo/ano — that each successive filter changes what is returned. It says nothing about uf, orgao, municipio, limite or offset, which the schema covers on its own.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Navega pelo acervo') and precisely describes the drill-down shape of the operation (sem filtros → por esfera → por tipo → por ano → lista). This clearly separates it from search-style siblings like buscar_norma or buscar_texto, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The progressive filter chain implicitly tells the agent this is the exploratory/browse entry point that feeds the other tools, but there is no explicit 'use this when…' or 'use buscar_norma instead when…' guidance. An agent must infer the distinction from behavior alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedbuscar_norma
    • First observedbuscar_texto
    • First observedler_artigo
    • First observedlistar_normas

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation4/5

The four tools target distinct retrieval actions: locating a norm, reading a specific article, searching within text, and browsing the collection. There is slight potential overlap between buscar_norma and listar_normas for discovering norms, but the descriptions make their roles sufficiently clear.

Naming Consistency5/5

All tool names follow a consistent Portuguese verb_noun pattern in snake_case: buscar_norma, ler_artigo, buscar_texto, listar_normas. The repeated verb buscar is used predictably for two different search scopes.

Tool Count5/5

Four tools is a well-scoped set for a legal norm retrieval server. Each tool covers a distinct core operation, and none appears redundant or merely decorative.

Completeness4/5

The surface covers the main read-only workflows: browsing norms, locating a norm, reading an article, and searching text. A minor gap is the lack of a direct way to retrieve an entire norm or list its article structure without relying on search or known article numbers.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers