Patrones de autenticación MCP: OAuth, tokens y cuándo usar cada uno

Patrones de autenticación MCP: OAuth, tokens y cuándo usar cada uno

Última verificación: 13 de octubre de 2026
14 min de lectura
Guía
500+ proyectos WP
Integración IA

#Patrones de autenticación MCP: OAuth, tokens y cuándo usar cada uno

MCP define un perfil de autorización OAuth para transportes HTTP. Los servidores públicos de solo lectura pueden ser anónimos. Las herramientas protegidas requieren autenticación, autorización e identidad verificada. Los tokens propios de socios también necesitan un contrato explícito de compatibilidad con el cliente MCP.

Este artículo forma parte del pilar sobre desarrollo de servidores MCP.

#TL;DR

  • La lectura de datos públicos con rate limiting es el único caso legítimo de acceso anónimo.
  • Los tokens de API con scopes, guardados con hash y con TTL corto, cubren B2B y headless.
  • OAuth 2.1 con PKCE cubre los asistentes de consumo que actúan en nombre de un usuario autenticado.
  • El rate limiting se asocia al principal; las herramientas que modifican estado reciben un bucket más estrecho.
  • Cada evento de autenticación se registra: emitido, usado, revocado, rechazado.

#Cómo elegir el método de autenticación MCP

Antes de elegir un patrón de autenticación, repaso siempre las mismas cinco preguntas:

  1. ¿Alguna herramienta modifica estado? Si es así, el acceso anónimo queda descartado.
  2. ¿El agente actúa en nombre de un usuario humano concreto? Si es así, OAuth.
  3. ¿El agente actúa como integración B2B sin usuario humano? Si es así, token de API con scopes.
  4. ¿La superficie de datos es accesible desde la Internet pública? Si es así, el rate limiting es obligatorio.
  5. ¿Se mezclan en un mismo servidor herramientas que modifican estado y herramientas de solo lectura? Si es así, scope de autenticación por herramienta, no por servidor.

El árbol se traduce en tres patrones:

PatrónCuándo usarloImplementación
Anónimo + rate limit por IPCatálogo público, solo lectura, carga acotadaEl Worker solo comprueba el bucket de la IP
Token de API con scopesIntegración B2B, runtime de agente headless, sin usuario humanoToken opaco aleatorio, hash almacenado, caducidad y rotación
OAuth 2.1 + PKCEAgente de consumo para un usuario autenticadoAuthorization code flow estándar

Los patrones no se excluyen. Un servidor de producción real suele ejecutar los tres, y cada herramienta lleva la etiqueta del scope que requiere.

#Acceso MCP anónimo de solo lectura con rate limiting

Expón solo campos públicos del catálogo aprobados expresamente. La API de gestión WooCommerce wc/v3 requiere credenciales en el servidor y no es un origen público anónimo. Utiliza un endpoint público revisado o un adapter que excluya campos privados.

Implementación:

async function checkAnonymousRateLimit(request: Request, env: Env): Promise<boolean> {
  const ip = request.headers.get("CF-Connecting-IP") ?? "unknown";
  const { success } = await env.AUTH_RATE_LIMIT.limit({ key: `anonymous:${ip}` });
  return success;
}

60 peticiones por minuto por IP es mi valor por defecto. Un contador basado en KV es aproximado (las escrituras en KV son eventually consistent); para límites estrictos, Durable Objects o el binding nativo de Rate Limiting de Cloudflare son la herramienta adecuada.

Lo que este patrón no cubre: ninguna herramienta que devuelva datos específicos de un usuario, ninguna que modifique estado, ninguna que revele el stock de productos no públicos. Esas requieren un principal real.

#Tokens de API con scopes para integraciones B2B con MCP

El caso B2B: la integración de un socio aporta un agente que llama a tu servidor MCP en nombre de la organización del socio, no de un usuario humano concreto. Ejemplos: un agente de sincronización de stock en un mayorista, una integración de marketplace en un agregador, un agente de analítica que informa de tendencias de pedidos al BI.

El flujo:

  1. Un administrador en el backend de WordPress crea un token con un nombre, un conjunto de scopes (catalogue:read, inventory:read, orders:write) y una fecha de caducidad (por defecto, 90 días).
  2. El token se muestra al administrador una sola vez y después se guarda como hash SHA-256 más el conjunto de scopes más la caducidad.
  3. El socio configura su cliente MCP con el token en la cabecera Authorization: Bearer <token>.
  4. El Worker calcula el hash del token entrante y lo busca en KV. Si el hash coincide, la caducidad está en el futuro y el scope que exige la herramienta está en el conjunto del token, la llamada continúa.
async function verifyApiToken(authHeader: string | null, env: Env): Promise<TokenContext | null> {
  if (!authHeader?.startsWith("Bearer ")) return null;
  const token = authHeader.slice(7);
  const hash = await sha256(token);
  const record = await env.TOKENS.get(`tok:${hash}`, "json") as TokenRecord | null;
  if (!record) return null;
  if (record.expiresAt < Date.now()) return null;
  return { tokenId: record.id, scopes: record.scopes, principal: record.principal };
}

function requireScope(ctx: TokenContext, scope: string): void {
  if (!ctx.scopes.includes(scope)) throw new Error("Insufficient scope");
}

Dos hábitos operativos mantienen el patrón honesto:

Rotación, no eternidad. Un token que nunca caduca es un token que dentro de seis meses acaba en un repositorio público de GitHub. 90 días por defecto, con un flujo de renovación en el que el token antiguo y el nuevo conviven durante 7 días, es el patrón que sobrevive a socios reales.

Almacenamiento con hash, no en texto plano. Si tu KV se filtra, los hashes sin el token original no sirven para nada. Si guardaste los tokens en texto plano, todas las integraciones de socios necesitan una rotación inmediata. La diferencia de coste en el momento de la emisión es una llamada a sha256.

#OAuth 2.1 con PKCE en un servidor MCP

El caso de consumo: el usuario abre Claude Desktop, conecta su cuenta de tu tienda mediante OAuth y le pide al agente “muéstrame mi último pedido”. El agente tiene que llamar ahora a tu servidor MCP con credenciales que digan “actúo en nombre del usuario 4231”.

OAuth 2.1 (draft-ietf-oauth-v2-1) es el perfil consolidado. PKCE (RFC 7636) es obligatorio para clientes públicos (aquí entran los asistentes de escritorio sin una parte de servidor confidencial).

El flujo en cinco pasos:

  1. El host MCP abre el navegador en tu endpoint de autorización con response_type=code, code_challenge=<hash S256 del verifier> y los scopes solicitados.
  2. El usuario inicia sesión en tu sitio WordPress (o en tu proveedor de autenticación) y acepta los scopes.
  3. Tu endpoint de autorización redirige al host con un código de autorización de un solo uso.
  4. El host intercambia el código más el code_verifier original en tu endpoint de tokens por un access token (TTL corto, 1 hora) y un refresh token (TTL más largo, 30 días).
  5. El host llama al servidor MCP con Authorization: Bearer <access_token>. El Worker verifica la firma del token, la caducidad y el scope frente a la herramienta invocada.

Un token OAuth puede ser opaco o JWT. El ejemplo utiliza un emisor configurado y la biblioteca jose mantenida para validar firma y claims:

import { createRemoteJWKSet, jwtVerify } from "jose";

const issuer = "https://identity.example.org";
const audience = "https://mcp.example.org/mcp";
const jwks = createRemoteJWKSet(new URL(issuer + "/.well-known/jwks.json"));

async function verifyJwt(token: string) {
  const { payload } = await jwtVerify(token, jwks, {
    issuer,
    audience,
    algorithms: ["RS256"],
    requiredClaims: ["sub", "exp"],
  });
  if (typeof payload.sub !== "string" || typeof payload.scope !== "string") {
    throw new Error("Invalid identity or scope claims");
  }
  return { subject: payload.sub, scopes: payload.scope.split(" ").filter(Boolean) };
}

Los scopes del JWT reflejan los del patrón de token con scopes: catalogue:read, orders:read, orders:write. El ID del usuario de WordPress va en el claim sub, así que una llamada orders:read devuelve solo los pedidos de ese usuario.

#Cómo combinar OAuth, tokens y acceso anónimo en un servidor MCP

Un servidor MCP real para WooCommerce suele exponer:

  • catalogue.list y product.detail: anónimo + rate limit por IP.
  • inventory.check (para socios): token con scope inventory:read.
  • order.status (para el usuario autenticado): OAuth con orders:read.
  • order.intent (para el usuario autenticado): OAuth con orders:write, más un rate limit más estrecho.

La lógica de pre-dispatch en el Worker recorre los patrones:

Autentica HTTP antes del dispatch MCP. Comprueba después los scopes de la herramienta y la propiedad del recurso. Rechaza herramientas desconocidas y políticas ausentes. Los fallos de autenticación requieren challenges bearer HTTP en vez de códigos JSON-RPC inventados como texto.

El mapa TOOL_AUTH_REQUIREMENTS es la única fuente de verdad sobre qué herramienta necesita qué modo de autenticación. Ninguna herramienta se añade sin una entrada explícita.

#Límites de peticiones MCP por IP, token y usuario

El tráfico anónimo recibe un bucket por IP. El tráfico con token recibe un bucket por token. El tráfico OAuth recibe un bucket por usuario. Las herramientas que modifican estado reciben un techo más bajo sea cual sea el principal.

Los siguientes valores son ejemplos de configuración, no mediciones ni límites predeterminados de producción. Define los límites reales según la capacidad del origen y el tráfico observado.

Categoría de herramientaAnónimoTokenOAuth
catalogue.* (lectura)60 / minuto / IP600 / minuto / token120 / minuto / usuario
inventory.* (lectura)no permitido300 / minuto / tokenno permitido
order.status (lectura)no permitido60 / minuto / token60 / minuto / usuario
order.intent (escritura)no permitido30 / minuto / token10 / minuto / usuario

Las cifras son un punto de partida; los valores correctos salen de observar tráfico real durante dos semanas y ajustar. Lo que cuenta es la estructura.

#Qué eventos de autenticación MCP registrar

Cada evento relevante para la autenticación acaba en el registro:

  • Token emitido. Administrador, principal de destino, scopes, caducidad.
  • Token usado. ID del token, nombre de la herramienta, principal, latencia, éxito/fallo.
  • Token revocado. ID del token, quién lo revocó, por qué.
  • Token rechazado. Motivo (caducado, falta scope, el hash no coincide), IP, user agent.
  • Intercambio de código OAuth. ID del usuario, scopes concedidos, refresh token emitido.
  • Refresh de OAuth. ID del usuario, nuevo access token, token antiguo sustituido.

Los registros van por Cloudflare Logpush a un almacenamiento a largo plazo. Una consulta de dashboard que sigue los “tokens usados en las últimas 24 horas que no se habían usado en los 90 días anteriores” detecta un probable robo de token. Una consulta de “verificaciones de token fallidas por IP” detecta intentos de credential stuffing.

#Discovery e identidad del recurso protegido

La especificación de autorización MCP de 2025-11-25 define un flujo OAuth para transportes HTTP. La autorización es opcional, pero un servidor HTTP protegido e interoperable necesita discovery y validación conforme a ese perfil. Stdio tiene otra frontera de despliegue y obtiene credenciales del entorno. Los tokens propios pueden servir a una integración controlada con socios. No presupongas que cualquier host MCP sabe descubrir u obtener esas credenciales. Prueba el host y el transporte que se utilizarán.

Separa los roles del servidor de recursos MCP y del servidor de autorización, aunque compartan aplicación. El primero ejecuta herramientas y valida el acceso. El segundo gestiona login, consentimiento y emisión de tokens. Publica metadatos del recurso protegido con su identidad canónica y los servidores de autorización. Una respuesta HTTP 401 puede señalar esos metadatos mediante WWW-Authenticate. Las direcciones deben funcionar detrás del reverse proxy y con un prefijo de ruta. Que el navegador muestre una página de login no demuestra que el host haya encontrado al emisor correcto.

El cliente solicita un access token destinado al recurso MCP mediante el parámetro resource. El servidor valida esa asociación. Un token emitido para otra API no resulta aceptable solo porque lo firmó correctamente un emisor conocido. Rechaza audience e issuer inesperados antes de ejecutar herramientas. Usa el mismo URI canónico en metadatos, solicitud de autorización y validación. No derives la audience esperada de un encabezado Host no fiable ni de un parámetro libre del cliente.

#Validación completa y credenciales de servicios externos

Los access tokens OAuth pueden ser opacos o JWT. El protocolo no obliga a todos los emisores a usar JWT. Un token opaco requiere el mecanismo de verificación admitido por su emisor. Un verificador JWT comprueba firma, algoritmo permitido, issuer, audience y fechas de validez. Después valida los claims de aplicación que utiliza. Una aserción de tipos TypeScript no hace comprobaciones en runtime. JSON malformado, ausencia de subject o scope con tipo incorrecto debe causar una denegación controlada. Usa una biblioteca mantenida y una fuente de confianza configurada en vez de un verificador parcial con Web Crypto.

Obtén las claves de la dirección JWKS configurada para el emisor, no de una URL arbitraria incluida en el token. Prepara la rotación de claves y la indisponibilidad del emisor. Un fallo al obtener una clave no puede admitir un token sin verificar. Una clave fiable ya guardada puede funcionar según la política definida, pero una clave desconocida exige una decisión explícita. Prueba tokens caducados, todavía no válidos, algoritmos distintos y tokens de otro entorno. Las credenciales de staging no deben funcionar por accidente en producción.

Las directrices de seguridad MCP prohíben token passthrough. Un bearer token dirigido al servidor MCP no puede enviarse a WooCommerce o ERP como credencial de esos servicios. Guarda las claves de origen en el servidor y autoriza la acción antes de utilizarlas. Si el servicio requiere identidad delegada, establece su flujo compatible de delegación o intercambio de tokens. Copiar el encabezado Authorization recibido no constituye un modelo de delegación.

#Scopes y propiedad de los pedidos

Autentica la petición HTTP y comprueba después los scopes de la operación. Una verificación de token correcta no elimina la comprobación de permisos de la herramienta. El registro debe indicar los derechos de cada operación. Una entrada desconocida se rechaza. Los cambios requieren pruebas de llamadas permitidas y denegadas. La lista de discovery también necesita una política para descripciones y parámetros sensibles. Conocer el nombre de una herramienta no concede el derecho a ejecutarla.

orders:read define una categoría de acciones, no el propietario del pedido. Asocia el subject verificado a una cuenta interna mediante un mapeo fiable y comprueba la propiedad al cargar el pedido. Un identificador de cliente enviado por el agente no demuestra autorización. El socio con acceso a toda una organización necesita una concesión separada y una frontera de tenant definida. Un distribuidor español que importa existencias y un cliente que consulta la entrega tienen identidades diferentes aunque accedan al mismo servidor MCP.

Gestiona los fallos de bearer authentication en la capa HTTP correspondiente. Un token ausente o inválido requiere denegación de autenticación. Los scopes insuficientes necesitan el challenge adecuado. Un access token caducado no debe parecer un resultado comercial de falta de existencias. Separar estos casos permite al host renovar acceso o solicitar consentimiento, en vez de repetir una acción con credenciales inalteradas.

#Revocación, cuotas y pruebas de publicación

Genera tokens opacos de socios con aleatoriedad criptográfica suficiente. Guardar hashes ayuda solo cuando el secreto original es difícil de adivinar. Separa el identificador público del secreto y usa una implementación de verificación revisada. Define la propagación de la revocación. Workers KV tiene consistencia eventual, por lo que eliminar un registro no garantiza revocación global inmediata. Las operaciones sensibles pueden necesitar una consulta a la fuente autoritativa u otra frontera de consistencia. Una caducidad corta limita exposición, pero no sustituye revocación.

El rate limiting también tiene un modelo de consistencia. El binding de rate limiting Workers limita volumen de peticiones, pero no es un presupuesto transaccional global para pedidos u operaciones pagadas. Utiliza un coordinador autoritativo adecuado para cuotas comerciales. Leer y después escribir en KV no constituye un incremento atómico. Las peticiones concurrentes pueden perder actualizaciones. Los reintentos del agente no deben generar más operaciones que la acción prevista.

Antes de publicar, prueba discovery desde el hostname de producción, consentimiento, caducidad, refresh, revocación y scopes insuficientes con el host MCP elegido. Incluye acceso al pedido de otro cliente y a otro tenant. Confirma que los resultados privados no llegan a una caché compartida. Registra identificador de token, identidad, herramienta y resultado sin secretos ni payloads de clientes. Separa eventos de seguridad de trazas de diagnóstico y define la retención de cada almacén. Un login correcto es solo el comienzo de la prueba de control de acceso.

#Temas relacionados

Este artículo trata la autenticación. El refuerzo más amplio de WordPress está en la guía de seguridad de WordPress. La página del servicio es desarrollo de servidores MCP.

Presupuesto individual, porque el alcance de la autenticación depende de los patrones que exige tu entorno; un servidor de solo lectura en modo anónimo es un proyecto distinto de una superficie completa que emite OAuth.

Siguiente paso

Transforma el artículo en una implementación real

Este bloque refuerza el enlazado interno y lleva al lector al siguiente paso más útil dentro de la arquitectura del sitio.

Explora otros servicios WordPress y base de conocimiento

Refuerza tu negocio con soporte técnico profesional en áreas clave del ecosistema WordPress.

Preguntas frecuentes

Respuestas prácticas para aplicar el tema en la ejecución real.

¿La especificación MCP exige autenticación?#
La autorización es opcional. Las implementaciones HTTP protegidas deberían seguir el perfil MCP con discovery OAuth y tokens asociados al recurso. Stdio obtiene credenciales del entorno.
¿Cuándo es aceptable un servidor MCP anónimo?#
Expón solo campos públicos del catálogo aprobados expresamente. La API de gestión WooCommerce wc/v3 requiere credenciales en el servidor y no es un origen público anónimo. Utiliza un endpoint público revisado o un adapter que excluya campos privados.
¿Por qué precisamente OAuth 2.1?#
OAuth 2.1 consolida las pautas actuales de OAuth 2.0 más PKCE, elimina los flujos obsoletos implicit y resource-owner-password y encaja con lo que Claude Desktop y otros hosts MCP admiten de forma nativa para el acceso delegado de agentes.
¿Dónde se guardan los tokens con scopes?#
Los tokens se emiten desde un área de administración del lado de WordPress, se guardan como valor con hash más scope más fecha de caducidad y se verifican en cada petición MCP. Guardarlos en texto plano es el mismo error que guardar contraseñas en texto plano.
¿Cómo encaja el rate limiting con la autenticación?#
Los límites se asocian al principal: un token autenticado tiene su propio bucket, el tráfico anónimo comparte un bucket por IP. Las herramientas que modifican estado reciben un bucket más estrecho sea cual sea el principal, para que un token comprometido no pueda ejecutar order.intent en bucle.

¿Necesitas un FAQ adaptado a tu sector y mercado? Preparo una versión alineada con tus objetivos de negocio.

Hablemos

Artículos Relacionados