Ir al contenido principal

Cómo crear un servidor y un cliente MCP con FastMCP 2.0

Creación, pruebas e integración del servidor MCP ArXiv Explorer.
Actualizado 17 sept 2026  · 8 min leer

Explora con IA

ChatGPTClaudePerplexity

En el mundo de la IA, el Model Context Protocol (MCP) se ha convertido rápidamente en un tema clave. MCP es un estándar abierto que ofrece a modelos de IA como Claude 4 una forma coherente de conectarse con herramientas externas, servicios y fuentes de datos en tiempo real. Esta conectividad cambia las reglas del juego porque permite a los modelos de lenguaje grandes (LLM) dar respuestas más relevantes, actuales y accionables al tender puentes entre la IA y los sistemas.

En este tutorial, nos adentraremos en FastMCP 2.0, un potente framework que facilita crear tu propio servidor MCP con solo unas pocas líneas de código. Veremos los componentes clave de FastMCP, cómo construir tanto un servidor como un cliente MCP, y cómo integrarlos sin fricción en tu flujo de trabajo. Si eres nuevo en MCP, echa un vistazo a nuestra guía del Model Context Protocol con proyecto de demostración para saber más. 

¿Qué es FastMCP 2.0?

FastMCP 2.0 es un framework de Python de código abierto diseñado para que crear servidores y clientes del Model Context Protocol (MCP) sea sencillo y eficiente. Con solo unas líneas de código, los desarrolladores pueden crear servidores MCP a medida y conectarlos a sus aplicaciones de IA, como editores de código o asistentes conversacionales.

FastMCP 2.0 es el sucesor de FastMCP 1.0, que ahora se conoce como MCP Python SDK, y ofrece un kit completo para trabajar en el ecosistema MCP.

Lo que diferencia a FastMCP 2.0 es su conjunto de funcionalidades, mucho más allá de la especificación básica de MCP. Simplifica el despliegue, la autenticación, el proxy de clientes y servidores, e incluso permite generar servidores a partir de APIs REST.  

Componentes clave de FastMCP 2.0

FastMCP 2.0 se articula en torno a tres componentes esenciales: herramientas (Tools), recursos (Resources) y prompts.

1. Tools

Las herramientas son funciones de Python expuestas a los LLM mediante el protocolo MCP. Al decorar una función con @mcp.tool, permites que el modelo de IA la invoque durante una conversación. Esto permite a los LLM ejecutar acciones reales, como consultar bases de datos, llamar a APIs o realizar cálculos.

from fastmcp import FastMCPmcp = FastMCP(name="UtilityServer")@mcp.tooldef convert_usd_to_eur(amount: float, rate: float = 0.91) -> float:    """Converts a given amount in USD to EUR using the provided rate."""    return round(amount * rate, 2)

2. Resources

Los recursos proporcionan a los LLM o a las aplicaciones cliente acceso de solo lectura a datos, como archivos, registros de base de datos, configuraciones o contenido generado dinámicamente. Por ejemplo:

from fastmcp import FastMCPmcp = FastMCP(name="WeatherResourceServer")@mcp.resource("config://weather-settings")def get_weather_settings() -> dict:    """Provides weather configuration."""    return {        "default_units": "metric",        "default_location": "Berlin",        "features_enabled": ["forecast", "alerts"]    }@mcp.resource("resource://welcome-message")def welcome_message() -> str:    """Returns a dynamic greeting for users based on time of day."""    from datetime import datetime    hour = datetime.now().hour    if hour < 12:        return "Good morning! Here's your weather update."    elif hour < 18:        return "Good afternoon! Need a forecast?"    else:        return "Good evening! Let's check the weather."

3. Prompts

Los prompts son plantillas de mensajes reutilizables y parametrizables que orientan las respuestas de los LLM. Al definirlos como funciones, garantizas instrucciones coherentes y con contexto que los clientes pueden invocar.

Son necesarios para ejecutar varias herramientas en secuencia y guiar al LLM para realizar tareas usando las herramientas y recursos disponibles.

from fastmcp import FastMCPfrom fastmcp.prompts.prompt import PromptMessage, TextContentmcp = FastMCP(name="TutorPromptServer")@mcp.promptdef explain_math_concept(concept: str) -> PromptMessage:    """Creates a message asking an AI tutor to explain a math concept simply."""    text = f"Can you explain the math concept of '{concept}' in a way that's easy for a 12-year-old to understand?"    return PromptMessage(role="user", content=TextContent(type="text", text=text))

Crear un ArXiv Explorer con FastMCP 2.0 y Tavily

En esta sección construiremos un servidor MCP "ArXiv Explorer". Este servidor tendrá dos herramientas: una para extraer enlaces y títulos de artículos científicos, y otra para resumirlos. Además, incluirá recursos y prompts para ayudarte a crear un informe completo sobre el tema elegido.

1. Preparación

Antes de empezar, necesitas obtener la clave de la API de Tavily. Puedes conseguir una clave gratuita con 1.000 solicitudes mensuales en tavily.com. Después, instala las librerías de Python necesarias:

pip install fastmcp tavily-python

2. Creación del servidor "ArxivExplorer"

Primero crearemos el archivo Python del servidor. El archivo incluye:

  1. Inicialización: crea una instancia de FastMCP asignando el nombre de servidor "ArxivExplorer".
  2. Recurso: El decorador @mcp.resource expone nuestra función arxiv_topics como fuente de datos de solo lectura. Un cliente de IA puede obtener estos temas para inspirarse si el usuario no lo tiene claro.
  3. Tools: el decorador @mcp.tool convierte funciones normales de Python en acciones que un LLM puede ejecutar.
    1. search_arxiv: esta herramienta usa la API de Tavily para restringir la búsqueda a un dominio específico (arxiv.org), garantizando que solo obtengamos artículos científicos relevantes de arxiv.org.
    2. summarize_paper: esta herramienta usa qna_search de Tavily, optimizada para ofrecer respuestas directas y concisas, perfecta para generar un resumen.
  4. Prompt: el decorador @mcp.prompt crea una plantilla reutilizable. No es un simple prompt; es un plan estratégico que indica a un LLM cómo usar las herramientas del servidor en secuencia para resolver una tarea compleja.
  5. Transporte HTTP: mcp.run(transport="http") es clave. En lugar de usar “stdio” para procesos locales, arranca un servidor web. Así, cualquier cliente de la red (o de la misma máquina) puede conectarse a nuestro servidor vía URL, convirtiéndolo en una herramienta remota y compartible.

server.py:

import osfrom typing import Dict, Listfrom fastmcp import FastMCPfrom tavily import TavilyClient# --- Configuration ---TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY")if not TAVILY_API_KEY:    raise ValueError("Please set the TAVILY_API_KEY environment variable.")tavily = TavilyClient(api_key=TAVILY_API_KEY)mcp = FastMCP(name="ArxivExplorer")print("✅ ArxivExplorer server initialized.")# --- Dynamic Resource: Suggested AI research topics ---@mcp.resource("resource://ai/arxiv_topics")def arxiv_topics() -> List[str]:    return [        "Transformer interpretability",        "Efficient large-scale model training",        "Federated learning privacy",        "Neural network pruning",    ]print("✅ Resource 'resource://ai/arxiv_topics' registered.")# --- Tool: Search ArXiv for recent papers ---@mcp.tool(annotations={"title": "Search Arxiv"})def search_arxiv(query: str, max_results: int = 5) -> List[Dict]:    """    Queries ArXiv via Tavily, returning title + link for each paper,    and *only* ArXiv results.    """    resp = tavily.search(        query=f"site:arxiv.org {query}",        max_results=max_results    )    return [        {"title": r["title"].strip(), "url": r["url"]} for r in resp.get("results", [])    ]# --- Tool: Summarize an ArXiv paper ---@mcp.tool(annotations={"title": "Summarize Paper"})def summarize_paper(paper_url: str) -> str:    """    Returns a one-paragraph summary of the paper at the given URL.    """    prompt = f"Summarize the key contributions of this ArXiv paper: {paper_url}"    return tavily.qna_search(query=prompt)print("✅ Tools 'Search Arxiv' and 'Summarize Paper' registered.")# --- Prompt Template: Explore a topic thoroughly ---@mcp.promptdef explore_topic_prompt(topic: str) -> str:    return (        f"I want to explore recent work on '{topic}'.\n"        f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n"        f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n"        f"3. Combine all summaries into an overview report."    )print("✅ Prompt 'explore_topic_prompt' registered.")if __name__ == "__main__":    print("\n🚀 Starting ArxivExplorer Server...")    mcp.run(transport="http")

3. Creación del cliente interactivo

Necesitamos probar las funciones y endpoints del servidor MCP antes de integrarlo en la aplicación de IA. Para ello, FastMCP ofrece una API sencilla para conectar con el servidor MCP y testear todas sus funciones.

El archivo del cliente incluye:

  1. Transporte HTTP: StreamableHttpTransport está diseñado específicamente para conectarse a un servidor FastMCP ejecutándose en modo HTTP.
  2. Ayudante unwrap_tool_result: es una utilidad crucial. El cliente FastMCP no devuelve datos en bruto; devuelve objetos estructurados. Esta función inspecciona la respuesta y extrae con seguridad los datos de Python que realmente necesitas.
  3. Flujo de trabajo: la función principal ejecuta una batería de pruebas completa.
    1. Hace ping al servidor para asegurarse de que está en línea.
    2. Enumera todas las herramientas, recursos y prompts disponibles.
    3. Lee el recurso arxiv_topics y analiza correctamente el resultado.
    4. Llama a la herramienta search_arxiv y usa la función auxiliar para desempaquetar la lista de artículos.
    5. Encadena herramientas tomando la URL del primer resultado y pasándola a summarize_paper.
    6. Finalmente, obtiene explore_topic_prompt, mostrando las instrucciones listas para enviar a un LLM.

client.py:

import astimport asyncioimport pprintfrom fastmcp import Clientfrom fastmcp.client.transports import StreamableHttpTransport# --- Configuration ---SERVER_URL = "http://localhost:8000/mcp"  # adjust if hosted elsewherepp = pprint.PrettyPrinter(indent=2, width=100)def unwrap_tool_result(resp):    """    Safely unwraps the content from a FastMCP tool call result object.    """    if hasattr(resp, "content") and resp.content:        # The content is a list containing a single content object        content_object = resp.content[0]        # It could be JSON or plain text        if hasattr(content_object, "json"):            return content_object.json        if hasattr(content_object, "text"):            try:                # Use ast.literal_eval for safely evaluating a string containing a Python literal                return ast.literal_eval(content_object.text)            except (ValueError, SyntaxError):                # If it's not a literal, return the raw text                return content_object.text    return respasync def main():    transport = StreamableHttpTransport(url=SERVER_URL)    client = Client(transport)    print("\n🚀 Connecting to FastMCP server at:", SERVER_URL)    async with client:        # 1. Ping to test connectivity        print("\n🔗 Testing server connectivity...")        await client.ping()        print("✅ Server is reachable!\n")        # 2. Discover server capabilities        print("🛠️  Available tools:")        pp.pprint(await client.list_tools())        print("\n📚 Available resources:")        pp.pprint(await client.list_resources())        print("\n💬 Available prompts:")        pp.pprint(await client.list_prompts())        # 3. Fetch the topics resource        print("\n\n📖 Fetching resource: resource://ai/arxiv_topics")        res = await client.read_resource("resource://ai/arxiv_topics")        topics = ast.literal_eval(res[0].text)        print("Today's AI topics:")        for i, t in enumerate(topics, 1):            print(f"  {i}. {t}")        # 4. Test the search tool        print("\n\n🔍 Testing tool: search_arxiv")        raw_search = await client.call_tool(            "search_arxiv",            {"query": "Transformer interpretability", "max_results": 3},        )        search_results = unwrap_tool_result(raw_search)        for i, paper in enumerate(search_results, 1):            print(f"  {i}. {paper['title']}\n     {paper['url']}")                # 5. Test the summarize tool on the first result        if search_results:            first_url = search_results[0]["url"]            print("\n\n📝 Testing tool: summarize_paper")            raw_summary = await client.call_tool(                "summarize_paper", {"paper_url": first_url}            )            summary = unwrap_tool_result(raw_summary)            print("\nSummary of first paper:\n", summary)        # 6. Test the prompt generator        print("\n\n🚀 Testing prompt: explore_topic_prompt")        prompt_resp = await client.get_prompt(            "explore_topic_prompt", {"topic": "Transformer interpretability"}        )        print("\nGenerated prompt for an LLM:")        for msg in prompt_resp.messages:            print(f"{msg.role.upper()}: {msg.content.text}\n")if __name__ == "__main__":    asyncio.run(main())

Todos los archivos y configuraciones están disponibles en el repositorio de GitHub kingabzpro/FastMCP-Project. Puedes usarlo si te surge alguna incidencia. También he incluido la guía de instalación para ejecutarlo en local.

4. Ejecución de la aplicación

Ahora vamos a ejecutar tanto el servidor MCP como el cliente. 

Primero, define la clave de API de Tavily como variable de entorno en tu sistema local:  

export TAVILY_API_KEY='your_tavily_api_key'

Después, ejecuta el servidor:  

python server.py

En segundos verás que el servidor FastMCP está en marcha en http://localhost:8000/mcp.

FastMCP server is running at http://localhost:8000/mcp

Abre una nueva terminal y ejecuta el script del cliente para comprobar que todo funciona correctamente:  

python client.py

Como puedes ver, todas las funciones, recursos, herramientas y prompts funcionan perfectamente. Nuestro servidor MCP rinde bien incluso con múltiples solicitudes a la API de Tavily.

🚀  Connecting to FastMCP server at: http://localhost:8000/mcp🔗 Testing server connectivity...✅ Server is reachable!🛠️  Available tools:[ Tool(name='search_arxiv', title='Search Arxiv', description='Queries ArXiv via Tavily, returning title + link for each paper,\nand *only* ArXiv results.', inputSchema={'properties': {'query': {'title': 'Query', 'type': 'string'}, 'max_results': {'default': 5, 'title': 'Max Results', 'type': 'integer'}}, 'required': ['query'], 'type': 'object'}, outputSchema={'properties': {'result': {'items': {'additionalProperties': True, 'type': 'object'}, 'title': 'Result', 'type': 'array'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Search Arxiv', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None),  Tool(name='summarize_paper', title='Summarize Paper', description='Returns a one-paragraph summary of the paper at the given URL.', inputSchema={'properties': {'paper_url': {'title': 'Paper Url', 'type': 'string'}}, 'required': ['paper_url'], 'type': 'object'}, outputSchema={'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Summarize Paper', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None)]📚 Available resources:[ Resource(name='arxiv_topics', title=None, uri=AnyUrl('resource://ai/arxiv_topics'), description=None, mimeType='text/plain', size=None, annotations=None, meta=None)]💬 Available prompts:[ Prompt(name='explore_topic_prompt', title=None, description=None, arguments=[PromptArgument(name='topic', description=None, required=True)], meta=None)]📖 Fetching resource: resource://ai/arxiv_topicsToday's AI topics:  1. Transformer interpretability  2. Efficient large-scale model training  3. Federated learning privacy  4. Neural network pruning🔍 Testing tool: search_arxiv  1. Transformer Interpretability Beyond Attention Visualization     https://arxiv.org/abs/2012.09838  2. A Practical Review of Mechanistic Interpretability for ...     https://arxiv.org/abs/2407.02646  3. Mechanistic Interpretability of Fine-Tuned Vision ...     https://arxiv.org/abs/2503.18762📝 Testing tool: summarize_paperSummary of first paper: The paper proposes a novel method for interpreting Transformer networks beyond attention visualization, introducing a new way to compute relevancy. It aims to enhance interpretability in vision tasks. The method is shown to provide more accurate insights into model decisions.🚀 Testing prompt: explore_topic_promptGenerated prompt:USER: type='text' text="I want to explore recent work on 'Transformer interpretability'.\n1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n3. Combine all summaries into an overview report." annotations=None meta=None

Integración del servidor MCP en Cursor AI

Mantén el servidor MCP en ejecución, porque vamos a integrarlo en el editor de código Cursor AI. 

  1. Ve a “Settings”.
  2. Haz clic en la pestaña “Tools & Integrations”.
  3. Haz clic en el botón “New MCP Server”.
  4. Añade la siguiente configuración:
{  "mcpServers": {    "ArxivExplorer": {      "url": "http://127.0.0.1:8000/mcp/"    }  }}

Cuando guardes el archivo mcp.json con la configuración anterior, verás el nuevo servidor MCP en la sección “Tools & Integrations”, que mostrará dos herramientas como en la imagen.

ArxivExplorer configured in Cursor AI

Pruebas del servidor MCP en Cursor AI

Ahora viene la parte divertida. Veamos cómo se comporta nuestro servidor MCP con el editor de código Cursor AI. Aprenderemos a usar prompts para invocar herramientas, acceder a recursos y ejecutar prompts personalizados, todo desde el editor.

1. Probar los recursos

Empieza comprobando si tu servidor MCP puede proporcionar datos útiles a través de sus recursos.

Prompt: “what are the some popular arxiv topics”

Testing the Resources

Si todo está bien configurado, el modelo de IA entenderá tu petición y recuperará automáticamente la lista de temas desde el endpoint de recursos de tu servidor MCP.

2. Probar las herramientas individuales

A continuación, probemos las herramientas que has expuesto mediante MCP. Primero, testaremos la herramienta search_arxiv pidiéndole al modelo de IA que liste los diez artículos más relevantes sobre modelos de lenguaje grandes.  

Prompt: “Please search for the top 10 research papers on large language models.”

La IA llamará a la herramienta search_arxiv y deberías ver una lista rápida y precisa de artículos relevantes extraídos directamente de arXiv.

Después probaremos la herramienta de resumen, que toma la URL del artículo y devuelve un resumen del trabajo.  

Prompt: “Please summarize the following paper for me: https://arxiv.org/abs/2402.06196”

La herramienta de resumen recuperará el artículo y devolverá un resumen conciso.

3. Probar el prompt

Ahora invocaremos un prompt personalizado del MCP que nos ayudará a generar un informe.

Prompt: “Create a report on Quantum computing using the latest work.”

Testing the Prompt

Si revisas el código del servidor, verás que el modelo de IA comprende la tarea y usa la función explore_topic_prompt.

@mcp.promptdef explore_topic_prompt(topic: str) -> str:    return (        f"I want to explore recent work on '{topic}'.\n"        f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n"        f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n"        f"3. Combine all summaries into an overview report."    )

Primero, llamará a la herramienta "Search Arxiv" para encontrar los enlaces a los artículos. 

Tool result output

Luego, pasará los enlaces a la herramienta "Summarize Paper" uno a uno para generar los resúmenes. Por último, creará el informe.

Tool result output

Conclusión

FastMCP 2.0 ofrece mucho más que una forma simple de crear servidores MCP. Proporciona un framework robusto para construir integraciones de IA seguras, modulares y escalables. Con funciones como autenticación, proxy avanzado (que permite que un servidor FastMCP actúe como frontend de otro) y la posibilidad de combinar varios servidores FastMCP en una sola aplicación mediante montaje e importación, puedes diseñar sistemas complejos y mantenibles con facilidad.

El soporte de middleware te permite añadir funcionalidades transversales, como registro de actividad o modificación de peticiones, a todas las solicitudes y respuestas MCP. También puedes enviar mensajes de log y actualizaciones de progreso a los clientes a través del contexto MCP, lo que facilita monitorizar y gestionar operaciones de larga duración.

En este tutorial, has aprendido a construir un servidor MCP completamente funcional y a probar sus características. Estas herramientas y el protocolo MCP se están convirtiendo en componentes esenciales de las aplicaciones modernas de IA, habilitando a los LLM para realizar tareas más avanzadas y automatizar flujos de trabajo con mayor eficacia. 

Para seguir aprendiendo sobre servidores MCP, no te pierdas estos recursos: 


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Soy un científico de datos certificado que disfruta creando aplicaciones de aprendizaje automático y escribiendo blogs sobre ciencia de datos. Actualmente me centro en la creación de contenidos, la edición y el trabajo con grandes modelos lingüísticos.

Temas
Inteligencia Artificial
Grandes modelos lingüísticos

Los mejores cursos de DataCamp

Curso

Sistemas multiagente con LangGraph

2 h 45 min
8.8K
Crea potentes sistemas multiagente aplicando patrones de diseño agentico emergentes en el marco LangGraph.
Ver detallesRight Arrow
Empezar Curso
Ver másRight Arrow
Relacionado
An AI juggles tasks

blog

Cinco proyectos que puedes crear con modelos de IA generativa (con ejemplos)

Aprende a utilizar modelos de IA generativa para crear un editor de imágenes, un chatbot similar a ChatGPT con pocos recursos y una aplicación clasificadora de aprobación de préstamos y a automatizar interacciones PDF y un asistente de voz con GPT.
Abid Ali Awan's photo

Abid Ali Awan

10 min

Tutorial

Tutorial de FastAPI: Introducción al uso de FastAPI

Explore el marco FastAPI y descubra cómo puede utilizarlo para crear API en Python.
Moez Ali's photo

Moez Ali

13 min

Tutorial

Tutorial FLAN-T5: Guía y puesta a punto

Una guía completa para afinar un modelo FLAN-T5 para una tarea de respuesta a preguntas utilizando la biblioteca de transformadores, y ejecutando la inferencia optmizada en un escenario del mundo real.
Zoumana Keita 's photo

Zoumana Keita

15 min

Tutorial

Tutorial sobre cómo crear aplicaciones LLM con LangChain

Explore el potencial sin explotar de los grandes modelos lingüísticos con LangChain, un marco Python de código abierto para crear aplicaciones avanzadas de IA.
Moez Ali's photo

Moez Ali

12 min

Tutorial

Tutorial de DeepSeek-Coder-V2: Ejemplos, instalación, puntos de referencia

DeepSeek-Coder-V2 es un modelo de lenguaje de código de código abierto que rivaliza con el rendimiento de GPT-4, Gemini 1.5 Pro, Claude 3 Opus, Llama 3 70B o Codestral.
Dimitri Didmanidze's photo

Dimitri Didmanidze

8 min

ChatGPT Code Interpreter

Tutorial

Cómo utilizar ChatGPT Code Interpreter

Todo lo que necesitas saber sobre ChatGPT Code Interpreter de OpenAI
Adel Nehme's photo

Adel Nehme

9 min

Ver MásVer Más