mcp-colombia-demo
# 🇨🇴 mcp-colombia-demo: Servidor MCP de Departamentos de Colombia
> Servidor de **Model Context Protocol (MCP)** minimalista desarrollado en **Node.js** que conecta un Modelo de Lenguaje de Inteligencia Artificial (LLM) con la **API REST oficial y pública de la República de Colombia** para consultar información geográfica en tiempo real sobre los departamentos del país.
---
## 2. Descripción General
### ¿Qué es MCP (Model Context Protocol)?
**Model Context Protocol (MCP)** es un protocolo abierto y estandarizado desarrollado por Anthropic que actúa como un "conector universal" o "puerto USB" para aplicaciones de Inteligencia Artificial. Permite que los modelos de lenguaje (LLM) descubran, comprendan e invoquen de manera autónoma y segura fuentes de datos externas, bases de datos y herramientas locales.
### ¿Qué hace este proyecto?
Este proyecto expone un servidor MCP local que proporciona a cualquier cliente de IA (Claude Desktop, Cursor, VS Code, MCP Inspector) la capacidad de consultar datos geográficos reales sobre Colombia.
- **API que utiliza**: API pública de Colombia (`https://api-colombia.com/api/v1`).
- **Herramienta que expone**: `obtener_departamentos`.
- **Beneficio para la IA**: Gracias a este servidor MCP, el modelo de IA puede responder a preguntas del usuario utilizando **datos oficiales y en tiempo real** (capital, población, superficie en $\text{km}^2$, municipios y prefijo telefónico) evitando alucinaciones o datos desactualizados.
> 💡 **Diferencia Fundamental: API vs MCP**
> - **API REST**: Es la fuente de información o servicio externo que almacena y entrega los datos mediante HTTP.
> - **MCP**: Es el protocolo de comunicación estandarizado que describe la herramienta a la IA en formato **JSON Schema**, permitiendo que el modelo decida por sí solo cuándo y cómo invocar la API.
---
## 3. ¿Qué problema resuelve?
### Sin MCP (Desarrollo Tradicional)
En una aplicación convencional o chatbot estático sin conectores:
```text
Usuario / Aplicación ──► Petición Rígida ──► API Colombia ──► Datos Estáticos
```
- **Problema**: El código es rígido y programado a mano para consultas fijas. Si el usuario hace una pregunta abierta o compleja, la IA depende de su memoria estática preentrenada, lo que produce información desactualizada o inventada (alucinaciones).
### Con MCP (Model Context Protocol)
```text
[Usuario] ──► [IA] ──► [MCP Client] ──► [MCP Server] ──► [Tool] ──► [API REST] ──► [Datos] ──► [MCP] ──► [IA] ──► [Usuario]
```
- **Ventajas de MCP**:
1. **Autonomía**: La IA razona dinámicamente sobre la pregunta del usuario y decide por sí misma si debe consultar todos los departamentos o filtrar uno específico.
2. **Estandarización**: Se escribe el servidor MCP una sola vez en Node.js y funciona en cualquier cliente compatible con MCP (Claude, Cursor, etc.).
3. **Veracidad**: Garantiza respuestas basadas en datos reales provenientes directamente de la fuente oficial en tiempo real.
---
## 4. Arquitectura del Proyecto
```text
┌──────────┐
│ Usuario │
└────┬─────┘
│ 1. Hace una pregunta en lenguaje natural ("¿Existe el departamento de Antioquia?")
▼
┌──────────────┐
│ Modelo de IA │ 2. Analiza las herramientas disponibles y emite un Tool Call
└──────┬───────┘
│ 3. Solicitud JSON-RPC con argumentos ({ "nombre": "Antioquia" })
▼
┌──────────────┐
│ MCP Client │ 4. Transmite el mensaje al servidor local mediante Stdio
└──────┬───────┘
│
▼
┌──────────────┐
│ MCP Server │ 5. Recibe la orden y ejecuta el controlador en index.js
└──────┬───────┘
│ 6. Invoca la función interna de la Tool
▼
┌───────────────────────────┐
│ Tool obtener_departamentos│ 7. Petición HTTP GET con fetch()
└──────────┬────────────────┘
│
▼
┌───────────────────────────┐
│ API Colombia (Externa) │ 8. Devuelve objeto JSON con datos reales
└──────────┬────────────────┘
│
│ 9. Retorna la respuesta HTTP JSON
▼
┌───────────────────────────┐
│ MCP Server (Node.js) │ 10. Filtra los campos y empaqueta en formato MCP
└──────────┬────────────────┘
│
│ 11. Envía resultado estructurado a la IA
▼
┌──────────────┐
│ Modelo de IA │ 12. Interpreta la información y genera la respuesta final
└──────┬───────┘
│
▼
┌──────────┐
│ Usuario │ 13. Recibe la respuesta informada en lenguaje natural
└──────────┘
```
### Explicación de Componentes:
- **Usuario**: Entabla conversación mediante texto en lenguaje natural.
- **Modelo de IA (LLM)**: Motor que razona la intención del usuario y decide si invocar herramientas.
- **MCP Client**: Aplicación (Claude Desktop, MCP Inspector, Cursor) que gestiona el canal de comunicación y le pasa las herramientas al LLM.
- **MCP Server**: Nuestro programa Node.js (`index.js`) que escucha por `StdioServerTransport` y ejecuta las funciones de la herramienta.
- **Tool (`obtener_departamentos`)**: Función JavaScript que construye la URL y realiza la llamada `fetch` a la API.
- **API Colombia**: Servicio público externo REST que almacena los datos de la República de Colombia.
---
## 5. ¿Qué hace nuestra Tool?
### Nombre
`obtener_departamentos`
### Descripción
Obtiene información oficial de los departamentos de Colombia desde la API pública de Colombia. Permite obtener la lista completa de departamentos o consultar/buscar un departamento específico por su nombre.
### Parámetros (JSON Schema)
- `nombre` *(opcional, string)*: Nombre o palabra clave del departamento a consultar (ejemplo: `"Antioquia"`, `"Norte de Santander"`, `"Cundinamarca"`). Si se omite, retorna la lista completa.
### Entrada (Input)
```json
{
"nombre": "Antioquia"
}
```
### Proceso Interno
1. Captura y sanitiza el parámetro `nombre`.
2. Si se recibió un nombre, construye la URL `https://api-colombia.com/api/v1/Department/search/Antioquia`. Si no, usa `https://api-colombia.com/api/v1/Department`.
3. Ejecuta la llamada `fetch(url)` a la API REST.
4. Procesa la respuesta JSON y extrae únicamente los 7 campos más relevantes (`id`, `nombre`, `capital`, `poblacion`, `superficie_km2`, `cantidad_municipios`, `prefijo_telefonico`).
5. Empaqueta y devuelve la respuesta a la IA en el formato estándar MCP `{ content: [{ type: "text", text: "..." }] }`.
### Salida (Output para la IA)
```json
[
{
"id": 2,
"nombre": "Antioquia",
"capital": "Medellín",
"poblacion": 6887306,
"superficie_km2": 63612,
"cantidad_municipios": 125,
"prefijo_telefonico": "4"
}
]
```
---
## 6. Tecnologías y Herramientas Necesarias
| Herramienta | Para qué sirve | Por qué se necesita |
| :--- | :--- | :--- |
| **Node.js** (v18+) | Entorno de ejecución de JavaScript en el servidor. | Permite ejecutar nuestro código del servidor MCP fuera del navegador. |
| **npm** | Gestor de paquetes de Node.js. | Necesario para instalar el SDK de MCP (`@modelcontextprotocol/sdk`). |
| **@modelcontextprotocol/sdk** | Librería oficial de MCP para Node.js. | Proporciona las clases `Server`, `StdioServerTransport` y esquemas de mensajes. |
| **API pública de Colombia** | Servicio web REST externo de libre acceso. | Suministra la base de datos oficial y actualizada sobre los departamentos. |
| **MCP Inspector / Claude Desktop** | Cliente ejecutor de MCP. | Permite interactuar visualmente con el servidor MCP y la IA. |
---
## 7. Requisitos Previos
- **Node.js**: Versión 18.0.0 o superior instalada.
- **Acceso a Internet**: Perteneciente al entorno donde se ejecuta el servidor para consultar `api-colombia.com`.
- **Sin llaves de API (API Keys)**: La API de Colombia es 100% libre y no requiere autenticación.
---
## 8. Estructura de Carpetas
```text
mcp-colombia-demo/
├── index.js # Código fuente principal del Servidor MCP y la Tool
├── package.json # Configuración de dependencias y scripts de Node.js
├── package-lock.json # Registro exacto de versiones instaladas
└── README.md # Documentación general y guía del proyecto
```
---
## 9. Crear el Proyecto desde Cero (Paso a Paso)
Si deseas recrear este proyecto en una carpeta completamente vacía, sigue estos pasos:
### Paso 1: Crear la carpeta del proyecto
```bash
mkdir mcp-colombia-demo
cd mcp-colombia-demo
```
*Crea un directorio llamado `mcp-colombia-demo` y entra en él.*
### Paso 2: Inicializar el proyecto Node.js
```bash
npm init -y
```
*Genera un archivo `package.json` por defecto con la configuración básica.*
### Paso 3: Configurar ES Modules y scripts en `package.json`
Edita `package.json` para asegurarte de incluir `"type": "module"` y el script de inspección:
```json
{
"name": "mcp-colombia-demo",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js",
"inspect": "npx @modelcontextprotocol/inspector node index.js"
}
}
```
### Paso 4: Instalar las dependencias de MCP
```bash
npm install @modelcontextprotocol/sdk
```
*Descarga e instala el SDK oficial de Model Context Protocol en la carpeta `node_modules`.*
### Paso 5: Crear el archivo principal `index.js`
Crea el archivo `index.js` e incluye el código del servidor:
```javascript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const API_BASE_URL = "https://api-colombia.com/api/v1";
const server = new Server(
{
name: "mcp-colombia-departamentos",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 1. Declarar la herramienta
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "obtener_departamentos",
description:
"Obtiene información oficial de los departamentos de Colombia desde la API pública de Colombia. Permite obtener la lista completa de departamentos o consultar/buscar un departamento específico por su nombre.",
inputSchema: {
type: "object",
properties: {
nombre: {
type: "string",
description:
"Nombre o palabra clave del departamento a consultar (ejemplo: 'Antioquia', 'Norte de Santander', 'Cundinamarca'). Si se omite, retorna la lista de todos los departamentos de Colombia.",
},
},
required: [],
},
},
],
};
});
// 2. Ejecutar la herramienta
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name !== "obtener_departamentos") {
throw new Error(`La herramienta '${name}' no existe en este servidor MCP.`);
}
const nombreFiltro = args?.nombre ? String(args.nombre).trim() : null;
try {
let url = `${API_BASE_URL}/Department`;
if (nombreFiltro) {
url = `${API_BASE_URL}/Department/search/${encodeURIComponent(nombreFiltro)}`;
}
const response = await fetch(url);
if (!response.ok) {
return {
isError: true,
content: [{ type: "text", text: `Error en la API de Colombia: Status ${response.status}` }],
};
}
const data = await response.json();
if (!data || (Array.isArray(data) && data.length === 0)) {
return {
content: [{ type: "text", text: `No se encontraron departamentos para: '${nombreFiltro}'.` }],
};
}
const departamentos = Array.isArray(data) ? data : [data];
const resultadoLimpio = departamentos.map((dept) => ({
id: dept.id,
nombre: dept.name,
capital: dept.cityCapital?.name || "No reportada",
poblacion: dept.population,
superficie_km2: dept.surface,
cantidad_municipios: dept.municipalities,
prefijo_telefonico: dept.phonePrefix,
}));
return {
content: [{ type: "text", text: JSON.stringify(resultadoLimpio, null, 2) }],
};
} catch (error) {
return {
isError: true,
content: [{ type: "text", text: `Excepción en la Tool: ${error.message}` }],
};
}
});
// 3. Iniciar servidor Stdio
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("🟢 Servidor MCP de Colombia listo (Stdio)...");
}
main().catch((err) => {
console.error("🔴 Error al iniciar servidor MCP:", err);
process.exit(1);
});
```
---
## 10. Instalación y Ejecución
### Probar en el Navegador con MCP Inspector (Recomendado para Pruebas)
```bash
npm run inspect
```
*Abre la herramienta visual interactiva MCP Inspector en tu navegador para ejecutar `obtener_departamentos` sin configurar un cliente de IA aún.*
---
## 11. Integración con Clientes MCP
### Configuración en Claude Desktop
Para conectar este servidor MCP con la aplicación de escritorio **Claude Desktop**, agrega la siguiente ruta a tu archivo `%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"colombia-departamentos": {
"command": "node",
"args": [
"C:/Users/Usuario/Desktop/Julio trabajos del sena/Hyalure/index.js"
]
}
}
}
```
Al reiniciar Claude Desktop, verás el icono de herramienta 🛠️ activo en la interfaz de chat.
---
## 📜 Licencia
Este proyecto es de código abierto bajo la licencia **MIT** y está diseñado exclusivamente con fines educativos y de investigación académica.
TDQS
Scored across 1 tool
With only a single tool, there is no possibility of confusion with other tools. The tool's purpose is clearly focused on retrieving Colombian department information.
The tool name follows a clear verb_noun pattern ('obtener_departamentos') which is consistent and readable. With one tool, there are no naming conflicts or mixed conventions.
A one-tool server feels thin, even for a demo, but the tool itself covers a well-defined narrow slice of Colombian data. It sits at the borderline of being just enough for a minimal demonstration.
The tool provides both full listing and name-based search for departments, covering the core read operations for this domain. A minor gap is the lack of lookup by department code or integration with other Colombian geographic entities, but the department surface is adequately covered.