Protocolo de contexto de modelos para principiantes con FastMCP y Ollama
Aprenda los roles de MCP: anfitrión, cliente, servidor y transporte; luego conecte un servidor de herramientas meteorológicas a un modelo local qwen3:8b mediante FastMCP y STDIO.
El Model Context Protocol, abreviado habitualmente como MCP, es un lenguaje compartido para conectar modelos de lenguaje grandes con herramientas y fuentes de datos a los que no pueden acceder por sí solos. Llamarlo protocolo resalta que estandariza cómo debe ser la conversación; las bibliotecas concretas implementan luego ese estándar para que los equipos no tengan que inventar sus propios sockets y esquemas de mensajes. FastMCP es una de estas implementaciones utilizadas en la guía a continuación.
Repositorio complementario: https://github.com/harshagangari747/MCPTutorial/tree/main
Requisitos previos
La demostración depende de tres paquetes: fastmcp, ollama y langchain-community. La inferencia se realiza con el modelo local qwen3:8b. Inícielo con:
ollama run qwen3:8b
Prepare una carpeta de proyecto que ya contenga archivos vacíos denominados weather_server_mcp.py y app.py para que el servidor y la aplicación tengan ubicaciones definidas.
Comprensión de MCP
Por sí solo, un LLM es un transductor de tokens: los tokens entran y los tokens salen. No llama a APIs meteorológicas, abre bases de datos ni lee el reloj del sistema, a menos que algo externo al modelo realice esas acciones. Los proveedores de nube a veces integran ejecutores de herramientas propietarias en sus APIs, lo cual es conveniente en entornos de producción pero problemático cuando el objetivo es analizar el protocolo en sí. Ejecutar un modelo local a través de Ollama mantiene el experimento autónomo.
Pruebe con una pregunta como “¿cómo está el clima hoy en Italia?”. Una respuesta típica local comienza admitiendo que no existe una fuente de datos meteorológicos en tiempo real. Aun así, la oración contiene tres indicaciones que el sistema debe resolver: el clima como tema, “hoy” como fecha y Italia como lugar. El modelo necesita una forma de calcular o obtener la información meteorológica, un medio para determinar qué significa “hoy” y una forma de asociar ese clima con Italia.
La falta de referencia al calendario es la brecha evidente. Los pesos del modelo no saben con fiabilidad la fecha actual. MCP resulta útil cuando el modelo puede proponer herramientas y argumentos, y un entorno de ejecución correspondiente los pone en práctica, devolviendo observaciones actualizadas que el modelo puede integrar en una respuesta.
Componentes en MCP
Una implementación práctica de MCP suele incluir varios elementos que colaboran entre sí:
- API funcional — cualquier servicio que ya responda a la pregunta del dominio, como un punto de conexión meteorológico disponible en línea.
- Servidor MCP — un proceso que oculta cómo se accede a la API o a la base de datos y publica herramientas llamables.
- Anfitrión MCP — la interfaz del producto, por ejemplo un planificador de viajes inteligente que combina el razonamiento de LLM con datos en tiempo real.
- Cliente MCP — un puente integrado dentro del anfitrión. Indica al modelo qué herramientas existen, convierte las intenciones del modelo en solicitudes MCP y transforma las respuestas MCP en un contexto adecuado para el modelo.
- Capa de transporte — JSON-RPC 2.0, entregado ya sea mediante HTTP/SSE cuando los componentes están remotos, o a través de STDIO cuando el modelo y las herramientas comparten la misma máquina.
- LLM — aquí
qwen3:8bproporcionado por Ollama.
Al definir esos roles, la pregunta sobre el clima en Italia se convierte en una secuencia coordinada en lugar de una sola llamada al modelo.
Analogía
Una metáfora de conducción mantiene claros los roles. La intención de conducir corresponde a la aplicación anfitriona. El cerebro es el LLM: lee el contexto de la carretera y decide acelerar, frenar o cambiar de marcha, pero no puede presionar los pedales. Las extremidades corresponden al servidor MCP; los músculos y huesos dentro de una extremidad son herramientas individuales: una extremidad dirige o cambia de marcha, mientras que otra frena o acelera. La interfaz nerviosa entre el cerebro y los músculos es el cliente MCP. Los nervios que transmiten impulsos eléctricos son el medio de transporte. El coche es la API externa. El cuerpo completo constituye el conjunto que permite que las partes cooperen.
Mapeo resumido:
- LLM → cerebro
- Servidor MCP → extremidad
- Herramienta → acción muscular
- Anfitrión MCP → intención de conducción
- Cliente MCP → interfaz nerviosa
- Medio de transporte → nervios
- API funcional → coche
- Conjunto de componentes → cuerpo completo
Esa imagen es suficiente para evitar que el servidor, el cliente y el mecanismo de transporte se conviertan en un único “plugin” vago.
Funcionamiento de MCP
La implementación sigue estos roles: establecer un servidor, un anfitrión, un LLM, un mecanismo de transporte, opcionalmente un sistema de integración, y una API o servicio real. El servidor abstracta la API y expone herramientas. Cada herramienta representa una acción concreta que el modelo puede solicitar; el modelo nunca ejecuta la llamada HTTP por sí mismo. El cliente tanto publica el catálogo como realiza traducciones en ambas direcciones, lo que mantiene al modelo y al servidor ligeramente acoplados.
Dado un servidor que ofrece get_todays_date() y get_weather_data(city, date), una consulta como “¿Cuál es el clima hoy en París?” puede desarrollarse de la siguiente manera:
- El modelo se da cuenta de que necesita la fecha de hoy.
- Pide al cliente MCP que utilice
get_todays_date. - El cliente envía la solicitud al servidor.
get_weather_data con la ciudad y la fecha.Las preguntas históricas que caen dentro del período de entrenamiento pueden responderse únicamente con la memoria, pero el propósito de MCP es el contexto actual: fechas y condiciones meteorológicas que cambian después del entrenamiento.
El proyecto
La muestra mantiene la descripción del clima concreta. Un servidor MCP gestiona la lógica que se comunica con una API meteorológica externa. Una aplicación anfitriona crea el cliente MCP, registra al servidor y realiza consultas a Ollama. Al aislar el acceso al LLM en su propio helper, la estructura de transmisión queda más legible.
Servidor MCP
# MCP Server
# weather_server_mcp.py
from fastmcp import FastMCP
import requests
# This is a server instance that we register in our host
server = FastMCP("weather-mcp-server")
# Third party api data
WEATHER_API_KEY = "api_key_here"
WEATHER_BASE_URL = "https://api.weatherapi.com/v1/"
# Tool 1
@server.tool()
def get_weather_data(city: str) -> float:
"""Get current temperature in Celsius"""
response = requests.get(
WEATHER_BASE_URL + "current.json",
params={"key": WEATHER_API_KEY, "q": city},
)
response.raise_for_status()
return response.json()["current"]["temp_c"]
# Tool 2
@server.tool()
def get_historical_weather_data(city: str, date: str) -> float:
"""Get max temperature for a historical date"""
response = requests.get(
WEATHER_BASE_URL + "history.json",
params={"key": WEATHER_API_KEY, "q": city, "dt": date},
)
response.raise_for_status()
return response.json()["forecast"]["forecastday"][0]["day"]["maxtemp_c"]
if __name__ == "__main__":
server.run()
Las funciones que acceden a la API están anotadas con @server.tool(), lo que las publica como herramientas. Las documentaciones al inicio de cada función no son meros adornos; indican al modelo cuándo utilizar esa herramienta. El ejemplo incluye dos herramientas: una que obtiene el clima actual de una ciudad y otra que obtiene el clima histórico de una ciudad en un día pasado.
Anfitrión MCP, cliente, LLM, método de transmisión
import asyncio
import sys
import json
from pathlib import Path
from langchain_community.llms import Ollama
from fastmcp import Client
from fastmcp.client.transports import StdioTransport
async def main():
# We mention the mcp server path.
server_path = Path(__file__).parent / "weather_server_mcp.py"
# The transport method here is STDIO
transport = StdioTransport(
command=sys.executable,
args=[str(server_path)],
)
# Register the MCP Client
mcp_client = Client(transport)
# LLM via Ollama
llm = Ollama(model="qwen3:8b", temperature=0.5)
async with mcp_client:
print("✓ Connected to MCP server!")
# We can now access that tools are present in the weather server mcp now.
mcp_tools = await mcp_client.list_tools()
tools_info = "\n".join([f"- {t.name}: {t.description or t.name}" for t in mcp_tools])
print(f"✓ Available tools:\n{tools_info}\n")
# Interactive loop
while True:
question = input("🌤️ Ask: ").strip()
if question.lower() == 'exit':
break
try:
# Step 1: Ask LLM to decide which tool to use
decision_prompt = f"""Given the question: "{question}"
Available tools:
{tools_info}
Respond with ONLY a JSON object (no other text):
{{"tool": "tool_name", "params": {{"city": "city_name"}}}}
For get_historical_weather_data, use: {{"tool": "get_historical_weather_data", "params": {{"city": "city_name", "date": "YYYY-MM-DD"}}}}"""
print(f"\n📍 Processing: {question}")
llm_response = llm.invoke(decision_prompt)
# Step 2: Parse JSON from LLM response
json_start = llm_response.find('{')
json_end = llm_response.rfind('}') + 1
if json_start == -1 or json_end == 0:
print("❌ LLM didn't return valid tool call")
continue
json_str = llm_response[json_start:json_end]
tool_call = json.loads(json_str)
print("Tool call: ", tool_call)
# Handle array responses
if isinstance(tool_call, list):
tool_call = tool_call[0]
tool_name = tool_call.get("tool")
params = tool_call.get("params", {})
print(f"🔧 Calling: {tool_name} with {params}")
# Step 3: Call MCP tool. This is where we actually call the tool.
result = await mcp_client.call_tool(tool_name, params)
answer = result.content[0].text
print(f"✓ Answer: {answer}°C\n")
except json.JSONDecodeError as e:
print(f"❌ JSON parsing error: {e}")
except Exception as e:
print(f"❌ Error: {e}\n")
if __name__ == "__main__":
asyncio.run(main())
¿Qué está sucediendo?
Se resuelve la ruta del módulo del servidor junto al anfitrión:
server_path = Path(__file__).parent / "weather_server_mcp.py"
Cree un transporte STDIO que inicie ese módulo con el intérprete de Python actual:
# The transport method here is STDIO
transport = StdioTransport(
command=sys.executable,
args=[str(server_path)],
)
Instancie el cliente MCP a partir del transporte:
mcp_client = Client(transport)
El host ahora cuenta con una ruta del servidor registrada, un transporte seleccionado y un cliente. Conecte el modelo a través de Ollama:
llm = Ollama(model="qwen3:8b", temperature=0.5)
Pida al cliente el catálogo de herramientas publicado por weather_server_mcp.py:
mcp_tools = await mcp_client.list_tools()
Pase ese catálogo al prompt e indique al modelo que responda únicamente con el nombre de la herramienta y sus parámetros. Después de analizarlo, ejecute la herramienta seleccionada:
result = await mcp_client.call_tool(tool_name, params)
Por lo tanto, la estructura básica del tutorial es: crear el servidor, registrarlo, registrar el cliente, conectar un LLM y seleccionar un transporte. Las herramientas de agente pueden ocultar parte de esta configuración; un bucle simple mantiene visibles todos los pasos del protocolo durante el proceso de aprendizaje.
En conjunto, MCP es menos una llamada a una biblioteca única y más una división del trabajo. El modelo propone; el cliente traduce; el servidor actúa; el transporte transmite mensajes JSON-RPC; el host se encarga del bucle orientado al usuario. Una vez claros esos límites, reemplazar el clima por calendarios, CRM o búsquedas internas consiste principalmente en crear nuevas herramientas y documentarlas lo suficientemente bien para que el modelo elija correctamente. Mientras el bucle está en ejecución, observe qué emite el modelo antes de cada llamada a una herramienta. Una traza saludable muestra que el modelo menciona una herramienta que realmente existe, proporciona las claves de los argumentos descritas en la documentación y espera a que el cliente devuelva datos antes de redactar la frase orientada al usuario. Si el modelo inventa un nombre de herramienta, refine la instrucción o mejore las descripciones de las herramientas. Si el servidor lanza un error, muestre dicho error a través del cliente para que el modelo pueda intentarlo de nuevo o disculparse en lugar de generar información falsa.
Los valores meteorológicos de Ating. Esa disciplina en la retroalimentación es tan importante como el cableado inicial.Lecturas relacionadas
- Cómo el Protocolo de Contexto del Modelo permite a los agentes de IA descubrir y usar herramientas — Una explicación clara de MCP: cómo los hosts, clientes y servidores permiten que una aplicación de IA descubra herramientas, las invoque con entradas estructuradas y entienda cuáles son sus limitaciones.
- Protocolo de Contexto del Modelo: Por qué las equipos denominan a MCP el USB-C de la IA — MCP estandariza la forma en que las aplicaciones de IA se conectan a herramientas, datos y sistemas, al igual que USB-C para las integraciones, sin reemplazar los modelos ni omitir la gobernanza.