mkdir 01-start && cd 01-start
pnpm initEsto genera el package.json inicial:
{
"name": "01-start",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.8.0"
}Se agrega "type": "module" al package.json y se crea el archivo main.ts.
package.json actualizado:
{
"name": "01-start",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.8.0"
}Estructura del proyecto:
01-start/
├── main.ts
└── package.json
pnpm add @modelcontextprotocol/sdkInstala @modelcontextprotocol/sdk@1.9.0 (81 paquetes).
package.json actualizado:
{
"name": "01-start",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.8.0",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.9.0"
}
}pnpm add zodInstala zod@3.24.2.
package.json actualizado:
{
"name": "01-start",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.8.0",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.9.0",
"zod": "^3.24.2"
}
}main.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from 'zod'
// 1. Crear el servidor
// Es la interfaz principal con el protocolo MCP. Maneja la comunicacion entre el cliente y el servidor.
const server = new McpServer({
name: 'Demo',
version: '1.0.0'
})Las herramientas le permiten al LLM realizar acciones a traves de tu servidor.
Se agrega server.tool() en main.ts:
// 2. Definir las herramientas
// Las herramientas le permite al LLM realizar acciones a través de tu servidor.
server.tool(
'fetch-weather', // titulo de la herramienta
'Tool to fetch the weather of a city', // descripción de la herramienta
{
city: z.string().describe('City name'),
},
async ({ city }) => {
return {
content: [
{
type: 'text',
text: `El clima de ${city} es soleado`
}
]
}
}
)Se agrega la conexion del servidor usando StdioServerTransport para escuchar las conexiones del cliente:
// 3. Escuchar las conexiones del cliente
const transport = new StdioServerTransport()
await server.connect(transport)main.ts completo:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from 'zod'
// 1. Crear el servidor
// Es la interfaz principal con el protocolo MCP. Maneja la comunicacion entre el cliente y el servidor.
const server = new McpServer({
name: 'Demo',
version: '1.0.0'
})
// 2. Definir las herramientas
// Las herramientas le permite al LLM realizar acciones a través de tu servidor.
server.tool(
'fetch-weather', // titulo de la herramienta
'Tool to fetch the weather of a city', // descripción de la herramienta
{
city: z.string().describe('City name'),
},
async ({ city }) => {
return {
content: [
{
type: 'text',
text: `El clima de ${city} es soleado`
}
]
}
}
)
// 3. Escuchar las conexiones del cliente
const transport = new StdioServerTransport()
await server.connect(transport)npx -y tsx main.tsEl servidor queda escuchando conexiones via stdio.
Para que Claude Desktop use este servidor MCP, se edita el archivo de configuracion claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Se agrega el servidor weather dentro de mcpServers:
{
"mcpServers": {
"weather": {
"command": "npx",
"args": [
"-y",
"tsx",
"/Users/midudev/Dev/mcp-clase/01-start/main.ts"
]
}
}
}Una vez configurado y reiniciado Claude Desktop, la herramienta fetch-weather aparece disponible en la lista de "Available MCP tools":
- fetch-weather - Tool to fetch the weather of a city - From server: weather
El MCP Inspector es una herramienta de depuracion que permite probar servidores MCP sin necesidad de un cliente como Claude Desktop.
Se ejecuta directamente con npx:
npx -y @modelcontextprotocol/inspector npx -y tsx main.tsEsto levanta el Inspector en http://127.0.0.1:6274 con la siguiente configuracion:
- Transport Type: STDIO
- Command: npx
- Arguments: -y tsx main.ts
En el MCP Inspector (v0.9.0):
- Ir a la pestaña Tools
- Hacer clic en List Tools para ver las herramientas disponibles
- Seleccionar fetch-weather
- Introducir un valor en el campo
city(ej:Barcelona) - Hacer clic en Run Tool
Resultado:
{
"content": [
{
"type": "text",
"text": "El clima de Barcelona es soleado"
}
]
}Tool Result: Success
Se actualiza la herramienta fetch-weather para que consulte datos reales del clima usando la API gratuita de Open-Meteo.
El flujo es:
- Geocoding: Buscar las coordenadas de la ciudad usando
geocoding-api.open-meteo.com - Forecast: Obtener el clima actual usando
api.open-meteo.comcon las coordenadas - Devolver el JSON completo al LLM para que lo interprete
La respuesta del geocoding viene dentro de data.results[]:
{
"results": [
{
"id": 2950159,
"name": "Berlin",
"latitude": 52.52437,
"longitude": 13.41053,
"elevation": 74.0,
"feature_code": "PPLC"
}
]
}main.ts actualizado (callback de server.tool):
server.tool(
'fetch-weather',
'Tool to fetch the weather of a city',
{
city: z.string().describe('City name'),
},
async ({ city }) => {
// Geocoding: obtener latitud y longitud de la ciudad
const response = await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${city}&count=1&language=en&format=json`)
const data = await response.json()
if (data.length === 0) {
return {
content: [
{
type: 'text',
text: `No se encontró información para la ciudad ${city}`
}
]
}
}
const { latitude, longitude } = data.results[0]
// Forecast: obtener el clima actual
const weatherResponse = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&hourly=temperature_2m¤t=temperature_2m,precipitation,is_day,rain&forecast_days=1`)
const weatherData = await weatherResponse.json()
return {
content: [
{
type: 'text',
text: JSON.stringify(weatherData, null, 2)
}
]
}
}
)Se devuelve JSON.stringify(weatherData, null, 2) con todos los datos para que el LLM los interprete.
Al probarlo en el Inspector con Barcelona, el resultado incluye los datos reales:
{
"latitude": 41.4375,
"longitude": 2.1875,
"generationtime_ms": 0.052928924560546875,
"utc_...": "..."
}Tool Result: Success
Al preguntar en Claude Desktop: "¿Qué tiempo hace hoy en Barcelona?"
Claude usa automaticamente la herramienta fetch-weather del servidor weather (local) y es capaz de interpretar el JSON devuelto por la API de Open-Meteo para generar una respuesta en lenguaje natural:
"Actualmente en Barcelona hace 14.3°C, con una ligera precipitación de 0.2 mm y algo de lluvia (0.1 mm). Es de día y según los datos, la temperatura ha sido moderada durante el día, alcanzando un máximo de aproximadamente 15.2°C alrededor de las 14:00 horas.
Para el resto del día se espera que la temperatura baje gradualmente hasta llegar a unos 10.7°C a medianoche."
El LLM recibe el JSON crudo y lo convierte en informacion comprensible para el usuario.
El mismo servidor MCP se puede usar desde VS Code con GitHub Copilot en modo Agente.
- Abrir la paleta de comandos (
Cmd+Shift+P/Ctrl+Shift+P) - Buscar
>pre→ Preferencias: Abrir configuración de usuario (JSON) - Verificar que el modo agente esta habilitado:
- Chat > Agent: Enabled → activado
- Chat > Agent: Max Requests → 15
Desde la paleta de comandos buscar >mcp:
- MCP: Agregar servidor... / MCP: Add Server...
- MCP: Enumerar servidores / MCP: List Servers
O directamente editar el settings.json de VS Code (~/Library/Application Support/Code/User/settings.json):
{
"chat.agent.enabled": true,
"mcp": {
"servers": {
"weather": {
"command": "npx",
"args": [
"-y",
"tsx",
"/Users/midudev/Dev/mcp-clase/01-start/main.ts"
]
}
}
}
}Una vez guardado, VS Code muestra el estado del servidor directamente en el settings.json:
✓ En ejecución | Detener | Reiniciar | Herramientas de 1
Al abrir el selector de herramientas en Copilot Chat se ven los servidores MCP disponibles:
- Servidor MCP: weather - Desde Global en Code (En ejecución) →
fetch-weather - Servidor MCP: postgres - Desde Escritorio de Claude (En ejecución) →
query - Servidor MCP: filesystem - Desde Escritorio de Claude (En ejecución) →
read_file,read_multiple_files, etc.
En el chat de Copilot (modo Agente), al preguntar por el clima, Copilot detecta el servidor MCP y solicita permiso para ejecutar la herramienta:
GitHub Copilot: "Voy a consultar el tiempo en Madrid para ti. Veo que tienes configurado un servidor MCP para el clima, así que puedo utilizar esa herramienta para obtener la información."
→ Ejecutar "fetch-weather"
[Continuar] | [Cancelar]
Al hacer clic en Continuar, Copilot ejecuta la herramienta fetch-weather y devuelve los datos del clima interpretados.