MCP frente a function calling: diferencias con ejemplos de OpenAI y Claude

MCP y function calling resuelven problemas distintos. Function calling permite que un modelo pida una acción, mientras que MCP da a las aplicaciones un protocolo común para encontrar herramientas. Este artículo compara ambos con ejemplos de código de OpenAI y Claude, una lista de verificación de seguridad y una regla sencilla para elegir.

MCP frente a function calling: diferencias con ejemplos de OpenAI y Claude
Cristian Da Conceicao
Fundador de Picasso IA

Elegir la capa equivocada te obligará a construir la misma integración dos veces. MCP vs function calling parece una encrucijada en la que hay que elegir, pero las dos piezas están en niveles distintos de la misma pila. Function calling es la forma en que un modelo pide una acción. El Model Context Protocol (MCP) es la forma en que una aplicación encuentra las herramientas en las que se ejecuta esa acción y llega a ellas.

La respuesta corta, antes de cualquier código: function calling es una función del modelo, MCP es un protocolo de comunicación y la mayoría de las configuraciones con MCP usan function calling por debajo. Con dos o tres herramientas dentro de una misma app, el function calling tradicional es más sencillo. Cuando varias apps necesitan las mismas herramientas, MCP se amortiza rápido. Las secciones siguientes muestran ejemplos de OpenAI y Claude para ambos enfoques, uno al lado del otro.

Mano a punto de conectar un cable USB-C a un equipo portátil junto a un hub de aluminio

Qué hace realmente function calling

Un modelo de lenguaje solo produce texto. Function calling le da a ese texto una forma en la que tu código puede confiar. En cada petición envías una lista de definiciones de herramientas: un nombre, una descripción en lenguaje natural y un JSON Schema para los argumentos. Cuando el modelo decide que hace falta una herramienta, no ejecuta nada. Devuelve una llamada estructurada con el nombre de la herramienta y sus argumentos, y tu código hace el trabajo.

El bucle de petición y respuesta

  1. Tu app envía el mensaje del usuario junto con las definiciones de herramientas.
  2. El modelo responde con una llamada a herramienta en lugar de texto final.
  3. Tu código ejecuta la función y captura el resultado.
  4. Envías el resultado de vuelta como un mensaje nuevo.
  5. El modelo escribe la respuesta final o pide otra herramienta.

💡 Consejo: El modelo nunca ejecuta código. Propone una llamada, y tu aplicación decide si la ejecuta. Ese espacio es exactamente donde deben ir los controles de permisos y el registro de actividad.

Mano de un carpintero sacando un martillo de su silueta pintada en una pared de paneles perforados

Dónde vive el esquema

Las definiciones viven en tu propio código, normalmente junto a la función que describen. OpenAI llama parameters al campo del esquema. Claude lo llama input_schema. El envoltorio varía un poco entre proveedores, así que una herramienta escrita para uno necesita un adaptador ligero para el otro.

Ese es el verdadero costo del function calling tradicional: cada app mantiene su propia copia de cada definición, y cada proveedor pide su propio formato. Si construyes la misma consulta de pedidos para una app de chat, un plugin de IDE y un bot de soporte, mantendrás tres copias.

Lo que MCP añade encima

Anthropic presentó MCP en noviembre de 2024 como protocolo abierto, y OpenAI lo adoptó en marzo de 2025. MCP estandariza cómo se describen, listan y llaman las herramientas, de modo que una herramienta escrita una sola vez como servidor MCP funciona en cualquier cliente que hable el protocolo. Es el mismo puerto estándar de la foto de arriba: una forma de conector, muchos dispositivos. En lugar de N apps por M herramientas de código de conexión a medida, construyes N clientes y M servidores.

Hosts, clientes y servidores

MCP tiene tres roles:

  • Host: la aplicación que ve el usuario, como una app de chat, un IDE o tu propio agente.
  • Cliente: un conector dentro del host que mantiene una sesión con un servidor.
  • Servidor: un pequeño programa que expone herramientas, datos y prompts.

Los mensajes usan JSON-RPC 2.0. Los servidores locales se comunican por stdio, y los remotos por Streamable HTTP. El cliente abre una sesión, pregunta al servidor qué ofrece y llama a las cosas por su nombre.

Operario insertando un cordón trenzado en un antiguo cuadro de conmutación telefónica

Herramientas, recursos y prompts

Un servidor puede exponer tres tipos de capacidades:

PrimitivaQué esQuién la controla
HerramientasAcciones o cálculos que el modelo puede invocarEl modelo
RecursosDatos legibles identificados por una URI, como un archivo o un registroLa aplicación
PromptsPlantillas de mensajes reutilizablesEl usuario

Solo las herramientas se solapan con function calling. Los recursos y los prompts no tienen una respuesta estándar en el function calling tradicional, y eso es en parte lo que lleva a la gente a usar MCP.

Esto es el tráfico de red de una sola herramienta. El cliente pide al servidor sus herramientas:

{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}

El servidor responde con definiciones que se parecen a las que escribirías a mano, salvo que el campo del esquema es inputSchema en camelCase:

{"jsonrpc": "2.0", "id": 1, "result": {"tools": [{
  "name": "get_order_status",
  "description": "Look up the shipping status of an order by its ID.",
  "inputSchema": {
    "type": "object",
    "properties": {"order_id": {"type": "string"}},
    "required": ["order_id"]
  }
}]}}

Más tarde, cuando el modelo pide esa herramienta, el cliente envía:

{"jsonrpc": "2.0", "id": 2, "method": "tools/call",
 "params": {"name": "get_order_status", "arguments": {"order_id": "8841"}}}

Mano abriendo un cajón de fichero de madera lleno de fichas

MCP frente a function calling, lado a lado

PreguntaFunction callingMCP
¿Qué es?Una función de la API del modeloUn protocolo abierto entre apps y servidores de herramientas
¿Dónde viven las definiciones?En el código de tu app, enviadas con cada peticiónEn el servidor, listadas a demanda con tools/list
¿Quién ejecuta la herramienta?El proceso de tu aplicaciónEl servidor MCP, local o remoto
Reutilización entre appsCopiar y adaptar en cada appEscribir una vez, conectar desde cualquier cliente
¿Necesita el otro?NoSí, el modelo sigue llamando herramientas mediante function calling
Esfuerzo de configuraciónMinutosUnas horas para el primer servidor, minutos para uno existente
Mejor paraPocas herramientas, lógica privada de la appHerramientas compartidas e integraciones de terceros

Vista cenital de un único estuche de destornilladores junto a un juego modular de puntas en una caja rígida

Cómo las llamadas MCP se convierten en function calls

Los dos no son rivales, porque MCP alimenta a function calling. Este es el recorrido completo de una petición en una configuración con MCP:

  1. El cliente MCP lista las herramientas de cada servidor conectado.
  2. Las convierte al formato de herramientas propio del proveedor y las envía con la petición.
  3. El modelo devuelve una llamada a función normal.
  4. El cliente MCP la reenvía al servidor correcto como tools/call.
  5. El resultado del servidor vuelve al modelo como un resultado de herramienta normal.

Desde el punto de vista del modelo, no ha cambiado nada. Vio definiciones de herramientas y emitió una llamada. Lo que cambia es quién escribió las definiciones y quién ejecutó la función.

💡 Regla general: Si puedes señalar la línea de tu propio código que ejecuta la función, estás usando function calling tradicional. Si la ejecuta un servidor aparte, estás usando MCP, y el function calling sigue ocurriendo entre el modelo y el cliente.

Ejemplos de OpenAI y Claude en código

La misma herramienta, de cuatro formas: una consulta del estado de un pedido. Los ejemplos usan Python, y la URL del servidor MCP es un marcador que sustituyes por la tuya.

Desarrolladora escribiendo en un escritorio de una oficina tranquila tipo loft al atardecer

Function calling de OpenAI

Esta versión usa la Responses API con GPT 5. Defines la herramienta, ejecutas tú la función y devuelves un elemento function_call_output.

import json
from openai import OpenAI

client = OpenAI()

def get_order_status(order_id: str) -> dict:
    return {"order_id": order_id, "status": "shipped", "eta": "2026-10-09"}

tools = [{
    "type": "function",
    "name": "get_order_status",
    "description": "Look up the shipping status of an order by its ID.",
    "parameters": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"],
        "additionalProperties": False,
    },
    "strict": True,
}]

input_items = [{"role": "user", "content": "Where is order 8841?"}]
response = client.responses.create(model="gpt-5", tools=tools, input=input_items)

input_items += response.output
for item in response.output:
    if item.type == "function_call":
        result = get_order_status(**json.loads(item.arguments))
        input_items.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps(result),
        })

final = client.responses.create(model="gpt-5", tools=tools, input=input_items)
print(final.output_text)

MCP remoto en OpenAI

La misma consulta, sin esquema y sin bucle en tu código. La API se conecta al servidor, lista sus herramientas y las llama por ti.

response = client.responses.create(
    model="gpt-5",
    tools=[{
        "type": "mcp",
        "server_label": "orders",
        "server_url": "https://mcp.example.com/mcp",
        "require_approval": "always",
    }],
    input="Where is order 8841?",
)
print(response.output_text)

Con require_approval configurado en "always", la respuesta contiene una solicitud de aprobación para cada llamada, y tu código decide si la permite. Usa "never" solo con servidores en los que confíes plenamente.

Tool use de Claude

La Messages API sigue el mismo bucle con nombres de campos distintos. El esquema va en input_schema, el modelo señala una llamada con stop_reason == "tool_use", y tú respondes con un bloque tool_result.

import json
import anthropic

client = anthropic.Anthropic()

tools = [{
    "name": "get_order_status",
    "description": "Look up the shipping status of an order by its ID.",
    "input_schema": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"],
    },
}]

messages = [{"role": "user", "content": "Where is order 8841?"}]
response = client.messages.create(
    model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages
)

if response.stop_reason == "tool_use":
    messages.append({"role": "assistant", "content": response.content})
    results = []
    for block in response.content:
        if block.type == "tool_use":
            output = get_order_status(**block.input)
            results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(output),
            })
    messages.append({"role": "user", "content": results})
    response = client.messages.create(
        model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages
    )

print(response.content[-1].text)

Envía todos los tool_result de un turno en un único mensaje de usuario. Repartirlos en varios mensajes enseña al modelo a dejar de llamar herramientas en paralelo.

Dos ingenieros revisando un diagrama de arquitectura impreso alrededor de una mesa de roble

Conector MCP de Claude

El conector MCP necesita dos partes: el servidor en mcp_servers, y una entrada mcp_toolset correspondiente en tools. Además, va detrás de una cabecera beta, y se conecta a servidores remotos por HTTP, no a servidores locales por stdio.

response = client.beta.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    betas=["mcp-client-2025-11-20"],
    mcp_servers=[{
        "type": "url",
        "url": "https://mcp.example.com/mcp",
        "name": "orders",
    }],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "orders"}],
    messages=[{"role": "user", "content": "Where is order 8841?"}],
)

Compara los cuatro. Las versiones con MCP son más cortas porque el esquema y el bucle han salido de tu código. La contrapartida es el control: entregas el bucle a la API y confías en lo que el servidor diga de sí mismo.

Trampas de seguridad y costo a vigilar

Descripciones de herramientas no fiables

Los nombres, las descripciones y los resultados de las herramientas fluyen todos hacia el contexto del modelo. Un servidor descuidado o malintencionado puede esconder instrucciones en ellos, lo que supone una vía de inyección de prompts. El function calling tradicional tiene el mismo riesgo con los resultados de las herramientas, pero MCP lo amplía porque terceros escriben las descripciones.

  • Conecta solo servidores en los que confíes, y fija las versiones cuando sea posible.
  • Mantén la aprobación humana en cualquier acción que escriba, envíe o borre.
  • Da a cada servidor las credenciales más restringidas que sigan funcionando.
  • Registra cada llamada con sus argumentos.

Candado pesado con cadena en un armario de equipos cerrado en una sala de redes

Costo en tokens de las listas largas de herramientas

Cada definición se envía como tokens de entrada en cada petición. Cuarenta herramientas con descripciones largas pueden añadir miles de tokens antes de que el usuario diga una palabra. MCP lo facilita sin querer, porque al conectar un servidor se cargan todas sus herramientas de una vez.

Tres soluciones funcionan bien:

  1. Conecta solo los servidores que necesita cada tarea.
  2. Acorta las descripciones a lo que el modelo necesita saber para elegir la herramienta.
  3. Carga las definiciones a demanda, por ejemplo con la herramienta de búsqueda de herramientas de Claude, y mantén cacheable la parte estable de la lista.

💡 Errores comunes: conectar todos los servidores a cada petición, aprobar automáticamente las acciones de escritura y no registrar las llamadas. Cada uno es fácil de evitar el primer día y caro de arreglar después de un incidente.

Cuándo elegir cada uno

Elige function calling cuando

  • Tienes un puñado de herramientas que usa una sola app.
  • Las herramientas necesitan acceso dentro del proceso a tu propio estado, como una sesión de base de datos o el usuario que ha iniciado sesión.
  • Quieres control total sobre la latencia, los reintentos y las pantallas de aprobación.
  • Estás haciendo un prototipo y quieres la menor cantidad posible de piezas móviles.

Elige MCP cuando

  • Varios clientes necesitan las mismas herramientas: una app de chat, un IDE y un agente.
  • Un tercero ya ofrece un servidor MCP para el servicio que necesitas.
  • Equipos distintos son dueños de las herramientas y de las apps, y no deberían bloquearse entre sí.
  • Quieres cambiar de proveedor de modelos sin reescribir el código de conexión de herramientas.

Excursionista en una bifurcación de un sendero del bosque al amanecer

La mayoría de los conjuntos de herramientas de producción acaban siendo mixtos. La lógica privada se mantiene como herramientas de función dentro del propio proceso, y las capacidades compartidas o de terceros llegan a través de servidores MCP. Ambas llegan al modelo mediante la misma interfaz de llamada a funciones, así que combinarlas casi no supone ningún costo.

Un servidor MCP real: PicassoIA

PicassoIA expone su generación de imágenes y video a través de un conector MCP, lo que lo convierte en un buen ejemplo de las decisiones de diseño anteriores. La generación lleva tiempo, así que las herramientas se dividen en las que inician trabajos y una de consulta de estado. Es la misma forma que construirías a mano con dos definiciones de función.

Lo que expone el conector

HerramientaQué hace
generate_imageInicia un trabajo de imagen y devuelve un ID de predicción
edit_imageInicia una edición de una imagen existente
generate_video_picassoiaInicia un trabajo de video con el modelo de video de PicassoIA
generate_video_seedanceInicia un trabajo de video con Seedance
get_generationConsulta una predicción hasta que tiene éxito o falla
list_generationsLista las generaciones anteriores
cancel_generationCancela un trabajo que sigue en cola o en ejecución
list_modelsMuestra qué modelos puede usar tu cuenta
get_accountMuestra tu plan y los límites de ejecución en paralelo

El patrón merece copiarse en tus propios servidores: devolver un ID rápido, consultar con una herramienta aparte y dar al modelo una herramienta de cancelación para que pueda desistir de una ejecución mala. La documentación para desarrolladores indica 5 predicciones simultáneas por cuenta, compartidas entre las credenciales de la API y las conexiones MCP, así que un cliente bien diseñado consulta en lugar de lanzarlo todo a la vez. Los mismos trabajos también están disponibles a través de una API REST de estilo Replicate en https://api.picassoia.com/v1. Consulta la página de precios para saber qué planes incluyen acceso a la API y a MCP.

Cómo usar Claude Sonnet 5 en PicassoIA

Antes de escribir código, puedes redactar esquemas de herramientas y probar prompts en la página de Claude Sonnet 5. La página del modelo muestra estas entradas:

  1. Prompt: escribe la petición, por ejemplo: "Escribe un JSON Schema para una herramienta llamada get_order_status que reciba un ID de pedido y devuelva el estado del envío."
  2. System prompt (opcional): define un rol una vez, como "Eres un diseñador de APIs. Responde solo con JSON."
  3. Effort: el valor por defecto es low, que desactiva el razonamiento para obtener respuestas más rápidas y baratas. Cambia a high o max para un error complicado en varios archivos o un diseño con muchas herramientas. Los niveles son low, medium, high, xhigh y max.
  4. Max tokens: el valor por defecto es 8192, suficiente para un esquema completo con su explicación.
  5. Imagen (opcional): adjunta una captura de un error o un boceto como contexto adicional.
  6. Ejecuta y compara: envía el mismo prompt a GPT 5 y mira qué esquema es más limpio.

💡 Consejo: Pide primero el esquema y luego pide al modelo que critique su propia descripción. Las descripciones cortas y concretas facilitan que la herramienta se elija correctamente.

Crea tus propias imágenes con Picasso IA

Cada foto de este artículo empezó como un prompt de texto: un panel perforado, un cuadro de conmutación, un fichero de tarjetas, una bifurcación en el sendero. Cada una convierte una idea abstracta en algo que puedes ver, y la misma receta sirve para tus publicaciones, documentación y presentaciones.

Usa esta estructura: sujeto y acción, entorno, iluminación, cámara y objetivo, detalles de textura. Por ejemplo: "Primer plano de una mano conectando un cable a un equipo portátil sobre un escritorio de roble, luz suave de ventana desde la derecha, objetivo macro de 100 mm, profundidad de campo reducida, textura de aluminio cepillado."

Abre Picasso IA, elige un modelo de texto a imagen de la lista completa de modelos, pega un prompt con esa forma y ejecútalo. Cambia un detalle cada vez, como el objetivo o la dirección de la luz, y observa cómo cambia el resultado. Si ya trabajas con Claude, conecta el conector MCP de PicassoIA desde tu cuenta y pide imágenes directamente desde el chat. Prueba hoy tres variaciones de una misma idea y quédate con la mejor.

Compartir este artículo

Elige tu idioma