MCP tools vs resources vs prompts: cuándo usar cada uno
Comparación práctica de tools, resources y prompts de MCP: control, discovery, schemas, permisos, frescura, UX, pruebas y diseño seguro del servidor.
Contenido del artículo
- 01Respuesta corta: acción, contexto y plantilla de interacción son contratos distintos
- 02El control plane define la UX, pero no concede autorización
- 03Tools: contrato de operación tipado con el mayor riesgo de autoridad
- 04Resources: URI, frescura y presupuesto de contexto deben ser explícitos
- 05Prompts: workflow reutilizable con argumentos visibles, no una frontera de policy
- 06Decision matrix y anti-patterns para un workflow de dominio
- 07Contract tests, canary rollout y rollback
Respuesta corta: acción, contexto y plantilla de interacción son contratos distintos
Una tool de MCP describe una operación que el modelo puede proponer invocar con argumentos tipados: buscar un pedido, calcular una tarifa o crear un borrador. Un resource aporta contexto que la aplicación host puede leer por URI y añadir a la conversación: un archivo, schema, referencia o snapshot. Un prompt es una plantilla parametrizada de mensajes que el usuario selecciona de forma consciente para un workflow repetible. Son tres control planes distintos, no tres formas de publicar la misma función.
Elija el primitive según quién controla el siguiente paso. Use una tool para una operación externa o un lookup autoritativo con parámetros de runtime. Use un resource cuando el usuario o la aplicación deban seleccionar y leer material como contexto. Use un prompt cuando el producto necesite un comando inicial visible con argumentos y messages preparados. Un mismo server puede combinar los tres: el prompt estructura la tarea, el resource aporta la policy y la tool realiza el lookup permitido. Prompt y resource no deben ocultar side effects, y una tool no debería usarse solo para transportar texto estático.
- Cambia o calcula estado a partir de runtime input → tool.
- Aporta contenido direccionable como contexto → resource.
- Inicia una interacción reutilizable elegida por el usuario → prompt.
- Necesita dos roles → composición de primitives con contratos separados.
El control plane define la UX, pero no concede autorización
La especificación describe las tools como model-controlled: un client puede mostrarlas al modelo y permitirle elegir una llamada. Para operaciones sensibles, el client debe mostrar los inputs y permitir que una persona rechace la acción. Los resources son application-driven: el host decide si ofrece picker, búsqueda, inclusión automática u otra interfaz. Los prompts son user-controlled y están pensados como comandos o templates accesibles al usuario, aunque el protocolo no impone una UI concreta.
Estas etiquetas no son autorización. Que el modelo elija una tool no concede permiso para un side effect; seleccionar un resource no demuestra acceso a cada URI; ejecutar un prompt no autoriza todas las acciones descritas en su texto. Client y server validan por separado identity, scopes, tenant, target y estado actual. Una acción con consecuencias necesita preview, confirmation o policy gate en el momento de ejecutarse, no confianza en una selección previa del prompt.
Tools: contrato de operación tipado con el mayor riesgo de autoridad
La definición de una tool necesita un name estable, description clara y JSON Schema válido para el input. Un outputSchema opcional permite al client validar structuredContent; ayuda a la automatización downstream, pero no prueba que los datos sean verdaderos. El server valida schema y restricciones de negocio, comprueba el permiso sobre el objeto concreto y devuelve tool execution error para fallos de dominio recuperables. Reserve protocol errors para requests mal formados o tools desconocidas.
Separe operaciones de lectura y escritura. `orders.get` puede ser un lookup de bajo riesgo, mientras que `orders.refund` debería exigir amount, currency, order version, reason, idempotency key y approval receipt. Evite un `execute_api` universal con path y body arbitrarios: oculta la autoridad al modelo, al reviewer y al audit log. Las tool annotations sirven como hints de UX, no como security policy fiable salvo que el client confíe en el server.
Un tool result puede contener text, structured content, resource link o embedded resource. Eso no convierte la tool en resource: la invocación sigue siendo una operación con inputs, timeout, semántica de errores y audit event. Si un resultado grande tiene URI estable o se reutiliza, devuelva un resumen estructurado breve y un resource link en lugar de copiar todo el corpus en cada resultado.
- Input schema valida la forma; policy valida permiso e intención.
- Output schema valida estructura; el sistema autoritativo valida el hecho.
- Write tool → target exacto, confirmation, idempotency y postcondition.
- Timeout ambiguo → reconcile antes de retry.
Resources: URI, frescura y presupuesto de contexto deben ser explícitos
Un resource tiene una URI única y puede contener texto o contenido binario con MIME type. Los resource templates publican URI parametrizadas y la completion opcional puede ayudar con un argumento. El client primero llama a resources/list o templates/list y después a resources/read. Las subscriptions y listChanged son capabilities opcionales separadas; soportar resources no implica refresh automático.
Para producción, registre source owner, data classification, revision o lastModified, audience permitido, size budget y cache policy. Annotations como `audience`, `priority` y `lastModified` son hints para el client, no decisiones de access control. El server comprueba URI, authorization y resource permission en cada lectura. No coloque secretos en una URI predecible ni suponga que un elemento no listado no puede leerse mediante request directo.
Un resource es adecuado para contexto, pero no garantiza que el modelo lo haya usado o citado correctamente. Los evals deben comprobar current revision, passage support, conflict disclosure, no-answer behavior y cross-scope canary. Para un business fact que cambia con frecuencia puede ser mejor una read-only tool con lookup autoritativo en el momento del request; para documentación navegable con identifiers estables, un resource ofrece un contrato mejor de discovery y cache.
- Contenido estable y navegable → resource o resource template.
- Dato vivo parametrizado → a menudo read-only tool.
- Subscription no sustituye revision check antes de una decisión importante.
- Visibilidad de URI no equivale a permiso.
Prompts: workflow reutilizable con argumentos visibles, no una frontera de policy
Una definición de prompt tiene name, title y description opcionales y una lista de arguments. prompts/get devuelve description y messages donde el server inserta argumentos validados. Los messages pueden incluir text, image, audio o embedded resource. Un buen prompt explica el resultado y los inputs esperados: `review_incident` con incident ID y review depth es más útil que un `analyze` ambiguo.
Un prompt funciona bien como slash-command descubrible, onboarding o secuencia estandarizada de análisis. No es automatización server-side ni garantiza que el modelo ejecute las instrucciones. No esconda approval, credential o una acción irreversible en el template. Si el workflow necesita una tool, el prompt puede preparar messages y pedir análisis, pero el client sigue aplicando tool policy y el server vuelve a autorizar la llamada.
Versione el contenido del template o guarde al menos su hash en la evaluation evidence. listChanged informa de que el catálogo cambió, pero una conversación activa puede contener ya messages antiguos. El regression set debe cubrir argument escaping, prompt injection en campos del usuario, argumentos ausentes, locale, permisos de embedded resources y comportamiento después de cambiar el template.
Decision matrix y anti-patterns para un workflow de dominio
Imagine un support server. `support://policies/refunds/2026-09` es un resource porque es contenido de policy versionado para lectura. `draft_refund_review` es un prompt porque el usuario elige un template repetible de review con ticket ID. `tickets.get` y `refunds.create_draft` son tools porque realizan lookup en runtime y crean un draft controlado. El `refunds.submit` final conviene separarlo con scope y confirmation más fuertes. Así source, reasoning workflow y authority quedan visibles como límites distintos.
Errores comunes: publicar cada fila de base de datos como tool; ocultar un write request en una resource URI; devolver policy stale mediante una tool sin revision; usar un prompt como system policy; duplicar el mismo content en prompt, resource y tool description; o exponer una mega-tool para todas las APIs. Estos patrones empeoran discovery, aumentan context, difuminan permissions e impiden que los evals localicen el fallo.
Antes de implementar, complete una contract card breve: user outcome, controller, data owner, freshness, input/output shape, side effects, permission check, audit event, failure semantics, context cost y rollback. Si dos entidades tienen authority o lifecycle distintos, use primitives distintos aunque compartan backend endpoint.
- Context failure → revisar resource revision y selection.
- Instruction failure → revisar prompt version y argument handling.
- Execution failure → revisar tool schema, policy, effect y reconciliation.
- Fallo mixto → conservar receipts separados para cada límite.
Contract tests, canary rollout y rollback
Empiece la contract suite con combinaciones de capabilities: server con cada primitive por separado, los tres juntos y cambios de catálogo. Pruebe pagination, names o URI desconocidos, argumentos inválidos, MIME handling, structured output, listChanged y resource subscription solo cuando la capability esté declarada. Los casos negativos de seguridad cambian tenant, target, URI, prompt argument y tool result, añaden indirect injection al resource y repiten un write después de un timeout ambiguo.
Ejecute un eval end-to-end sobre un caso sintético de soporte: el usuario elige un prompt, el client lee una policy revision concreta, el modelo propone una read tool y el write draft requiere confirmation separada. El evidence pack contiene protocol version, capability manifest, catalog hashes, resource revision, rendered prompt, tool inputs/results, approval receipt, final state y reviewer verdict. Así se identifica qué límite falló sin depender de una final answer fluida.
Inicie el rollout con un read-only resource, un prompt y una read-only tool. Tras validar scope y audit, añada un draft write reversible; mantenga acciones irreversibles fuera de model authority hasta contar con un approval contract separado. Rollback desactiva la capability o tool afectada, revoca scope, fija la última revision verificada de resource o prompt y conserva diagnostics read-only. La reactivación exige regression sobre el primitive cambiado y toda la composición.
- Hard gate → cross-tenant read, side effect oculto o write no autorizado.
- Quality gate → revision stale, claim no soportado o prompt outcome ambiguo.
- Compatibility gate → la capability anunciada no coincide con el method behavior.
- Recovery gate → retry no duplica el effect ni rompe la audit chain.
Ejemplos prácticos
Workflow de soporte con tres primitives
El usuario inicia un prompt para revisar un ticket. El client lee un resource versionado de refund policy. El modelo llama a una read-only ticket tool, prepara la conclusión y solo tras una confirmation separada llama a la create-draft tool. La evidence conserva revisions y receipts en cada límite.
Cuándo un resource es mejor que una tool
El server publica un catálogo de API schemas versionados como resource templates. El host ofrece un picker y cachea revisions sin cambios. Solo hace falta una tool para validar el schema en vivo contra un deployment concreto, no para reenviar un documento estático.
FAQ
¿Cuál es la diferencia principal entre MCP tools, resources y prompts?
Una tool es una operación model-controlled, un resource es contexto application-managed por URI y un prompt es un template reutilizable de messages elegido por el usuario. El client concreto define la UI; authority y permissions siempre se verifican aparte.
¿Puede una tool devolver un resource?
Sí. Un tool result puede contener un embedded resource o un resource link. La llamada sigue siendo un contrato de operación con inputs, errors y audit, mientras el resource mantiene sus propias semánticas de URI, permission y freshness.
¿Cuándo conviene leer datos con una tool y cuándo con un resource?
Use un resource para contenido navegable, direccionable y a menudo versionado. Use una read-only tool para lookup parametrizado en vivo cuando el resultado depende de runtime input, authorization y estado actual autoritativo.
¿Puede un prompt aprobar automáticamente una tool call?
No. Ejecutar un prompt no autoriza una acción posterior. El client aplica confirmation policy y el server comprueba identity, scope, target y state en cada tool call con consecuencias.
Materiales relacionados
Una elección práctica entre una respuesta MCP de texto o estructurada y una MCP App interactiva: criterios de valor, arquitectura, seguridad, fallback, pruebas y rollout.
MCP Tasks vs tool calls síncronos: cómo ejecutar operaciones largasUna elección práctica entre MCP tools/call estándar y MCP Tasks experimentales para operaciones largas: capability negotiation, estados, polling, cancelación, seguridad, pruebas y rollout.
Human-in-the-loop para IAUna arquitectura práctica de producción para supervisión humana: incorpora a una persona en un punto concreto de riesgo y dale suficiente contexto para ejercer un control real, no meramente formal. Cubre contratos, límites de autoridad, fallos, evaluación y despliegue controlado.