Tres publishes fallidos y una guía de publicar

Publicar un servidor MCP en el registro oficial parece una llamada a una API. No lo es: es un protocolo de tres pasos con dos trampas que no dan error de validación y un límite de bytes que te corta a mitad. Publicamos el nuestro (dev.theboomer/ai-tasker) el 21 de octubre de 2026, y este es el registro de los tres intentos que hicieron falta.

Revisado · Publicado

Por qué el registro oficial va primero

El registro oficial es el directorio canónico del protocolo: lo consultan los clientes MCP y los agregadores, y es la fuente de la que beben el resto de índices. Un servidor que está en el registro aparece después en otros directorios sin que nadie lo pida: la ficha de Glama de AI Tasker existe por esa vía, sin que nadie la enviara a mano. Por eso el orden de publicación no es caprichoso: registro oficial primero, directorios después.

La parte incómoda es que el registro no exige que publiques el código. La autenticación es por desafío DNS sobre tu dominio, así que un servidor MCP puede vivir en un repositorio privado y seguir siendo descubrible por cualquier cliente. Eso cambia la conversación con los directorios: no hace falta abrir el repositorio para que el servidor se pueda instalar.

El intento 1: 403 por un namespace mal entendido

El primer publish devolvió un 403 que no parecía un problema de permisos:

Respuesta del registro (403).

You do not have permission to publish this server.
You have permission to publish: dev.theboomer/*, dev.theboomer.*

El nombre de un servidor en el registro es reverse-DNS: el dominio al revés, como io.github.usuario/repo. Autenticar el dominio theboomer.dev concede el namespace dev.theboomer, no theboomer.dev. Lo que hacíamos era autenticar un dominio y publicar en otro: por eso el permiso era dev.theboomer/* y nosotros pedíamos theboomer.dev/ai-tasker.

La corrección no fue de permisos sino de nombre: el servidor pasó a llamarse dev.theboomer/ai-tasker, con el dominio del producto (ai-tasker.theboomer.dev) como websiteUrl y el dominio que se autentica como theboomer.dev. El endpoint y el código no cambian; cambia la etiqueta.

El intento 2: 400 por 4 KB de extension

Con el nombre corregido, el registro devolvió otro 400, este vez sobre la extension _meta que el publicador puede adjuntar al manifiesto:

Respuesta del registro (400).

_meta.io.modelcontextprotocol.registry/publisher-provided extension
exceeds 4KB limit (4835 bytes)

La extension _meta está limitada a 4 KB, y con la descripción de las 40 tools del servidor MCP el bloque iba a 4.835 bytes. La solución no fue recortar tools sino decidir qué va en el manifiesto y qué no: la extension lleva solo los nombres de las tools (2.004 bytes) y las descripciones se quedan en el catálogo legible por máquina (/llms-full.txt) y en la página de tools del sitio.

La lección: el manifiesto oficial es un índice, no un manual. Cuanto más grande sea la extension, menos veces se podrá republicar sin romper el límite, porque cualquier tool nueva añade bytes.

El intento 3: 200

Con el namespace correcto y la extension dentro del límite, el publish devolvió 200 y el servidor quedó publicado con su versión:

Publicación (200).

{"server":{"name":"dev.theboomer/ai-tasker","version":"1.1.8", ...}}

Dos trampas que no son errores de validación

Lo que más tiempo costó no fueron los errores: fueron las respuestas que parecían correctas y no lo eran.

  • El token viene en `registry_token`, no en `access_token`. Buscar access_token en la respuesta es el error más rápido de cometer y el que más confunde, porque el cuerpo dice 200 y trae un token que no es el que esperabas.
  • `GET /v0/servers?search=…` tarda más de 25 segundos y agota el timeout de cualquier cliente serio. Para verificar que la publicación existe, usa el endpoint de versión, que responde en menos de un segundo: /v0/servers/<nombre>%2F<servidor>/versions/<version>.
  • El JWT caduca a los 5 minutos. La autenticación por DNS y el publish tienen que ir en la misma ejecución: no se puede autenticar por la mañana y publicar por la tarde.

El desafío DNS, en detalle

La prueba de dominio tiene tres pasos y ninguno necesita una cuenta de terceros. Se genera un par de claves Ed25519; la clave privada vive fuera del repositorio (en un fichero con permisos 600) y la pública se publica como un registro TXT en el ápex del dominio:

Registro TXT en el ápex del dominio.

v=MCPv1; k=ed25519; p=<clave pública en base64 estándar>

Con el TXT propagado, se firma un timestamp RFC3339 con la clave privada y se envía al endpoint de autenticación, que devuelve un token de uso único:

Autenticación y publicación.

POST /v0/auth/dns
  {"domain":"theboomer.dev","timestamp":"...","signed_timestamp":"<hex>"}
  -> {"registry_token":"<JWT>","expires_at":...}

POST /v0/publish   Authorization: Bearer <JWT>

Rotar la clave es borrar el TXT y volver a publicar uno nuevo con el script: la firma antigua deja de valer. Retirar la entrada del registro es un DELETE sobre /v0/servers/<nombre> con el mismo token.

Lo que se lleva de aquí

  • El nombre del servidor es reverse-DNS del dominio que autenticas, no el que te apetece. Compruébalo antes de firmar nada.
  • La extension _meta del publicador tiene un límite de 4 KB: mete índices, no contenido.
  • Autentica y publica en la misma ejecución (el JWT dura 5 minutos).
  • Verifica contra el endpoint de versión, no contra el buscador: el buscador tarda más de 25 segundos.
  • El manifiesto se genera en runtime desde la versión y el catálogo reales, así que no puede desviarse de lo que hay desplegado.

Todo esto está automatizado en el repositorio del proyecto: el script de publicación hace el TXT, espera la propagación, firma, autentica, publica y verifica; y falla con código distinto de cero si el manifiesto no cumple el schema vigente, si la extension se pasa de 4 KB o si el registro rechaza la publicación. La parte que no se puede automatizar es el TXT: hay que publicarlo en el panel del dominio.

Publicar un servidor MCP en el registro oficial

Los cuatro pasos reales, con lo que hay que comprobar en cada uno y qué respuesta se obtiene.

  1. Genera el par de claves y el TXT

    El script crea una clave Ed25519 fuera del repositorio (modo 600) e imprime el registro TXT a publicar en el ápex del dominio: v=MCPv1; k=ed25519; p=<clave pública>. El DNS lo publica una persona: no hay API para eso.

  2. Espera la propagación y autentica

    Con el TXT visible, el script firma el timestamp RFC3339 con la clave privada y hace POST /v0/auth/dns. La respuesta trae registry_token (no access_token) y caduca a los 5 minutos.

  3. Publica el manifiesto

    POST /v0/publish con el JWT en Authorization. El manifiesto se valida contra el schema vigente del registro: si la extension _meta supera 4 KB, el registro responde 400 y no publica.

  4. Verifica contra el endpoint de versión

    GET /v0/servers/<nombre>%2F<servidor>/versions/<version> responde en menos de un segundo. No uses el buscador: GET /v0/servers?search=… tarda más de 25 segundos y agota el timeout.

Preguntas frecuentes

¿Hacen falta cuenta de GitHub o repositorio público para publicar en el registro?

No. La autenticación es por desafío DNS sobre el dominio: se publica un TXT con una clave pública y se firma un timestamp. El repositorio del servidor MCP puede seguir siendo privado. AI Tasker está publicado como dev.theboomer/ai-tasker con el código en un repositorio privado.

¿Qué límite tiene la extensión _meta del manifiesto?

4 KB. La extensión que añade el publicador no puede superar ese tamaño. Con las descripciones de las 40 tools llegaba a 4.835 bytes y el registro devolvía un 400; la solución fue incluir solo los nombres de las tools (2.004 bytes) y dejar las descripciones en el catálogo legible por máquina.

¿Por qué mi publicación devuelve 403 aunque el dominio esté autenticado?

Porque el nombre del servidor es reverse-DNS y debe coincidir con el namespace concedido. Autenticar theboomer.dev concede el namespace dev.theboomer, así que el servidor tiene que llamarse dev.theboomer/<nombre> y no theboomer.dev/<nombre>.

Fuentes

Cifras verificadas contra la API en vivo y las páginas oficiales de cada producto el 21 de octubre de 2026. Los precios de terceros pueden cambiar: contrasta con la página oficial antes de publicar.

Guías relacionadas

Esta guía existe para ser indexada y citada. No está en el menú a propósito.