Saltar ao contido
26/30Capítulo 26 de 30

MCP explicado fronte á especificación: que é realmente un servidor

Unha liña de JSON a un subprocesso e volven trece definicións de ferramentas, lida contra a revisión 2026-07-28.

Nesta páxina

Instala un servidor MCP publicado, envíalle unha liña de JSON e le o que devolve.

terminalBASH
npm i @modelcontextprotocol/server-everything@2026.8.31
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"result":{"tools":[{"name":"echo","title":"Echo Tool","description":"Echoes
back the input string","inputSchema":{"$schema":"http://json-schema.org/draft-07/
schema#","type":"object","properties":{"message":{"type":"string","description":
"Message to echo"}},"required":["message"]},"annotations":{"readOnlyHint":true,
…                                        … 7,663 bytes on one line …
"jsonrpc":"2.0","id":1}

Trece definicións de ferramentas, nunha soa liña, desde un proceso que leu unha liña da súa entrada estándar. Acabas de falar o Model Context Protocol, sen SDK, sen biblioteca cliente e sen framework. Iso é todo: un transporte, un formato de mensaxe e un pequeno conxunto de métodos con nome.

O capítulo 18 definiu unha ferramenta como dúas cousas: un JSON Schema que o modelo ve e un endpoint no teu código que o modelo nunca ve. O capítulo 23 construíu un harness que mantén un catálogo delas. Ningún dos dous respondeu á pregunta que decide se algo disto é reutilizable: quen escribe o schema, e como chega desde quen o escribiu ata o teu prompt? MCP é unha resposta a esa pregunta, e paga a pena lelo no orixinal, porque case todo o que se escribiu sobre el describe unha revisión que xa non existe.

Tres cousas sobre o comando que acabas de executar están mal, e cada unha delas é unha sección deste capítulo. Non levaba versión de protocolo, así que un servidor conforme teríao rexeitado. Obtivo unha resposta igualmente, por unha razón que a especificación chama perigo en vez de funcionalidade. E pediu unha das tres primitivas sen descubrir nunca que as outras dúas existen.

O problema que resolve, e a analoxía que fai a propia especificación

Ligazón á sección: O problema que resolve, e a analoxía que fai a propia especificación

Antes do fío, a aritmética. Tes NN aplicacións de IA e MM cousas ás que deberían poder chegar: un calendario, un xestor de tickets, unha base de datos de almacén, unha ferramenta de deseño. Sen un contrato compartido, alguén escribe N×MN \times M integracións, e cada unha delas é un schema máis un endpoint máis unha historia de autenticación máis unha carga de mantemento. Con un, o provedor da ferramenta escribe un servidor, o provedor da aplicación escribe un cliente, e o total é N+MN + M.

Non é unha observación nova, e a especificación di de quen foi a idea:

MCP takes some inspiration from the Language Server Protocol, which standardizes how to add support for programming languages across a whole ecosystem of development tools. In a similar way, MCP standardizes how to integrate additional context and tools into the ecosystem of AI applications.1

Toma esa comparación literalmente, non como un eloxio. Antes dese protocolo, dar soporte a unha linguaxe nun editor significaba un plugin por editor; despois, un equipo de linguaxe distribuía un servidor e todos os editores o obtiñan. A medida do éxito non era a elegancia, era que a conta de integracións deixaba de multiplicarse. Aquí pasa o mesmo: o valor está no número de implementacións, non no deseño. Un protocolo que falan dous produtos é un formato de datos con cerimonia extra.

As mensaxes MCP son JSON-RPC 2.0. Unha petición é un obxecto con jsonrpc, un id, un method e params opcional; unha resposta leva o mesmo id e ou ben result ou ben error; unha notificación é unha petición sen id e non recibe resposta. A especificación engade tres restricións por riba: o id debe ser unha cadea ou un número e non debe ser null, non debe colidir con outra petición aínda en curso, e cada resultado debe levar un campo resultType.2

No transporte stdio —o que usou o comando anterior— a regra de framing é unha liña por mensaxe:

Messages are delimited by newlines, and MUST NOT contain embedded newlines. […] The server MUST NOT write anything to its stdout that is not a valid MCP message.3

Esa última cláusula é a forma máis común na que rompe un servidor feito na casa, e rompe en silencio: un console.log perdido, unha barra de progreso, un aviso de deprecación dunha dependencia, e o parser de liñas do cliente bate con algo que non é JSON. A vía de escape está na mesma sección: o servidor pode escribir o que queira en stderr, e o cliente non debería tratalo como un erro. O servidor de referencia anterior imprime Starting default (STDIO) server... en cada arranque, en stderr, por iso a tubaxe seguiu funcionando.

O outro transporte estándar é Streamable HTTP: cada mensaxe é un POST a un único endpoint, e a resposta é ou ben un obxecto JSON ou ben un fluxo de Server-Sent Events limitado á petición: o formato de fío que o capítulo 14 parseou á man. A semántica é idéntica nos dous, porque un transporte é un binding: define framing e entrega, non significado.4

A primeira cousa que estaba mal: non había versión

Ligazón á sección: A primeira cousa que estaba mal: non había versión

O comando anterior enviou tools/list e nada máis. Segundo a revisión actual, esa petición está mal formada, e un servidor conforme debe rexeitala.

Desde o 2026-07-28, MCP é un protocolo sen estado, e a especificación dilo sen matices:

The Model Context Protocol (MCP) is a stateless protocol: all the information needed to process a request is contained in the request itself. A server processes each request independently; no state should be inferred from previous requests, even those on the same connection or stream.2

Así que cada petición leva a súa propia versión de protocolo e as súas propias capacidades de cliente, nun obxecto reservado _meta dentro de params. Dous deses campos son obrigatorios en absolutamente cada petición; unha petición á que lle falte calquera deles está mal formada e o servidor debe responder -32602:2

clave _metaobrigatoriaque é
io.modelcontextprotocol/protocolVersionsia revisión que fala esta petición, p. ex. "2026-07-28"
io.modelcontextprotocol/clientCapabilitiessio que o cliente pode facer polo servidor nesta petición
io.modelcontextprotocol/clientInfonon (pero debería)nome e versión do cliente, só para visualización e logs
io.modelcontextprotocol/logLevelnono nivel mínimo de log que o servidor debería emitir para esta petición

Escrito completo, un tools/list correcto é isto —e é a última vez que este capítulo mostra os metadatos enteiros, porque desde aquí van en cada petición:

one line, split for the pageTEXT
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{"elicitation":{"form":{}}},
  "io.modelcontextprotocol/clientInfo":{"name":"bare-hands","version":"0.0.1"}}}}

O obxecto de capacidades é a negociación. Xa non hai un paso de negociación separado: o cliente declara o que pode facer en cada petición, o servidor declara o que pode facer no resultado, e ningún dos lados pode usar unha función que o outro non reivindicou. Un servidor que necesita unha capacidade que o cliente non declarou debe responder -32021 e nomear a capacidade que falta en data.requiredCapabilities. Un servidor que non fala a versión solicitada debe responder -32022 e listar as versións que si fala.2

Os clientes que queiran a resposta por adiantado poden pedila: server/discover é unha RPC obrigatoria que devolve versións soportadas, capacidades, identidade e un bloque opcional de instructions nunha soa ida e volta.5 Chamala é opcional. Implementala non.

A segunda cousa que estaba mal: o servidor era legacy

Ligazón á sección: A segunda cousa que estaba mal: o servidor era legacy

O comando funcionou. Segundo a revisión actual non debería telo feito, e paga a pena medir a razón máis ca explicala nun parágrafo, porque é o estado de todo o ecosistema nunha liña.

Proba o servidor de referencia como a especificación lle di a un cliente moderno que probe:

terminalBASH
echo '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{}}}}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found"}}

Esa é a terceira rama da regra de compatibilidade: un DiscoverResult significa moderno, un erro moderno recoñecido significa moderno-pero-versión-incorrecta, e calquera outra cousa —incluído -32601— significa legacy, volve ao handshake initialize.3 Así que fai iso, pedindo a revisión actual:

TEXT
→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28",
   "capabilities":{},"clientInfo":{"name":"bare-hands","version":"0.0.1"}}}

← {"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true},
   "prompts":{"listChanged":true},"resources":{"subscribe":true,"listChanged":true},
   "logging":{},"tasks":{…},"completions":{}},"serverInfo":{"name":"mcp-servers/everything",
   "title":"Everything Reference Server","version":"2.0.0"},"instructions":"…"}}

O cliente pediu 2026-07-28 e o servidor respondeu 2025-11-25. O 7 de setembro de 2026, o servidor oficial de referencia —paquete npm @modelcontextprotocol/server-everything, versión 2026.8.31, publicado o 31 de agosto de 2026— non implementa a revisión actual. Tampouco, polas datas, o fai o SDK TypeScript sobre o que está construído: a release 1.30.0 saíu o 27 de xullo de 2026, o día anterior á revisión.

Le a consecuencia, non o cotilleo. Case todo o que se escribiu sobre MCP describe un protocolo cun handshake initialize, unha sesión, unha petición roots/list que o servidor envía ao cliente e un transporte HTTP+SSE. As catro cousas desapareceron ou están desaparecendo. Cando leas calquera cousa sobre MCP, incluída esta páxina, o primeiro que debes buscar é un número de revisión.

E a razón pola que o primeiro comando funcionou aparece na especificación como un perigo, non como unha funcionalidade:

some legacy servers do not validate that a request arrives after initialize and would process an era-ambiguous method (such as tools/call) under legacy semantics. Probing yields a deterministic failure instead.3

Medido: enviar tools/list a ese servidor sen ningún handshake devolve o catálogo completo. Un método que debería ser rexeitado foi servido, que é exactamente por que a especificación di que probes con server/discover primeiro mesmo cando só soportas versións modernas.

Tres roles, e a frase que citar de todo o documento

Ligazón á sección: Tres roles, e a frase que citar de todo o documento

MCP ten tres partes, e a distinción entre as dúas primeiras é a que a xente adoita comprimir:

Host. A aplicación: o produto de chat, o editor, o agent. É quen posúe a conversa, o modelo, as credenciais e o consentimento do usuario. Crea clientes e aplica a fronteira de seguridade entre eles.

Cliente. Un conector dentro do host. Cada cliente fala con exactamente un servidor —unha relación estrita 1:1— e engade a versión do protocolo e as capacidades a cada petición que enruta.

Servidor. Un proceso ou un servizo que expón recursos, ferramentas e prompts. Pode ser local ou remoto, opera de maneira independente, e todo o seu traballo é unha área enfocada.6

Esa regra de "exactamente un servidor" non é burocracia. É o que fai implementable o principio de deseño de abaixo, e esta é a frase que debes levar da especificación se só levas unha:

Servers should not be able to read the whole conversation, nor "see into" other servers. Servers receive only necessary contextual information. Full conversation history stays with the host. Each server maintains isolation. Cross-server interactions are controlled by the host.6

Iso derruba o modelo mental co que chega a maioría da xente. Un servidor do tempo que conectas ao teu asistente non ve o que preguntaches. Ve un tools/call cos argumentos que escolleu o modelo, e nada máis: nin as quendas anteriores, nin o teu system prompt, nin os resultados que devolveu hai un intre o servidor de calendario. Se dous servidores teñen que cooperar, o host leva un valor dun ao outro, deliberadamente, porque o modelo o pediu. Por iso o illamento é a propiedade de seguridade na que se apoia o capítulo 30: un servidor comprometido ten un radio de explosión pequeno e definido, e amplialo require que o host coopere.

A terceira cousa: tres primitivas, ordenadas por quen manda

Ligazón á sección: A terceira cousa: tres primitivas, ordenadas por quen manda

O primeiro comando pediulle ferramentas a ese servidor e recibiu trece. Failles as outras dúas preguntas e tamén as responde: resources/list devolve sete, prompts/list devolve catro. Ningunha delas apareceu, porque nada preguntou. Isto lévanos á columna vertebral pedagóxica de MCP, situada na especificación como unha táboa que case ninguén cita:

PrimitivaControlDescriciónExemplo
PromptsControlado polo usuarioTemplates interactivas invocadas por elección do usuarioComandos slash, opcións de menú
RecursosControlado pola aplicaciónDatos contextuais anexados e xestionados polo clienteContidos de ficheiros, historial git
FerramentasControlado polo modeloFuncións expostas ao LLM para realizar acciónsPeticións API POST, escritura de ficheiros

Non "tres formas de expoñer unha capacidade". Tres respostas a quen decide que isto acontece. O modelo decide chamar unha ferramenta. A aplicación decide anexar un recurso. A persoa decide executar un prompt. Se o entendes mal, a funcionalidade segue funcionando, pero funciona no momento equivocado e polo motivo equivocado.

A forma máis clara de notalo é un calendario. Aquí tes un servidor que expón o mesmo calendario tres veces, unha como cada primitiva, en cen liñas de Node puro sen dependencias:

calendar.mjs — the parts that matterJS
const TOOL = {
  name: "create_event",
  description: "Create a calendar event. Writes to the calendar.",
  inputSchema: {
    type: "object",
    properties: {
      title:    { type: "string", description: "Event title." },
      startsAt: { type: "string", format: "date-time", description: "Start, ISO 8601 UTC." },
    },
    required: ["title"],
  },
};

switch (method) {
  case "resources/read":                                          
    return ok(id, { contents: [{ uri: "calendar://week",
      mimeType: "application/json", text: JSON.stringify(EVENTS) }],
      ttlMs: 60000, cacheScope: "private" });

  case "prompts/get":                                             
    return ok(id, { description: PROMPT.description, messages: [{ role: "user",
      content: { type: "text", text: `Read calendar://week and draft a plan. ` +
        `Focus: ${params.arguments?.focus ?? "balance"}.` } }] });

  case "tools/list":                                              
    return ok(id, { tools: [TOOL], ttlMs: 300000, cacheScope: "public" });
}

Execútao e pregúntalle das tres maneiras. Saída real, unha mensaxe por liña no fío, envolta aquí para a páxina, coa petición _meta e o bloque de identidade do servidor omitidos:

TEXT
→ resources/read  {"uri":"calendar://week"}
← {"resultType":"complete","contents":[{"uri":"calendar://week",
   "mimeType":"application/json","text":"[{\"id\":\"e1\",\"title\":\"Standup\",
   \"startsAt\":\"2026-09-07T09:00:00Z\"},{\"id\":\"e2\",\"title\":\"Design review\",
   \"startsAt\":\"2026-09-09T15:00:00Z\"}]"}],"ttlMs":60000,"cacheScope":"private"}

→ prompts/get    {"name":"prepare_week","arguments":{"focus":"deep work"}}
← {"resultType":"complete","description":"Read the week and draft a plan.",
   "messages":[{"role":"user","content":{"type":"text",
   "text":"Read calendar://week and draft a plan. Focus: deep work."}}]}

→ tools/call     {"name":"create_event","arguments":{"title":"Dentist",
                  "startsAt":"2026-09-10T08:30:00Z"}}
← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],
   "structuredContent":{"id":"e3","title":"Dentist","startsAt":"2026-09-10T08:30:00Z"},
   "isError":false}

Tres métodos, tres formas, un calendario. Agora o punto:

Está dirixido por unha URI, é inerte, e a aplicación decide se o anexa á conversa. Nada no protocolo deixa que o modelo vaia buscalo pola súa conta. O resultado leva ttlMs e cacheScope, novos nesta revisión, para que o cliente poida cachear a semana durante un minuto en vez de facer polling.

Ten un schema, ten efectos secundarios, e o modelo decide cando chamala. O seu resultado leva isError, que é o campo polo que argumentaba o capítulo 18: unha validación fallida volve como resultado da ferramenta que o modelo pode ler e corrixir, non como erro de protocolo.

É unha template con nome e argumentos que a persoa invoca: o comando slash no menú. Devolve mensaxes, non unha resposta. É unha maneira de que o autor dun servidor distribúa a formulación que funciona coas súas propias ferramentas, que é exactamente o coñecemento que ten o autor do servidor e non ten o usuario.

Case todo o mundo converte estas tres cousas en ferramentas. O resultado é un catálogo no que unha lectura que a aplicación debería anexar en silencio compite pola attention do modelo cunha escritura que precisa aprobación, e no que o único para o que unha persoa quería un botón queda soterrado nun schema. Non custa nada facelo ben, e decídese antes de escribir unha liña.

A ferramenta de calendario ten un argumento obrigatorio, title, e un startsAt opcional. Pídelle que cree un evento sen data, e devolve algo interesante:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"}}

← {"resultType":"input_required",
   "inputRequests":{"when":{"method":"elicitation/create","params":{"mode":"form",
     "message":"When should \"Dentist\" start?",
     "requestedSchema":{"type":"object",
       "properties":{"startsAt":{"type":"string","format":"date-time"}},
       "required":["startsAt"]}}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

O servidor non enviou unha petición. Respondeu á que recibiu, con resultType: "input_required" e unha descrición do que aínda necesita. O cliente recolle a resposta da persoa, e logo reenvía a chamada orixinal, cun novo id, levando inputResponses e ecoando de volta o requestState opaco:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"},
   "inputResponses":{"when":{"action":"accept",
     "content":{"startsAt":"2026-09-10T08:30:00Z"}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],"isError":false}

Isto son Multi Round-Trip Requests, introducidas na revisión actual, e substituíron o deseño anterior no que os servidores enviaban peticións JSON-RPC de volta aos clientes. A especificación de transporte agora indica a regra sen rodeos: "servers do not initiate JSON-RPC requests and clients do not send JSON-RPC responses".4 Hai unha soa dirección de iniciativa, e pertence ao host.

Dúas funcionalidades do lado do cliente van montadas nese mecanismo, e unha delas ten un nome que che fará tropezar.

Elicitation é o servidor pedíndolle algo á persoa: un formulario cun JSON Schema deliberadamente restrinxido —obxectos planos, propiedades primitivas, sen aniñamento— para que calquera cliente poida renderizalo sen motor de layout. Leva unha regra dura: os servidores non deben usar o modo formulario para pedir "passwords, API keys, access tokens, or payment credentials", e deben usar o modo URL para iso, que envía o usuario a unha páxina que o cliente nunca le.7

Sampling é o servidor pedíndolle unha xeración ao modelo do host, para que un servidor poida ser intelixente sen gardar unha API key. E aquí vai o aviso de vocabulario, porque esta palabra xa significa outra cousa neste curso: isto non é o sampling do capítulo 17. Aquí nada vai de temperatura, top-p nin da forma dunha distribución de probabilidade. É unha chamada de modelo aniñada que viaxa cara atrás a través dun protocolo.

Hai unha segunda razón para non usalo de primeiras: nesta revisión, sampling está deprecated, xunto con roots e logging, baixo SEP-2577, cunha migración suxerida moi clara: "integrate directly with LLM provider APIs instead of Sampling".8 A idea non fallou tecnicamente; non xustificou a súa superficie, e un protocolo que pode quitar cousas é máis san ca un que non pode.

Rómpeo a propósito: as conexións non son sesións

Ligazón á sección: Rómpeo a propósito: as conexións non son sesións

A ausencia de estado soa a detalle de formato de fío ata que a probas. Colle o intercambio de tres mensaxes de arriba e executa cada mensaxe nun proceso separado: un node calendar.mjs novo, sen memoria compartida, sen arrastrar nada:

TEXT
process A   tools/call (no date)   → resultType: input_required
                                     requestState: eyJ0aXRsZSI6IkRlbnRpc3QifQ==
process B   tools/call (with the answer, same requestState)
                                   → resultType: complete
                                     "Created e3: Dentist at 2026-09-10T08:30:00Z"
process C   resources/read calendar://week
                                   → events: 2  (Standup, Design review)

O proceso B, que nunca viu a pregunta, completou unha chamada multi-round-trip que iniciou o proceso A. Ese é o propósito de requestState: a continuación viaxa na mensaxe, así que nada depende de que o proceso sexa o mesmo.

O proceso C é o fallo. O evento foi creado e non está aí, porque o servidor de xoguete garda EVENTS nun array a nivel de módulo, e un array a nivel de módulo é estado de conexión. A nota da especificación nomea o erro con precisión:

an open connection, such as a STDIO process, is not a conversation or session: clients may interleave unrelated requests on the same transport, and a server must not treat connection or process identity as a proxy for conversation or session continuity.2

A corrección prescrita non é unha sesión. É un handle explícito: unha ferramenta de creación devolve un identificador opaco, e cada chamada posterior tómao como un argumento ordinario. O protocolo non ten ningún concepto del: "from the wire's perspective a handle is an ordinary string in a tool result and an ordinary argument to subsequent tool calls".9 Iso pon o modelo a cargo de transportalo, e pon o servidor a cargo de validar que este chamador ten permiso para usalo en cada chamada, porque un handle é un nome e non un permiso.

Cada ferramenta que expón un servidor é un schema que entra no teu prompt en cada petición, e o capítulo 24 mediu o que iso lle fai a unha window. MCP engade unha segunda partida fácil de pasar por alto, así que paga a pena contar as dúas no servidor de referencia de arriba.

o200k_base tokensTEXT
13 tool definitions (name + description + inputSchema):  1,307 tokens
  cheapest tool, get-tiny-image                              52
  costliest tool, gzip-file-as-resource                     235
server `instructions`, returned by discovery:               312 tokens
                                                          ------
one server, connected, before it is used:                 1,619 tokens

Dúas observacións. A primeira é aritmética: conecta cinco servidores deste tamaño e aproximadamente oito mil tokens da túa window quedan ocupados en cada quenda, para sempre, use ou non o modelo algún deles; este é o mecanismo detrás da redución de 150.000 a 2.000 que citou o capítulo 24, e a razón pola que existe o descubrimento de ferramentas just-in-time.

A segunda é unha nota de seguridade disfrazada de contabilidade. instructions é texto en linguaxe natural, escrito polo autor do servidor, que aterra no prompt do host, e as descricións das ferramentas ao lado son o mesmo. A especificación di que facer con iso nos seus propios principios de seguridade: as anotacións e descricións de ferramentas "should be considered untrusted, unless obtained from a trusted server", e os hosts "must obtain explicit user consent before invoking any tool".1 Conectar un servidor MCP non é engadir unha dependencia. É concederlle a un estraño 1.619 tokens do teu system prompt e o dereito a ser chamado. O capítulo 30 é o que pasa cando ese estraño é hostil.

Sección datada: a revisión 2026-07-28, e o que rompe

Ligazón á sección: Sección datada: a revisión 2026-07-28, e o que rompe

Todo nesta sección é certo para a revisión do protocolo 2026-07-28, a actual, lida o 7 de setembro de 2026. As revisións dátanse como YYYY-MM-DD e a data é a última vez que se fixo un cambio incompatible cara atrás.10 O documento normativo é un ficheiro TypeScript, schema/2026-07-28/schema.ts; o JSON Schema que hai ao lado xérase a partir del, por iso aquí a especificación se le en TypeScript e por iso ensinar MCP desde calquera outra cousa é ensinar unha tradución.

Que cambiouEraÉ agoraRompe
O handshakeinitialize + notifications/initialized, unha vez por conexióneliminado; cada petición leva versión e capacidades _metatodos os clientes escritos antes desta revisión
Sesiónscabeceira Mcp-Session-Id, estado limitado á conexióneliminadas; o estado viaxa en handles explícitos xerados polo servidorendpoints de lista que variaban por conexión
Descubrimentoinferido do resultado initializeserver/discover, que os servidores deben implementarnada, pero agora é obrigatorio implementalo
Chamadas de servidor a clienteo servidor enviaba roots/list, sampling/createMessage, elicitation/createInputRequiredResult e un reintento do clientetodos os servidores que empurraban unha petición a un cliente
Forma do resultadocalquera obxectoresultType obrigatorio: "complete" ou "input_required"nada: un campo ausente debe lerse como "complete"
Subscriciónsfluxo HTTP GET, resources/subscribeun fluxo subscriptions/listen con tipos opt-ino endpoint GET desaparece
Reanudación de fluxoreplay Last-Event-ID en Streamable HTTPeliminado; un fluxo roto perde a petición, reemítea cun novo idclientes que dependían da reentrega
Rootsunha funcionalidade de cliente que os servidores podían pedirdeprecated (SEP-2577); pasa rutas como argumentos de ferramenta ou URIs de recursonada aínda: xanela de doce meses
Sampling e loggingfuncionalidades de clientedeprecated (SEP-2577)nada aínda: xanela de doce meses
Transporte HTTP+SSEdeprecated desde 2025-03-26Deprecated baixo a política de ciclo de vida (SEP-2596)migra a Streamable HTTP
Rexistro de clienteOAuth 2.0 Dynamic Client Registration, RFC 7591deprecated en favor de Client ID Metadata Documentsmantido para servidores de autorización sen eles
Códigos de erro-32002 para recurso non atopado-32602; -32020-32099 reservados para a especificaciónnovos códigos -32020, -32021, -32022

O cambio de gobernanza baixo esa táboa importa máis ca calquera fila concreta. Esta revisión adoptou unha política de ciclo de vida de funcionalidades e deprecación: as funcionalidades son Active, Deprecated ou Removed, unha funcionalidade deprecated documenta a súa ruta de migración e queda na especificación polo menos doce meses antes de ser elixible para a eliminación, e hai un rexistro que lista todo o que está actualmente no estado Deprecated.8 Antes desa política, "deprecated" nun protocolo de IA significaba o que dixese o último blog post. Agora significa unha data.

Mostrar detalles

Extensións, que son a parte sobre a que aínda non escribiu ninguén.

Máis alá do núcleo, MCP define extensións opcionais: "always opt-in and require explicit support from both client and server", declaradas mediante un campo extensions nas capacidades do cliente e do servidor.1 Tres paga a pena coñecelas polo nome:

  • Tasks (io.modelcontextprotocol/tasks), movida fóra do protocolo núcleo a unha extensión oficial nesta revisión: execución asíncrona de operacións longas, con polling mediante tasks/get, entrada en metade do voo mediante tasks/update e handles duradeiros. É a resposta a unha ferramenta que tarda vinte minutos, que o capítulo 23 resolveu cun evento de progreso e un sinal que chega á ferramenta.
  • Skills over MCP, un grupo de traballo que fai que as skills de agent —o tema do capítulo 28— sexan descubribles e consumibles a través do protocolo.
  • MCP Apps, UI interactiva renderizada inline na conversa: gráficas, formularios, reprodutores de vídeo.

E observa que significa agora "negociado": non hai inicialización na que negociar, así que unha extensión declárase por petición como todo o demais.

Onde encaixa MCP fronte a todo aquilo co que se confunde

Ligazón á sección: Onde encaixa MCP fronte a todo aquilo co que se confunde

Este é o vocabulario de todo o bloque nun só lugar.

Que éQuen fala con quenCando é a resposta
Unha API simpleUnha interface para un programao teu código ↔ un servizoEstás escribindo o chamador. Controlas o schema, a auth e a xestión de erros, e non hai un problema de descubrimento que resolver.
MCPUn protocolo para expoñer ferramentas, datos e templates a unha aplicación de IAhost ↔ servidor, un cliente por cada unOutra persoa escribiu a capacidade e moitos hosts deberían poder usala sen unha integración a medida.
RAGUnha técnica para atopar texto e poñelo no prompto teu código ↔ o teu índiceO modelo necesita saber algo. Capítulo 19. MCP é unha maneira de entregar un retriever; non é un retriever.
Agent skillsUn cartafol cun SKILL.md que o modelo lemodelo ↔ un documentoO coñecemento é procedemental —como o facemos nós— e é prosa, non unha función. Capítulo 28.
A2AUn protocolo para que agents colaboren como paresagent ↔ agentO outro lado razoa, planifica e mantén estado ao longo dunha tarefa longa, en vez de responder unha chamada.
ACPEra un protocolo separado de comunicación entre agentsXa non é unha comparación viva. Mira abaixo.

Dous deles merecen unha frase cada un, porque aí é onde vive realmente a confusión.

MCP fronte a A2A non é unha rivalidade, e as dúas especificacións o din. A documentación de A2A traza a liña polo que hai no outro extremo: MCP "defines how an AI agent interacts with and utilizes individual tools and resources, such as a database or an API", onde unha ferramenta realiza "specific, often stateless, functions"; A2A trata con agents, "more autonomous systems" que "reason, plan, use multiple tools, maintain state over longer interactions, and engage in complex, often multi-turn dialogues". O seu propio resumo é a frase que cómpre lembrar: "A2A is about agents partnering on tasks, while MCP is more about agents using capabilities."11 Os dous aniñan: unha aplicación usa A2A para chegar a outros agents, e cada agent usa MCP para chegar ás súas propias ferramentas. O capítulo 25 trazou esa liña dentro dun proceso, entre preguntarlle a un sub-agent e pasarlle a conversa; A2A trázaa entre organizacións.

MCP fronte a ACP é unha comparación cunha premisa caducada, que é exactamente por iso que paga a pena respondela. O Agent Communication Protocol era un estándar aberto separado para mensaxería agent-to-agent. A súa propia documentación agora abre co aviso: "ACP is now part of A2A under the Linux Foundation!"12 A resposta honesta a "MCP ou ACP?" en setembro de 2026 é que a pregunta ten unha opción menos do que suxiren as páxinas que posicionan por ela.

E a comparación que máis pide a xente, mcp vs api, ten a resposta menos interesante: MCP é unha API. O que engade non é potencia, son convencións: un conxunto fixo de nomes de métodos, unha chamada de descubrimento, unha xerarquía de control sobre as primitivas e un modelo de illamento. Renuncias á liberdade de deseñar a túa propia interface e recibes todos os hosts que falan o protocolo, que é o intercambio que todo protocolo ofreceu sempre.

Agora podes ler a especificación sen tradutor, distinguir un recurso dunha ferramenta e dun prompt por quen está a cargo del, escribir unha petición á man cando unha biblioteca cliente che mente, e poñerlle data a calquera artigo sobre MCP que leas mirando cales das funcionalidades deprecated segue ensinando como actuais.

O que aínda non fixeches é publicar un. O capítulo 27 escribe o mesmo servidor dúas veces —TypeScript e Python, lado a lado, porque MCP é o único territorio realmente bilingüe deste curso e os números din o mesmo nas dúas direccións. Cobre correctamente os dous transportes vivos, o inspector, o empaquetado e a metade do protocolo que este capítulo deixou deliberadamente a un lado: autorización. Porque no momento en que o teu servidor é remoto en vez dun subprocesso no teu propio portátil, o cliente dun estraño presentará un token, e a regra da especificación sobre o que podes facer con el é inusualmente estrita.

Isto suscita a pregunta que debe responder o seguinte capítulo, e non é amable: se un token chega ao teu servidor e foi emitido para a audience doutra persoa, que impide exactamente que o reenvíes?


Cada cita, nome de método, código de erro e regra deste capítulo leuse na especificación do Model Context Protocol, revisión 2026-07-28, o 7 de setembro de 2026. Cada traza produciuse localmente en Node 22: o servidor de calendario de xoguete ten 101 liñas sen dependencias, e o servidor de referencia é o paquete npm publicado que se nomea abaixo. Non se chamou ningunha API de pago para escribir este capítulo: nada aquí necesita un modelo, que é en si mesmo o punto.

As medicións: @modelcontextprotocol/server-everything@2026.8.31, publicado o 31 de agosto de 2026, construído sobre @modelcontextprotocol/sdk@1.30.0, publicado o 27 de xullo de 2026, un día antes da revisión que describe este capítulo. Responde server/discover con -32601, negocia 2025-11-25 cando se lle pide 2026-07-28, e serve tools/list sen ningún handshake. O seu catálogo son 13 ferramentas en 7.663 bytes; as contas de tokens son o200k_base vía tiktoken, sobre o name, description e inputSchema de cada definición, que é o que un provedor renderiza no teu prompt e non o que pesa o frame JSON-RPC.

Anthropic, Code execution with MCP: building more efficient agents, 4 de novembro de 2025, é a fonte da cifra de 150.000 a 2.000, citada e usada no capítulo 24 e só referenciada aquí.

  1. Specification, modelcontextprotocol.io/specification/latest (redirixindo a /2026-07-28), lida o 7 de setembro de 2026. Fonte da comparación co Language Server Protocol; da afirmación de que a especificación está "based on the TypeScript schema in schema.ts"; do resumo do protocolo base ("Stateless, self-contained requests", "Per-request capability negotiation"); da lista de extensións (Tasks, Skills over MCP, MCP Apps) e da afirmación de que as extensións "are always opt-in and require explicit support from both client and server"; e dos principios de Security and Trust & Safety, incluído "Hosts must obtain explicit user consent before invoking any tool" e o tratamento das anotacións de ferramentas como non fiables. 2 3

  2. Base Protocol, modelcontextprotocol.io/specification/2026-07-28/basic. Fonte das restricións JSON-RPC (id non null, non reutilizar id, resultType obrigatorio); da sección Statelessness e da súa nota de que un proceso stdio aberto non é unha sesión; da táboa de claves reservadas _meta e do estado obrigatorio/opcional de cada campo por petición; da regra -32602 para un campo obrigatorio ausente; da regra MissingRequiredClientCapability (-32021); e da política de asignación de códigos de erro. 2 3 4 5

  3. stdio transport, modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio. Fonte das regras de framing delimitado por saltos de liña, do requisito de pureza de stdout, da concesión de stderr e da proba de compatibilidade cara atrás con tres resultados, incluído o aviso de que algúns servidores legacy procesan métodos ambiguos de era sen handshake, que reproduce a medición deste capítulo. 2 3

  4. Transports overview, modelcontextprotocol.io/specification/2026-07-28/basic/transports. Fonte do framing de "a transport is a binding" e da afirmación de que os servidores non inician peticións JSON-RPC e os clientes non envían respostas JSON-RPC. 2

  5. Discovery, modelcontextprotocol.io/specification/2026-07-28/server/discover. Fonte do carácter obrigatorio de server/discover, da forma de DiscoverResult e do campo instructions descrito como "optional natural-language guidance for LLMs on how to use this server effectively".

  6. Architecture, modelcontextprotocol.io/specification/2026-07-28/architecture. Fonte das definicións de host/client/server, da regra 1:1 de cliente a servidor, dos catro principios de deseño, dos que aquí se cita o principio de illamento sen a súa quinta viñeta, "Host process enforces security boundaries", e da sección de negociación de capacidades. 2

  7. Elicitation, .../client/elicitation, e Sampling, .../client/sampling. Fonte dos dous modos de elicitation e do seu schema restrinxido; da prohibición de pedir credenciais mediante modo formulario; da definición de sampling, do seu requisito human-in-the-loop e do aviso de deprecación asociado.

  8. Key Changes, modelcontextprotocol.io/specification/2026-07-28/changelog, e Feature lifecycle and deprecation policy, .../community/feature-lifecycle. Fonte de cada fila da táboa de cambios: eliminación de sesións e da cabeceira Mcp-Session-Id (SEP-2567); ausencia de estado e eliminación de initialize (SEP-2575); server/discover (SEP-2575); subscriptions/listen (SEP-2575); Multi Round-Trip Requests e resultType (SEP-2322); eliminación da reanudabilidade de fluxo (SEP-2575); deprecación de Roots, Sampling e Logging (SEP-2577); reclasificación de HTTP+SSE (SEP-2596); deprecación de Dynamic Client Registration en favor de Client ID Metadata Documents; renumeración de códigos de erro; e a xanela de deprecación de doce meses. 2

  9. Tools, modelcontextprotocol.io/specification/2026-07-28/server/tools, e Server Features, .../server. Fonte da táboa de xerarquía de control reproducida arriba; das formas tools/list e tools/call; da distinción isError entre erros de protocolo e erros de execución de ferramenta; das regras de nomes de ferramentas e da nota de namespace que recomenda "prefixing tool names with a server identifier"; e da guía non normativa "Stateful Tools" sobre handles explícitos.

  10. Versioning, modelcontextprotocol.io/specification/versioning. Fonte do esquema YYYY-MM-DD, dos estados de revisión Draft/Current/Final, da confirmación de que 2026-07-28 é actual e das regras de negociación por petición. A táboa de tiers de SDK en modelcontextprotocol.io/docs/sdk lista TypeScript, Python, C#, Go e Rust no Tier 1, Java e Ruby no Tier 2, e Swift, PHP e Kotlin no Tier 3.

  11. A2A Protocol, versión 1.0.0, a2a-protocol.org: a especificación e a páxina A2A and MCP: Relationship and Distinction, lidas o 7 de setembro de 2026. Fonte da distinción entre ferramentas e agents, da afirmación de que os dous protocolos "address distinct but highly complementary needs", e da formulación partnering/using.

  12. Agent Communication Protocol, agentcommunicationprotocol.dev, lido o 7 de setembro de 2026: "ACP is now part of A2A under the Linux Foundation!", un banner engadido por riba dunha especificación que segue servíndose enteira: arquitectura, manifesto de agent, descubrimento de agent, estrutura de mensaxe, agents con estado, ciclo de vida de run e lista de endpoints REST seguen respondendo 200. A especificación non desapareceu; desapareceu o proxecto.

Listo para deixar que LIA escolla por ti?

Crea con todos os modelos de IA nun só sitio: empeza gratis hoxe mesmo.