Skip to main content
Glama

LeXML-mcp

MCP server for LexML Brasil — search the legislative SRU acervo, resolve URNs, and inspect service metadata. Built with FastMCP + httpx.

Features

Tool

Description

lexml_search

Search the LexML SRU acervo with CQL queries

lexml_resolve_urn

Resolve a LexML URN to its public URL

lexml_explain

Retrieve metadata about the SRU service

Every response includes a provenance envelope (source_url, source_kind, authority, retrieved_at, content_hash, backend_name, backend_version, schema_version).

Related MCP server: MCP-LEI

Quick start

# Install
uv sync

# Run the server (stdio transport)
uv run lexml-mcp

The server listens on stdio — configure your MCP client to launch it:

{
  "mcpServers": {
    "lexml": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/LeXML-mcp", "lexml-mcp"]
    }
  }
}

Usage examples

# Search for documents about consumer protection law
result = await lexml_search(
    query='dc.title any "código de defesa do consumidor"',
    start_record=1,
    maximum_records=10,
    record_schema="dc"
)

Returns structured records with Dublin Core fields, number_of_records, next_record_position, and provenance.

lexml_resolve_urn

# Resolve a URN to its public URL
result = await lexml_resolve_urn(
    urn="urn:lex:br:federal:lei:1990-09-11;8078"
)

Returns public_url, status_code, redirect_chain, and provenance.

lexml_explain

# Inspect SRU service capabilities
result = await lexml_explain()

Returns SRU explain record data with server info, database info, and supported schemas.

Challenge detection

The SRU endpoint may return an HTML verification page instead of XML. The server detects this and returns a structured object:

{
  "is_challenge_like": true,
  "content_type": "text/html",
  "raw_excerpt": "<!DOCTYPE html>...",
  "status_code": 200,
  "provenance": { ... }
}

Error handling

All errors are returned as structured objects — never crashes:

Error type

Trigger

network_error

Connection refused, DNS failure

timeout

Request exceeded timeout (default 15s)

invalid_xml

SRU returned malformed XML

http_error

Non-2xx HTTP status

Caching

LRU cache with configurable TTL (default 300s, max 256 entries). Challenges are never cached as successes. Configure via environment:

  • LEXML_CACHE_TTL — seconds (default 300)

  • LEXML_CACHE_MAXSIZE — max entries (default 256)

Configuration

Env variable

Default

Description

LEXML_SRU_URL

https://www.lexml.gov.br/busca/SRU

SRU endpoint

LEXML_URN_TEMPLATE

https://www.lexml.gov.br/urn/{urn}

URN resolution template

LEXML_TIMEOUT

15.0

HTTP request timeout (seconds)

LEXML_CACHE_TTL

300

Cache TTL (seconds)

LEXML_CACHE_MAXSIZE

256

Max cache entries

Project structure

src/lexml_mcp/
├── server.py              # FastMCP server, tool registration
├── config.py              # Environment-based configuration
├── connectors/
│   └── acervo.py          # SRU search, explain, URN resolution
├── models/
│   ├── provenance.py      # Provenance envelope
│   ├── search.py          # Search result models
│   └── error.py           # Structured error objects
└── utils/
    ├── cache.py           # LRU TTL cache
    └── challenge.py       # Challenge HTML detection

Testing

uv run pytest

29 tests covering:

  • SRU success parsing (Dublin Core records)

  • Challenge HTML detection

  • Malformed XML handling

  • Timeout simulation

  • URN resolution

  • Explain response parsing

  • Provenance envelope construction

  • Cache set/get/expiry/eviction

  • Structured error types

  • Tool registration

Limitations

  • Parser, linker, renderer not implemented — these require JVM/Scala/Haskell infrastructure and are roadmap items

  • SRU endpoint may return challenge HTML — the server detects and reports this transparently

  • No multi-tenancy — single-user, local-first design

  • No DOCX output — renderer integration is future scope

  • No Unicode normalization — preserves original content as-is

  • No external health checks — liveness is local only

Dependencies

  • mcp — official Python SDK (FastMCP)

  • httpx — async HTTP client

  • stdlib only beyond those two

License

GPL-3.0-or-later

Available Tools

3 tools
lexml_explainA

Retrieve metadata about the LexML SRU service (explain operation).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior2/5

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

With no annotations, the description carries full burden. It only states 'retrieve metadata' but fails to disclose any behavioral traits (e.g., authentication, rate limits, data format).

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?

Single sentence, front-loaded, zero waste. Perfectly concise for a simple tool.

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?

Given zero parameters and no output schema, the description is mostly complete. Minor gap: could mention what metadata is returned (e.g., service capabilities).

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?

No parameters exist, so schema coverage is 100%. The description adds nothing beyond the schema but is not required to. Baseline 4 applies.

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

Purpose5/5

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

The description uses specific verb 'retrieve' and resource 'metadata about the LexML SRU service', clearly stating what the tool does and distinguishing it from siblings (search and resolve URN).

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus lexml_search or lexml_resolve_urn. Usage is implied but not explicit.

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

lexml_resolve_urnA

Resolve a LexML URN to its public URL.

Args: urn: LexML URN (e.g. 'urn:lex:br:federal:lei:1990-09-11;8078') verify: If True, follow redirects and validate final host (SSRF guard). Default False — only constructs the URL without network call.

ParametersJSON Schema
NameRequiredDescriptionDefault
urnYes
verifyNo

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It explains the verify parameter's behavior: default False constructs URL without network call, True follows redirects and validates host (SSRF guard). This is important for security and safety.

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?

The description is concise with two paragraphs and an Args list. First sentence states purpose. Every sentence provides value, no fluff.

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?

Given 2 parameters and no output schema, the description covers parameter behavior and the two modes of operation. It mentions SSRF guard. Return format (URL string) is implied. Sufficient for the tool's simplicity.

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 0% so description must compensate. It explains both parameters: urn with example format, verify with behavioral effect. This adds meaningful context beyond the schema's type/title.

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

Purpose5/5

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

The description clearly states the verb 'Resolve' and the resource 'LexML URN to its public URL'. It distinguishes itself from siblings by focusing on resolution, while lexml_search and lexml_explain have different purposes.

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 description does not explicitly state when to use this tool versus alternatives. It implies usage for resolving a specific URN, but lacks clear guidance on when not to use or which sibling to choose.

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. Dates show when Glama detected each change.

  1. 3 tool updatesv0.2.0
    • First observedlexml_explain
    • First observedlexml_resolve_urn
    • First observedlexml_search

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search for documents, resolve URNs to URLs, and retrieve service metadata. No overlap.

Naming Consistency5/5

All tool names follow the consistent pattern 'lexml_verb' (search, resolve_urn, explain), making them predictable.

Tool Count5/5

Three tools cover the core functionality of searching, resolving identifiers, and explaining the service—well-scoped for a legal document server.

Completeness4/5

Covers search (with flexible filters), URN resolution, and service info. Missing direct document retrieval, but URN resolution provides URL for fetching.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prof-ramos/LeXML-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server