CREG MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CREG MCP Server¿está vigente la resolución CREG 030 de 2018?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
CREG MCP Server
An MCP (Model Context Protocol) server for querying the regulation of Colombia's Energy and Gas Regulatory Commission (CREG, Comisión de Regulación de Energía y Gas). Claude Desktop, Claude Code or any other MCP client can search CREG resolutions and legal opinions (conceptos), read them in chunks or by searching inside, and see each rule's regulatory graph: which law it rests on, what it repeals or amends, and what later repealed or amended it.
What sets it apart from a search engine is that validity is not typed in by hand: it is computed from the texts themselves. Every read starts with the rule's computed status (its effective-date clause and the repeals found in the corpus, with the evidence), so a repealed resolution is not cited as current. For example, CREG 030 of 2018 comes out repealed by CREG 174 of 2021.
The documents are in Spanish, as published by the CREG; tool names and outputs are in Spanish too.
Tools
Tool | What it does |
| Corpus inventory by topic and document type |
| Keyword search, filtered by topic and type ( |
| Reads a rule in chunks ( |
| Regulatory graph of a rule ( |
Each tool takes a single params object, for example creg_relaciones(params={"norma": "030 de 2018"}).
Suggested use: creg_buscar to find the rule, creg_relaciones to know where to look, creg_leer_documento to cite. The graph tells you where to look; the citation comes from what you read.
Related MCP server: lex-provenance-mcp
Corpus
CREG resolutions and opinions in Markdown, shipped inside the package (src/creg_mcp/corpus/), organised by topic: renewables and distributed generation (AGPE, GD), trading and wholesale market, distribution and grid connection, metering, tariffs, reliability charge, non-interconnected zones (ZNI) and energy storage. The full list is in corpus.txt.
CREG texts only: no technical standards (IEC, IEEE, NTC), which are copyrighted, and no laws, decrees or RETIE.
Only the text of the rule: handwritten working summaries are not included.
It is a dated selection, not the whole of CREG regulation. A rule outside the corpus shows up in the graph as "fuera del repositorio" and cannot be read through the server: do not cite it as read.
To use another corpus with the same layout (
<topic>/resoluciones|conceptos/*.md), setCREG_MCP_CORPUSto its path.
Installation
Requires Python 3.10 or later.
git clone https://github.com/jpsalamanca-co/creg-mcp.git
cd creg-mcp
pip install -e ".[dev]" # [dev] adds pytest, pytest-asyncio and ruff
python -m pytest tests -qClient configuration
Claude Desktop (claude_desktop_config.json) or Claude Code (.mcp.json):
{
"mcpServers": {
"creg": {
"command": "creg-mcp",
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}To run it directly over stdio: creg-mcp or python -m creg_mcp.server. Quick check without a client: creg-mcp --test.
Tests
python -m pytest tests -q checks that:
the corpus holds only CREG resolutions and opinions, with no handwritten summaries, and matches
corpus.txt;CREG 030 of 2018 comes out repealed by 174 of 2021, and 174 of 2021 comes out in force;
reads cannot escape the corpus folder;
over stdio, the server lists its four tools and answers a rule's graph.
Scope
A lookup tool, not legal advice. Computed validity comes from the rules written in vigencia.py applied to the corpus in the package: a later rule that is not in the corpus cannot be taken into account. Before applying a rule, confirm its text and status at the CREG's official source.
License
Code: MIT, see LICENSE. The CREG texts are official documents published by the Commission; see NOTICE.md.
Available Tools
4 toolscreg_buscarARead-onlyIdempotent
Busca documentos regulatorios del sector eléctrico colombiano por palabra clave.
Busca en títulos, temas, nombres de archivo y resúmenes de los documentos .md del repositorio. Útil para encontrar resoluciones CREG, conceptos jurídicos, leyes y decretos sobre FNCER, generación distribuida, tarifas, conexión, etc.
Args: params (BuscarInput): Parámetros de búsqueda: - query (str): Palabra clave (ej: 'AGPE', 'excedentes', 'solar') - categoria (Optional[str]): Filtrar por categoría - tipo (Optional[str]): 'resolucion', 'concepto', o 'decreto' - limite (int): Máximo resultados (default 10) - todos (bool): exigir todos los términos. Por defecto la búsqueda puntúa término a término (OR): 'zanahoria AGPE' devuelve lo mismo que 'AGPE'.
Returns: str: Resultados en Markdown con título, categoría, tipo y ruta de cada documento.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/openWorld=false. The description adds non-obvious behavioral detail about scoring semantics: the default OR behavior and how 'todos' switches to AND, which is real value an agent cannot get from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence, then a well-organized Args/Returns layout. Slightly redundant to repeat the OR explanation in both the Args entry and the todos field, but overall tight and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, search surface, all parameters, and even the return format despite an output schema existing. Missing only explicit sibling routing, which is the one gap for a tool that sits alongside three related search/read tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Top-level schema coverage is 0%, so the description must carry the parameter burden, and its Args block documents all five fields (query, categoria, tipo, limite, todos) with examples and the OR/AND semantics. Minor flaw: it lists 'decreto' as a valid tipo while the schema restricts tipo to 'resolucion' or 'concepto' — a small inconsistency.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Busca) and resource (documentos regulatorios del sector eléctrico colombiano) plus the exact search surface (títulos, temas, nombres de archivo, resúmenes de los .md). This clearly distinguishes it from siblings like creg_leer_documento and creg_listar_categorias without needing their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete context for when to reach for it ('Útil para encontrar resoluciones CREG, conceptos jurídicos, leyes y decretos sobre FNCER, generación distribuida, tarifas, conexión'). However it never names the alternatives (creg_listar_categorias, creg_leer_documento, creg_relaciones) or states when NOT to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
creg_leer_documentoARead-onlyIdempotent
Lee el contenido completo de un documento regulatorio .md del repositorio.
Dado la ruta relativa de un documento (obtenida de creg_buscar), retorna su contenido en Markdown. Incluye la tabla de metadata y el texto completo de la resolución, concepto o decreto.
Antepone la vigencia CALCULADA por vigencia.py desde la propia norma (cláusula de vigencia y derogatorias del corpus). Esa es la que se cita, no la fila Estado del documento.
Varias normas pasan de 50 000 caracteres (la 174/2021 tiene más de 200 000):
para citar un artículo, localizarlo con buscar y leerlo con desde.
Args: params (LeerDocumentoInput): Parámetros: - ruta (str): Ruta relativa del documento - max_caracteres (int): Límite de caracteres (default 8000) - desde (int): Posición desde la que leer (default 0) - buscar (str): Texto a localizar; devuelve fragmentos con su posición
Returns:
str: Vigencia calculada y el tramo pedido del documento, o los fragmentos
donde aparece buscar.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description adds substantial behavior beyond them: the vigencia shown is CALCULATED by vigencia.py rather than read from the Estado row, documents can exceed 50,000 chars (174/2021 over 200,000), the response tells you the next 'desde', and 'buscar' matches case- and accent-insensitively.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then workflow, then a structured Args/Returns block; every section is useful. There is mild duplication between the Args block and the schema descriptions, and the Returns line restates the vigencia/pagination point already made above.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-argument read tool with full annotation coverage, the description supplies everything an agent needs: where the path comes from, how vigencia is derived, how to paginate long documents, and how to locate text. An output schema exists, yet the description is still clear about what comes back.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With reported schema coverage at 0% for the top-level param, the description's Args block documents all four fields with defaults (ruta, max_caracteres=8000, desde=0, buscar) and explains their pagination relationship. It does not mention the 500–50,000 bound on max_caracteres or the length limits on 'buscar', so it is strong but not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lee el contenido completo de un documento regulatorio .md del repositorio') and names the sibling that produces the input path ('Dado la ruta relativa de un documento (obtenida de creg_buscar)'), so an agent can distinguish it from creg_buscar without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context and a concrete workflow: obtain 'ruta' from creg_buscar, and for citing an article locate it with 'buscar' then read with 'desde'. It does not address when to prefer this over siblings like creg_relaciones or creg_listar_categorias, so it stops short of explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
creg_listar_categoriasARead-onlyIdempotent
Lista las categorías del repositorio regulatorio CREG con conteo de documentos.
Retorna un resumen del inventario: cuántas resoluciones, conceptos y decretos hay en cada carpeta temática. Útil para entender qué regulación está disponible antes de buscar documentos específicos.
Returns: str: Resumen en Markdown con categorías y conteos.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower. The description adds genuine context beyond them: the inventory is broken down by document type and thematic folder, and it is a pre-search orientation step rather than a retrieval tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and the prose is short, but the 'Returns: str: Resumen en Markdown con categorías y conteos' block restates the earlier 'Retorna un resumen del inventario' line and is redundant given an output schema already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only listing tool with an output schema and full annotation coverage, the description supplies everything needed to select and call it: what is listed, how results are grouped, and why to call it. Only the redundant return-value restatement keeps it from being fully tight.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which is the baseline-4 case, and schema coverage is 100%. There is nothing for the description to compensate for; the absence of parameter discussion is appropriate rather than a gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lista las categorías del repositorio regulatorio CREG') and adds scope detail ('conteo de documentos', 'cuántas resoluciones, conceptos y decretos'). The functional routing line distinguishes it from the search-oriented siblings, but it never names an alternative, so it stops short of the top band.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Útil para entender qué regulación está disponible antes de buscar documentos específicos' gives a clear when-to-use and implicitly positions it ahead of creg_buscar. There are no explicit exclusions or named alternatives, so it is clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
creg_relacionesARead-onlyIdempotent
Muestra de dónde viene una norma, qué deroga o modifica y quién la derogó o modificó.
Sale de grafo.py, que lee las cláusulas de los propios textos (deroga, modifica, adiciona, sustituye, "derogado por" en las anotaciones del Gestor, y las leyes invocadas en el preámbulo). Cada relación trae la cita y la ruta del documento para abrirlo.
NO sustituye la lectura: para citar una norma, aunque sea para decir que está derogada, abrir su documento con creg_leer_documento. Esto dice dónde mirar; la cita sale de lo leído.
Args: params (RelacionesInput): norma ('174 de 2021' o ruta) y profundidad (1-3).
Returns: str: Árbol en texto con fundamento, predecesoras, reemplazos, proyectos y conceptos que la mencionan.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring readOnlyHint, idempotentHint, and destructiveHint=false, the description adds substantial behavioral context: it explains the data source (grafo.py reading clauses, annotations, and preamble invocations) and states that each relationship includes the citation and document path needed to open it. It also describes the return structure (fundamento, predecesoras, reemplazos, proyectos, conceptos).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and is structured into useful sections (source, warning, Args, Returns). It is somewhat long due to internal implementation detail about grafo.py, but most sentences earn their place by clarifying provenance, limitations, or output shape.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema existing, the description helpfully explains the return tree's categories and emphasizes that citations must be read from the source document. Combined with annotations covering safety and idempotence, this gives the agent enough context to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents norma's accepted formats and profundidad's 1-3 depth semantics in detail, so the description's Args line ('norma ... y profundidad (1-3)') only restates them at a high level. The description adds no new format or behavior detail beyond the schema, making the baseline 3 appropriate where schema text carries the meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Muestra') and resource ('de dónde viene una norma, qué deroga o modifica y quién la derogó o modificó'), making the tool's purpose concrete. It also distinguishes itself from the sibling creg_leer_documento by warning that it does not replace reading the source document.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when not to use it and what to use instead: 'NO sustituye la lectura: para citar una norma, aunque sea para decir que está derogada, abrir su documento con creg_leer_documento.' It also identifies the tool's role as showing where to look, not providing the citation itself.
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.
4 tool updates
v0.1.0- First observed
creg_buscar - First observed
creg_leer_documento - First observed
creg_listar_categorias - First observed
creg_relaciones
TDQS
Scored across 4 tools
Each tool targets a clearly distinct operation: listing categories, searching, reading full content, and exploring normative relations. There is no meaningful overlap—creg_buscar locates documents, creg_leer_documento reads them, and creg_relaciones maps their lineage. An agent can easily pick the right tool.
All names share a consistent `creg_` prefix and are in Spanish, with clear verb_noun forms (listar_categorias, buscar, leer_documento). The minor deviation is creg_relaciones, which is a noun rather than a verb, slightly breaking the otherwise uniform action-oriented pattern.
Four tools is well-scoped for a read-only regulatory repository: inventory, search, retrieval, and relationship mapping. Each tool earns its place and none is redundant. Nothing feels thin or bloated.
For a read-only corpus, the surface covers the full lifecycle of discovery (list categories), search, full-text reading with pagination, and cross-reference/derogation mapping. No obvious gaps remain for the stated purpose of finding and citing Colombian electric-sector regulation.
Maintenance
Related MCP Connectors
- LegalizeOAuthdev.legalize
Official MCP connector for Legalize: read and search its whole open corpus, at any point in time.
Brazilian legal stack in one MCP: lawsuits, court publications, case law, tenders, certificates.
Public Indian legal search MCP for Roop judgments, statutes, and corpus grounding.
Resolve, search and verify legal citations against the official sources, with provenance.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for searching and extracting official announcements, decrees, and resolutions from the Argentine Official Gazette (Boletín Oficial de la República Argentina). It enables LLMs to perform real-time searches and retrieve verbatim legal text with complete juridical fidelity.1419 npm3MIT
- AlicenseNot gradedqualityBmaintenanceA read-only MCP connector for searching, fetching, and citing provenance-tracked legal corpora with verifiable content hashes.Apache 2.0
- AlicenseNot gradedqualityFmaintenanceEnables querying Spanish legislation (BOE) and EU law integration through MCP, providing full-text search, citation validation, and cross-referencing capabilities.34 npm2Apache 2.0
- AlicenseNot gradedqualityBmaintenanceAn MCP server for querying Colombian legislative norms and their current legal effect, with read-only tools for normativity search and validity consultation. It provides provenance-backed data with explicit citations to official sources.MIT