MCP vs Function Calling: Cuándo Usar Cada Uno en tus Agentes IA

Programación· 4 min de lectura

MCP vs Function Calling: Cuándo Usar Cada Uno en tus Agentes IA

Llevo meses construyendo agentes con Claude y veo el mismo patrón una y otra vez: los desarrolladores confunden MCP (Model Context Protocol) con function calling. No es culpa tuya. Ambos permiten que los modelos interactúen con sistemas externos. Pero son herramientas completamente diferentes.

La diferencia no es técnica. Es arquitectónica.

El Problema Real

Cuando empiezas a construir agentes, quieres que hagan cosas:

  • Consultar bases de datos
  • Llamar APIs externas
  • Leer archivos
  • Ejecutar búsquedas

Tienes dos caminos. Ambos funcionan. Pero uno te va a causar problemas más adelante.

Function Calling: Para lo Simple

Function calling es lo que probablemente conoces. Defines funciones que el modelo puede invocar:

```python tools = [ { "name": "get_user", "description": "Obtiene información de un usuario", "input_schema": { "type": "object", "properties": { "user_id": {"type": "string"} } } } ]

response = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "Dame info del usuario 123"}] ) ```

Es directo. Funciona. Y es perfecto para:

  • **Búsquedas simples**: "Encuentra este producto en nuestra base de datos"
  • **Cálculos**: "Calcula el total del carrito"
  • **Acciones puntuales**: "Envía este email"
  • **Consultas rápidas**: "¿Cuál es el precio actual?"

La ventaja es obvia: implementas rápido. La desventaja es que cada llamada es aislada. El modelo no tiene contexto persistente. No hay estado entre llamadas. No hay forma elegante de manejar flujos que requieren múltiples pasos interdependientes.

MCP: Para lo Complejo

MCP es diferente. Es un protocolo. Un estándar de comunicación entre el modelo y sistemas externos.

En lugar de funciones individuales, defines servidores MCP que exponen recursos, herramientas y prompts:

```javascript // Un servidor MCP simple const server = new Server({ name: "database-server", version: "1.0.0" });

// Expones herramientas server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "query_database", description: "Ejecuta queries complejas con transacciones", inputSchema: { type: "object", properties: { query: { type: "string" }, transaction_id: { type: "string" } } } } ] }; });

// Manejas las llamadas server.setRequestHandler(CallToolRequestSchema, async (request) => { // Aquí tienes control total sobre estado, conexiones, etc. return { content: [{ type: "text", text: resultado }] }; }); ```

Pero MCP es más que eso. También puedes exponer:

  • **Recursos**: Archivos, documentos, datos que el modelo puede leer directamente
  • **Prompts**: Templates reutilizables que el modelo puede invocar
  • **Contexto persistente**: El servidor mantiene estado entre llamadas

Cuándo Elegir Cada Uno

La regla es simple:

Function Calling cuando:

  • Necesitas una o dos llamadas puntuales
  • Las llamadas son independientes entre sí
  • El flujo es lineal y predecible
  • Implementas rápido (startup, MVP)
  • La complejidad es baja

MCP cuando:

  • Tienes flujos que requieren múltiples pasos coordinados
  • Necesitas mantener estado entre llamadas
  • Quieres reutilizar lógica en múltiples agentes
  • Trabajas con sistemas complejos (bases de datos, APIs con transacciones)
  • Necesitas actualizaciones en tiempo real
  • Planeas escalar (la arquitectura debe ser mantenible)

Un Ejemplo Real

Imagina que construyes un agente que procesa pedidos:

Con Function Calling (frágil):

1. El modelo llama a `get_inventory` 2. El modelo llama a `create_order` 3. El modelo llama a `update_inventory` 4. El modelo llama a `send_confirmation`

Problem: Si algo falla en el paso 3, ¿qué pasó en los pasos 1 y 2? ¿Cómo revienes? No hay transacciones. No hay rollback.

Con MCP (robusto):

Tienes un servidor MCP que expone:

  • Una herramienta `process_order_transaction` que maneja todos los pasos internamente
  • Mantiene estado de la transacción
  • Implementa rollback automático si algo falla
  • Devuelve un resultado atómico

El modelo simplemente invoca una herramienta. El servidor se encarga de la complejidad.

El Costo de Elegir Mal

Sobrecomplicar con MCP:

Uso MCP para una búsqueda simple en la base de datos. Ahora necesito:

  • Mantener un servidor MCP
  • Gestionar conexiones
  • Monitorear logs
  • Debuggear en dos sistemas (cliente + servidor)

Es overkill. Function calling habría sido suficiente.

Subestimar con Function Calling:

Empiezo con function calling para un agente de pedidos. Funciona. Luego necesito:

  • Manejar transacciones
  • Mantener consistencia
  • Agregar auditoría
  • Coordinar múltiples sistemas

Ahora tengo lógica dispersa en prompts, manejo de errores frágil, y un sistema que es difícil de mantener. Debería haber usado MCP desde el principio.

Mi Recomendación

Empieza simple. Function calling para MVP.

Cuando veas que el flujo se complica, que necesitas estado persistente, que tienes múltiples pasos que deben coordinarse: migra a MCP.

No es una migración complicada. Es un refactor limpio.

Pero aquí está el truco: MCP es relativamente nuevo. La mayoría de tutoriales te muestran function calling porque es más simple de explicar. No confundas "más popular" con "mejor para tu caso".

Conclusión

Function calling es tu navaja suiza. MCP es tu taller completo.

Usa la navaja para tareas rápidas. Monta el taller cuando necesites precisión y complejidad.

Y recuerda: la mejor arquitectura es la que puedes mantener sin perder la cabeza.

Brian Mena

Brian Mena

Ingeniero informatico construyendo productos digitales rentables: SaaS, directorios y agentes de IA. Todo desde cero, todo en produccion.

LinkedIn