PTENES
MÓDULO 3.4

🔢 Servidor de calculadora

Construye un server con 4 operaciones matemáticas: tu primer server con múltiples tools y validación de entrada.

6
Temas
35
Minutos
Intermedio
Nivel
Práctico
Tipo
1

🎯 Planificando las tools

Antes de escribir código, vamos a planificar nuestro server de calculadora. La idea es crear cuatro tools matemáticas básicas: sumar, restar, multiplicar e dividir. Cada una recibirá dos números de punto flotante (float) como parámetros y devolverá el resultado de la operación. Este será tu primer server con varias tools: un paso importante para construir servers MCP más complejos.

💎 Concepto principal

Nuestro server tendrá 4 tools, todas siguiendo el mismo patrón de firma:

sumar(a: float, b: float) → float

restar(a: float, b: float) → float

multiplicar(a: float, b: float) → float

dividir(a: float, b: float) → float # con validación de b != 0

Todas reciben dos floats y devuelven un float. La excepción es la división, que debe validar si el divisor es cero antes de ejecutar la operación. Este patrón coherente facilita tanto la implementación como el uso por parte del modelo de IA.

💡 Consejo práctico

Planificar las tools antes de programar es un buena práctica esencial. Define el nombre, los parámetros (con tipos) y el valor devuelto de cada tool. Esto garantiza la coherencia, facilita la documentación automática generada por FastMCP y ayuda al modelo de IA a entender cuándo y cómo usar cada herramienta. Piensa en las tools como una API: cuanto más predecible, mejor.

2

➕ Suma y resta

Empecemos por las operaciones más sencillas: suma y resta. Son tools directas, sin necesidad de una validación especial. Sirven como base para entender el patrón que se repetirá en las demás operaciones. Con FastMCP, cada tool es simplemente una función de Python decorada: así de sencillo.

💎 Concepto principal

# server_calculadora.py

from mcp.server.fastmcp import FastMCP


mcp = FastMCP("Calculadora")


@mcp.tool()

def sumar(a: float, b: float) -> float:

"""Suma dos números."""

return a + b


@mcp.tool()

def restar(a: float, b: float) -> float:

"""Resta b de a."""

return a - b

Observa cómo los type hints (a: float, b: float) son fundamentales. FastMCP usa estas anotaciones para generar automáticamente el esquema JSON que el cliente MCP envía al modelo. Sin anotaciones de tipo, el modelo no sabe qué tipo de dato enviar.

💡 Consejo práctico

Siempre escribe docstrings en tus tools. La docstring se convierte en la descripción de la tool en el schema MCP: es lo que el modelo lee para decidir qué tool usar. Una docstring clara como «Suma dos números» es mucho mejor que no tener ninguna.

📊 Datos e investigación

FastMCP convierte automáticamente los type hints de Python en JSON Schema. Un parámetro float se convierte {"type": "number"} en el schema. Un str se convierte {"type": "string"}. Esta conversión automática elimina la necesidad de escribir schemas manualmente: basta con anotar correctamente las funciones de Python y FastMCP se encarga del resto.

3

✖️ Multiplicación

La tool de multiplicación sigue exactamente el mismo patrón que las anteriores. Es intencional: mantener la coherencia entre las tools facilita el trabajo del desarrollador y del modelo. También es una buena oportunidad para entender cómo FastMCP genera el schema automáticamente a partir de tu función de Python.

💎 Concepto principal

@mcp.tool()

def multiplicar(a: float, b: float) -> float:

"""Multiplica dos números."""

return a * b

Cuando FastMCP registra esta tool, genera automáticamente un esquema como: {"name": "multiplicar", "description": "Multiplica dois números.", "inputSchema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]}}. Todo esto a partir de una simple función de Python con type hints y docstring.

❌ Evitar
  • •Funciones sin type hints (el schema queda vacío)
  • •Funciones sin docstring (sin descripción para el modelo)
  • •Nombres genéricos como «calcular» o «func1»
  • •Mezclar la lógica de negocio con el formato
✅ Hacer
  • •Type hints en todos los parámetros y en el valor de retorno
  • •Docstrings claros y descriptivos
  • •Nombres específicos: sumar, restar, multiplicar
  • •Una responsabilidad por tool
4

➗ División con validación

La división es diferente de las demás operaciones porque tiene un caso especial peligroso: la división por cero. Si el usuario pide dividir cualquier número entre cero y la tool simplemente lo ejecuta a / b, Python lanzará un ZeroDivisionError y el servidor puede fallar. Debemos validar la entrada antes de ejecutar la operación.

💎 Concepto principal

@mcp.tool()

def dividir(a: float, b: float) -> str:

"""Divide a entre b. Devuelve un error si b es cero."""

if b == 0:

return "Error: no se permite dividir entre cero."

return f"{a / b}"

En lugar de dejar que la excepción se propague, devolvemos una mensaje de error amigable como string. El modelo recibe este mensaje y puede informar al usuario de forma natural: "No es posible dividir entre cero." Esto es mucho mejor que un traceback de Python incomprensible.

🚨 Alerta

¡Nunca dejes que una tool falle! Una excepción no controlada puede hacer que todo el server MCP deje de funcionar y desconectar al cliente. Valida siempre las entradas, usa try/except cuando sea necesario y devuelve mensajes de error claros. El modelo sabe manejar mensajes de error; no sabe manejar un server que dejó de responder.

❌ Evitar
  • •Dejar que las excepciones se propaguen sin manejarlas
  • •Devolver tracebacks de Python como respuesta
  • •Ignorar los casos extremos (cero, None, etc.)
  • •Confiar en que el modelo siempre envía datos válidos
✅ Hacer
  • •Validar las entradas antes de procesarlas
  • •Devolver mensajes de error amigables
  • •Usar try/except para errores inesperados
  • •Probar intencionalmente con entradas no válidas
5

🧪 Probando todas las herramientas

Con las 4 tools implementadas, es hora de configurar el server en Claude Desktop y probar cada operación. El objetivo es verificar que Claude identifique correctamente qué tool usar para cada pregunta y que todas las operaciones devuelvan resultados correctos, incluido el manejo de la división por cero.

💎 Concepto principal

Agrega el server al claude_desktop_config.json y reinicia Claude Desktop. Después, no olvides agregar el bloque de inicialización al final del archivo:

if __name__ == "__main__":

mcp.run()

Ahora prueba las tools con preguntas en lenguaje natural. Claude elegirá automáticamente la tool correcta para cada operación.

📋 Secuencia de pruebas recomendada
Prueba 1 — Suma

"¿Cuánto es 15 + 27?" — Claude debe usar la tool somar y devolver 42.

Prueba 2 — Resta

"¿Cuánto es 100 menos 37?" — Claude debe usar subtrair y devolver 63.

Prueba 3 — Multiplicación

"Multiplica 8 por 7." — Claude debe usar multiplicar y devolver 56.

Prueba 4 — División normal

"Divide 100 entre 4." — Claude debe usar dividir y devolver 25.

Prueba 5 — División por cero

"Divide 100 entre 0." — Claude debe recibir el mensaje de error y explicar que no es posible dividir entre cero.

💡 Consejo práctico

Prueba también con números decimales ("¿Cuánto es 3.14 por 2?") y con números negativos ("Resta 50 de 30"). Verifica si Claude puede encadenar operaciones: "Suma 10 y 20, después multiplica por 3" — debe llamar a las tools en el orden correcto.

6

🔧 Mejoras y refactorización

Ahora que el server básico funciona, podemos pensar en mejoras. Redondear los resultados, admitir explícitamente enteros y números de punto flotante, y agregar nuevas operaciones como la potenciación. Estas mejoras convierten un server de demostración en algo más robusto y profesional.

💎 Concepto principal

Algunas mejoras prácticas para el server de calculadora:

  • 1. Redondeo: Usa round(resultado, 10) para evitar problemas de punto flotante como 0.1 + 0.2 = 0.30000000000000004.
  • 2. Tipos union: Usa a: int | float para aceptar explícitamente tanto enteros como números de punto flotante.
  • 3. Nueva tool: Agrega potenciar(base: float, expoente: float) como ejercicio: sigue el mismo patrón que los demás.
💡 Consejo práctico

Como ejercicio, implementa la tool potenciar(base: float, expoente: float). Debe devolver base ** expoente. Piensa: ¿necesita una validación especial? ¿Qué pasa con 0 ** 0? ¿Y con exponentes negativos? Practica el pensamiento de "¿qué puede salir mal?" — esta mentalidad te servirá en cada server MCP que construyas.

❌ Evitar
  • •Dejar los problemas de punto flotante sin manejar
  • •Crear una única tool "calcular" que lo haga todo
  • •Agregar complejidad sin necesidad
  • •Olvidar probar las mejoras
✅ Hacer
  • •Redondear resultados de punto flotante
  • •Mantener las tools separadas por operación
  • •Agregar nuevas tools de forma incremental
  • •Probar cada mejora por separado

📝 Resumen del módulo

  • ✓ Planificamos 4 tools con firmas coherentes: sumar, restar, multiplicar y dividir.
  • ✓ Implementamos suma y resta como funciones simples con type hints y docstrings.
  • ✓ Entendimos cómo FastMCP genera automáticamente schemas JSON a partir de type hints de Python.
  • ✓ Agregamos validación para la división por cero: se devuelve un mensaje de error en lugar de que el proceso se bloquee.
  • ✓ Probamos todas las tools en Claude Desktop con diferentes tipos de entrada.
  • ✓ Exploramos mejoras como el redondeo, los union types y nuevas operaciones.

Siguiente Módulo: 3.5 — Servidor de consulta del clima