Prompts MCP: qué son, cómo funcionan y cómo los muestran los clientes
Prompts MCP en la especificación 2026-07-28: quién los invoca, prompts/list y prompts/get, argumentos de texto, autocompletado y cómo los muestra cada cliente.
Por Andrés León Bohórquez Actualizado el
Datos a 8 de octubre de 2026 · especificación MCP 2026-07-28
Los prompts MCP son plantillas de mensajes con nombre que un servidor publica y que el usuario elige a mano, normalmente desde un comando o un menú. Siguen en la especificación 2026-07-28 casi como estaban, pero con los cambios del protocolo sin estado: pistas de caché en el listado, resultType en cada resultado y avisos de cambio por suscripción. En esta guía vas a ver qué viaja por la red, qué admiten los argumentos, cómo funciona el autocompletado y cómo los muestran Claude Code, VS Code, Claude y Cursor.
Este artículo se publicó en 2025 con otro enfoque y hoy lo hemos reescrito entero. La versión anterior tenía errores que repasamos al final. Los bloques de código son literales de la especificación o de la referencia del curso, que contiene ejemplos ejecutados, y cada uno lleva su fuente al pie. Consultamos todas las fuentes el 8 de octubre de 2026.
¿Qué es un prompt de MCP y quién lo invoca?
La especificación lo define como una forma estándar de que los servidores expongan plantillas de prompt a los clientes. El cliente descubre los prompts disponibles, obtiene su contenido y le pasa argumentos para adaptarlo. El servidor lo entrega ya rellenado como una lista de mensajes, que el host añade a la conversación.
Lo que distingue a un prompt de las otras dos primitivas es quién decide usarlo. La especificación dice que los prompts son «user-controlled». Es decir, se exponen para que el usuario los seleccione de forma explícita. Las tools, en cambio, son «model-controlled»: el modelo las descubre y las invoca. Los resources son «application-driven», porque es la aplicación host la que decide cómo incorporarlos.
La especificación pone como ejemplo los comandos con barra, pero no obliga a nada: «the protocol itself does not mandate any specific user interaction model». Cada cliente decide si los muestra como comando, en un menú o con un botón. La página divulgativa oficial cita los comandos con barra y los botones dedicados, y añade las paletas de comandos y los menús contextuales.
Un matiz que se pasa por alto a menudo es que «user-controlled» se refiere a quién decide cuándo se usa el prompt, no a quién escribe su contenido. El contenido lo define el servidor. Ninguna de las fuentes oficiales que hemos consultado describe que el modelo pueda invocar un prompt por su cuenta.
¿Qué devuelve prompts/list en la versión 2026-07-28?
Un servidor que tiene prompts debe declarar la capacidad prompts en su DiscoverResult, la respuesta a server/discover. Opcionalmente añade listChanged para indicar que avisará cuando cambie la lista. Si el servidor no declara la capacidad, prompts/list responde con el error -32601.
Esta es la respuesta de ejemplo de la especificación:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"prompts": [
{
"name": "code_review",
"title": "Request Code Review",
"description": "Asks the LLM to analyze code quality and suggest improvements",
"arguments": [
{
"name": "code",
"description": "The code to review",
"required": true
}
],
"icons": [
{
"src": "https://example.com/review-icon.svg",
"mimeType": "image/svg+xml",
"sizes": ["any"]
}
]
}
],
"nextCursor": "next-page-cursor",
"ttlMs": 600000,
"cacheScope": "public"
}
}
Ejemplo literal de la especificación 2026-07-28, copiado en la referencia del curso (spec-2026-07-28.md §5.7).
Hay tres detalles nuevos respecto a 2025. El primero es resultType, que lleva todo resultado. El segundo son ttlMs y cacheScope, porque la página de caché dice que los servidores «MUST include caching hints» en prompts/list. El alcance "public" sirve cuando la lista es igual para todos los usuarios, y "private" cuando la filtras por usuario.
El tercero es una regla del protocolo sin estado. El listado puede cambiar con el tiempo, pero «MUST NOT vary per-connection». Sí puede variar según la autorización de cada petición, por ejemplo para devolver solo los prompts que permiten los scopes de quien pregunta. Lo que cambia en 2026-07-28 para todas las peticiones lo contamos en MCP 2026-07-28, el protocolo sin estado.
Los ejemplos de la especificación omiten _meta por brevedad, pero cada petición real lo lleva. Dentro van la versión del protocolo, clientInfo y clientCapabilities.
¿Qué tipo de argumentos admite un prompt?
Cada argumento tiene name y, de forma opcional, title, description y required. Nada más. El schema no tiene campo de tipo, ni enumeraciones, ni JSON Schema. En la petición, arguments es un mapa de texto a texto ({ [key: string]: string }). Por eso todos los valores llegan como cadenas y es tu servidor quien los valida. La especificación dice que los servidores «SHOULD validate prompt arguments» y que deben validar entradas y salidas para evitar inyecciones.
Las fuentes oficiales se contradicen en este punto. La página divulgativa server-concepts enseña un prompt con un argumento "type": "number" y otro de tipo lista. Esos campos no existen en el schema ni en la especificación, y nosotros seguimos al schema.
El SDK de TypeScript v2 añade una capa encima. Allí describes los argumentos con un objeto Zod (argsSchema), y el SDK saca de él el listado y la validación. Su documentación explica que el .describe() de Zod llega como description del argumento. Por la red, sin embargo, solo viajan el nombre, la descripción y si es obligatorio.
¿Qué devuelve prompts/get?
El cliente pide un prompt con prompts/get, su name y sus arguments. El servidor responde con una description opcional y la lista messages:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"description": "Code review prompt",
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Please review this Python code:\ndef hello():\n print('world')"
}
}
]
}
}
Ejemplo literal de la especificación 2026-07-28, copiado en la referencia del curso (spec-2026-07-28.md §5.7).
Cada mensaje tiene un role, que solo puede ser user o assistant. No existe el rol system. Como la lista está ordenada y cada mensaje lleva su rol, puedes alternar mensajes de usuario y de asistente para dar ejemplos al modelo. La lección de prompts lo hace así con un caso de Nortia Logística.
Cada mensaje lleva un único bloque de contenido, que puede ser text, image, audio, resource_link o resource. Las imágenes y el audio van en base64 con su tipo MIME. Un resource_link no trae el contenido, solo la URI y unos metadatos, y el cliente decide si la lee. Un resource embebido trae el contenido entero, así que el cliente no necesita resources/read.
El resource embebido tiene requisitos estrictos. Debe incluir una URI válida, el tipo MIME y el contenido, en text o en blob base64. Así puedes meter en la conversación documentación, código de ejemplo u otro material que gobierna el servidor. Qué es un resource y cómo se lee está en la lección de recursos.
Hay cuatro reglas más que conviene conocer:
- El resultado de
prompts/getno se cachea. No llevattlMsnicacheScope, así que cada invocación obtiene el contenido vigente. - El servidor puede responder con
InputRequiredResultsi le falta información. El cliente repite la petición coninputResponsesy, si el servidor lo envió, conrequestState. - En Streamable HTTP, la cabecera
Mcp-Namelleva el nombre del prompt. - Un nombre inválido o un argumento obligatorio ausente se responden con
-32602, y un fallo interno con-32603. Los prompts no tienenisError, que es propio de las tools.
¿Cómo funciona el autocompletado de argumentos?
La especificación permite que el servidor sugiera valores mientras el usuario escribe un argumento. Para eso el servidor tiene que declarar una capacidad propia, completions: {}, distinta de prompts. Sin ella, completion/complete responde -32601.
El cliente envía una referencia al prompt ({"type": "ref/prompt", "name": "code_review"}), el argumento que se está escribiendo con su name y su value, y en context.arguments los argumentos que el usuario ya rellenó. El servidor devuelve completion.values, que es una lista de cadenas de 100 elementos como máximo, junto con total y hasMore opcionales.
La especificación recomienda al servidor ordenar por relevancia y limitar la frecuencia de peticiones, y al cliente agrupar las peticiones rápidas. También pide controlar el acceso a sugerencias sensibles, porque el autocompletado puede revelar datos.
En el SDK de TypeScript v2 envuelves un campo de argsSchema con completable(...), y el callback devuelve un string[]. Su documentación dice que el primer campo completable registra el manejador de completion/complete y anuncia la capacidad completions sin que tengas que declararla. Si ningún campo lo usa, el servidor no anuncia la capacidad. Por eso el ejemplo de la lección 06, ejecutado con la versión 2.3.0 del paquete, no la anuncia.
¿Cómo se entera el cliente de que cambió la lista?
En 2025-06-18, el servidor enviaba notifications/prompts/list_changed por la sesión. En 2026-07-28 ya no hay sesión. El cliente abre un stream con subscriptions/listen y pide promptsListChanged: true, y solo por ese stream llega el aviso. Al recibirlo, el cliente vuelve a pedir prompts/list, aunque no haya vencido el ttlMs de su caché.
Claude Code documenta cómo lo trata. En una sesión interactiva, al recibir un list_changed vuelve a pedir la lista a ese servidor. En modo no interactivo con -p y en el Agent SDK solo refresca la lista de tools.
¿Cómo se escribe un prompt con el SDK de TypeScript v2?
En la versión 2 del SDK, server.prompt() ya no existe y se usa registerPrompt. Este fragmento sale del servidor mínimo de la referencia del curso, que se ejecutó tal cual:
server.registerPrompt(
'revisar-codigo',
{
title: 'Revisar código',
description: 'Pide una revisión de código',
argsSchema: z.object({ codigo: z.string().describe('Código a revisar') })
},
({ codigo }) => ({
messages: [{ role: 'user' as const, content: { type: 'text' as const, text: `Revisa este código:\n\n${codigo}` } }]
})
);
Ejemplo literal de docs/curso/referencia/sdk-typescript.md §5 (src/build-server.ts), ejecutado con @modelcontextprotocol/server 2.3.0.
Un cliente que llama a listPrompts() y a getPrompt() contra ese servidor, e imprime solo el nombre y los argumentos de cada prompt, obtiene esta salida real:
prompts: [{"name":"revisar-codigo","arguments":[{"name":"codigo","description":"Código a revisar","required":true}]}]
getPrompt: [{"role":"user","content":{"type":"text","text":"Revisa este código:\n\nlet x = 1"}}]
Salida literal del Ejemplo 1 de docs/curso/referencia/sdk-typescript.md §5.
Fíjate en la primera línea. El objeto Zod se convierte en name, description y required, sin tipo, como vimos al hablar de los argumentos. Ten en cuenta también que el SDK v2 no habla 2026-07-28 por defecto. Para servir esa versión por stdio se usa serveStdio(...). El servidor completo, con transporte y cliente, está en crear un servidor MCP en TypeScript y en la lección Servidor en TypeScript. A 8 de octubre de 2026, npm ya publica @modelcontextprotocol/server 2.3.1, del 5 de octubre.
¿Cómo aparecen los prompts en Claude Code, VS Code, Claude y Cursor?
Claude Code es el cliente mejor documentado. Al escribir / ves los comandos disponibles, y cada prompt de MCP aparece como /servername:promptname (MCP). También funciona si escribes la forma /mcp__servername__promptname, como en el ejemplo oficial /mcp__github__pr_review 456. Los argumentos van detrás, separados por espacios, y Claude Code los divide por los espacios. De esa frase deducimos que un argumento con espacios no se puede pasar como un solo valor por esta vía. El resultado del prompt se inyecta directamente en la conversación. Su documentación no dice que use completion/complete para los argumentos.
VS Code tiene dos páginas oficiales que no coinciden. La guía de usuario dice que escribas /<MCP server>.<prompt> en el chat. La guía de desarrolladores habla de un comando con la forma mcp.servername.promptname. No hemos podido comprobar cuál es la vigente sin ejecutar VS Code. Lo que sí documenta es que, si defines completions, VS Code muestra un diálogo para recoger los argumentos. Si el prompt devuelve un resource, lo adjunta como contexto del chat.
Claude, en la web y en Desktop, aparece en la guía de modelcontextprotocol.io para conectar servidores remotos. Según esa guía, los prompts y resources del servidor salen en el menú de adjuntos, al que se llega desde el indicador «Add files, connectors, and more /». Lo dice esa guía, no la documentación de Anthropic, y los menús de Claude cambian a menudo.
Cursor declara en su tabla de soporte «Prompts: Supported», pero su página no explica cómo los muestra.
¿Cuándo usar un prompt en lugar de una tool, un resource o una skill?
El criterio oficial es el de quién controla cada pieza. Si el modelo debe decidir cuándo usarla, es una tool. Si es un dato o una referencia, es un resource. Si el usuario la lanza a mano, es un prompt. Un prompt no ejecuta nada, solo devuelve mensajes, aunque puede llevar resources dentro.
Las skills no tienen una comparación oficial con los prompts. Las diferencias salen de las fuentes. En Claude Code, Claude usa una skill cuando le parece relevante o cuando tú la invocas con /, mientras que un prompt de MCP solo lo lanzas tú. Además, la skill es una carpeta local (personal, del proyecto o de un plugin), y el prompt es una plantilla que gobierna el servidor. Como prompts/get no se cachea, cuando el servidor cambia la plantilla, todos sus clientes reciben la versión nueva en la siguiente invocación. La extensión que sirve skills por MCP la explicamos en Skills sobre MCP.
Nuestra regla práctica, que es deducción propia y no texto oficial, es esta. Una acción atómica va en una tool, un dato en un resource y una plantilla que el usuario lanza a mano en un prompt. Un procedimiento de varios pasos que combina tools y referencias va en una skill. El reparto completo, con un caso real, está en tools, resources y skills en MCP.
¿Qué cambió desde la versión de 2025 de este artículo?
La versión anterior se publicó el 15 de octubre de 2025. La hemos contrastado con 2026-07-28 y, cuando el veredicto cambia, también con 2025-06-18. Estos son sus errores principales:
- El código usaba la API v1 del SDK (
ServerysetRequestHandler). Para 2026-07-28 el SDK es@modelcontextprotocol/server2.x, conregisterPrompt. - Devolvía las sugerencias de autocompletado como objetos
{ value, label }. Son cadenas, tanto en 2026-07-28 como en 2025-06-18. - Hablaba de «argumentos tipados» y de «tipado fuerte». Los argumentos son texto, y el autocompletado sugiere valores pero no los valida.
- Presentaba las plantillas de resources como parte de un prompt. Las plantillas son de Resources, y un prompt puede embeber o enlazar un resource concreto, no una plantilla.
- Embebía resources sin
mimeTypey con una instrucción en lugar del contenido. ElmimeTypeya era obligatorio en 2025-06-18. - Atendía
completion/completesin declarar la capacidadcompletions. - Le faltaban el
_metade cada petición,resultTypey las pistas de caché, que 2026-07-28 hace obligatorios.
Además, describía un flujo de comandos y preguntas una a una que ninguna fuente oficial describe así, igual que el método server.handleRequest con el que proponía probar el servidor. El SDK v2 documenta las pruebas con un Client en memoria. Sus tres enlaces de «Recursos» estaban rotos: uno no conectaba y los otros dos respondían 404.
¿Por dónde sigo?
La lección de prompts del curso recorre todo esto con Nortia Logística y con código en TypeScript y Python. La hemos revisado contra la especificación y coincide en todo lo que comprobamos.
En el blog tienes el contexto:
- el reparto entre las primitivas, en tools, resources y skills en MCP
- los cambios del protocolo sin estado, en MCP 2026-07-28
- un servidor completo, en crear un servidor MCP en TypeScript
- los términos, en el glosario de MCP.
Aprende esto en el curso
- Básico Gratis Prompts · Plantillas gobernadas en el servidor que invoca el usuario
- Básico Gratis Servidor en TypeScript · Construye nortia-pedidos con el SDK oficial v2
- Básico Gratis Recursos · Datos direccionables por URI, caché y suscripciones
La lección 1 la puedes leer ya, sin registro. Las otras 13 del Básico son gratis con una cuenta.
Empieza gratis Ir a la lecciónFuentes
- Especificación 2026-07-28: Prompts (2026-10-08)
- Especificación 2026-07-28: Completion (2026-10-08)
- Especificación 2026-07-28: Caching (2026-10-08)
- Especificación 2026-07-28: Subscriptions (2026-10-08)
- Schema 2026-07-28 (schema.ts) (2026-10-08)
- MCP: Understanding MCP servers (server concepts) (2026-10-08)
- SDK de TypeScript v2: Prompts (2026-10-08)
- SDK de TypeScript v2: Completion (2026-10-08)
- Claude Code: Use MCP prompts as commands (2026-10-08)
- VS Code: Use MCP servers (2026-10-08)
- VS Code: MCP developer guide (2026-10-08)
- MCP: Connect to remote MCP servers (2026-10-08)
- Cursor Docs: Model Context Protocol (MCP) (2026-10-08)