@auth0/agent-components
@auth0/agent-components — Auth0 Universal Components for Agents
Convierte un Auth0 Form en una MCP App — una interfaz de usuario interactiva que un servidor de Model Context Protocol sirve a un cliente MCP, renderizada en un iframe aislado. Esto es Auth0 Universal Components for Agents: cualquier Auth0 Form se convierte en una interfaz de usuario invocable por agentes, sin necesidad de una Auth0 Action.
Estado: prueba de concepto. Funciona de extremo a extremo con la capacidad oficial de MCP Apps (SEP-1865), el MCP Inspector y CopilotKit (ver
examples/copilotkit-poc).
Por qué
Los Auth0 Forms normalmente se renderizan solo dentro de una Auth0 Action durante el Universal Login. El dx-flows-sdk desacopló eso: un formulario se puede incrustar mediante el bundle del navegador fuera de una redirección de login. Las MCP Apps permiten que un servidor entregue HTML interactivo a un cliente para renderizarlo en un iframe aislado. Juntándolos, un agente puede mostrar un Auth0 Form real y completamente funcional — registro, consentimiento, perfil, pago — como una de sus herramientas.
Related MCP server: Homespun
Cómo funciona
MCP host (e.g. MCP Inspector, CopilotKit)
└─ sandboxed iframe ← our ui:// HTML resource (text/html;profile=mcp-app)
├─ <script src="https://<tenant>/forms/sdk/forms.js">
├─ Auth0Forms.embed(formId, "#root", { fields: { session_token } })
│ └─ form submits to its OWN Auth0 backend (/forms/api/...) ← we never see the data
└─ bridge: on af-submitForm-success → app.updateModelContext({ status: "completed" })
→ app.requestTeardown() (close the app view)
on af-redirect → app.openLink(url) (never navigates the iframe)El formulario es dueño de sus datos. El Auth0 Form se envía de forma nativa a su backend de Auth0. La capa MCP nunca lee ni transmite los valores de los campos — solo informa un estado de finalización (completed / cancelled / errored, más un destino de redirección opcional) para que el agente sepa que el usuario terminó.
Paquetes
Package | What it is |
| |
| |
POC de servidor MCP ejecutable; pruébalo desde el MCP Inspector. Incluye | |
CopilotKit como cliente MCP — login real de Auth0 ( |
Uso
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerAuth0Forms } from "@auth0/agent-components";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
await registerAuth0Forms(
server,
[
{
formId: "your-form-id",
tenantOrigin: "https://your-tenant.us.auth0.com",
// inputMode: "prefill", // expose form fields as optional agent inputs
// ui: { csp: { frameDomains: ["https://js.stripe.com"] } }, // for payment/social steps
onComplete: (r) => console.log(r.formId, r.status), // status only — no field data
},
],
{ assumeUiSupport: true }, // register before connect; see "Registration timing"
);
// ...connect your transport (StreamableHTTP / stdio / SSE)Cada formulario registra:
una herramienta
open_form_<slug>cuyo_meta.ui.resourceUriapunta a …un recurso
ui://agent-components/<formId>que devuelve el HTML de la aplicación de formulario + un bloque CSP.
CSP
El host renderiza el recurso bajo una política predeterminada estricta (default-src 'none'). @auth0/agent-components automáticamente incluye en la lista blanca tu tenantOrigin en ambos:
csp.resourceDomains— para queforms.js, estilos, fuentes e imágenes se carguen, ycsp.connectDomains— para que elfetchdel bundle a/forms/api/...funcione.
Si un paso del formulario anida un iframe de otro origen (Stripe, un proveedor social, un captcha), decláralo:
ui: { csp: { frameDomains: ["https://js.stripe.com", "https://hooks.stripe.com"] } }Observa la consola del navegador la primera vez que renderices un formulario nuevo: cualquier violación de CSP te indica exactamente qué origen añadir.
Formularios respaldados por sesión (formularios de flujo/router)
Los formularios con un nodo FLOW/ROUTER necesitan una sesión autenticada — de lo contrario, el paso posterior al router falla con ERR_INVALID_FORM_SESSION. El mecanismo (confirmado con el equipo de Forms, verificado de extremo a extremo):
Declara un campo oculto en el formulario (por ejemplo,
session_token).El flujo del formulario lo lee — por ejemplo, una acción
Update Userconuser_id: {{fields.session_token}}.El servidor MCP, actuando como servidor de recursos OAuth, verifica el token de Auth0 del llamante, resuelve el
subdel usuario, emite un JWT de confianza de corta duración para él (firmado con un secreto compartido que el backend de Forms confía) y lo inyecta en el campo oculto por solicitud.
Marca el formulario como consciente de sesión:
{
formId: "ap_...",
session: { field: "session_token" }, // must match the form's hidden field
}…e inicializa el cliente con la configuración de confianza del servidor + un resolvedor que lee la identidad verificada (verifier + subFromExtra provienen del subpath /auth, respaldado por @auth0/auth0-api-js):
import { createAgentComponents } from "@auth0/agent-components";
import { subFromExtra } from "@auth0/agent-components/auth";
const agentComponents = createAgentComponents({
tenantOrigin: "https://your-tenant.auth0.com",
assumeUiSupport: true,
sessionTrust: { secret: process.env.FORMS_TRUST_SECRET! }, // shared with the Forms backend
resolveUserSub: subFromExtra, // returns the caller's `sub`, or undefined
});
await agentComponents.register(server, forms);El servidor POC (examples/poc-server) conecta el flujo completo: createAuth0Verifier (→ @auth0/auth0-api-js), un endpoint de metadatos ProtectedResourceMetadataBuilder y requireBearerAuth — de modo que un desafío 401 + WWW-Authenticate permite al cliente ejecutar el flujo OAuth de Auth0. El token/sub/JWT emitido nunca entra en el contexto del modelo MCP — el token emitido viaja en embed().fields solo al backend de Auth0 Forms.
Nota: un viaje de Auth0 Forms completado es de un solo uso hoy (re-enviar un viaje gastado devuelve
ERR_INVALID_FORM_SESSION). Universal Portals EPIC 7 añade viajes re-completables. La MCP App se completa una vez e informa el estado, por lo que una nueva invocación de herramienta obtiene un viaje nuevo — el re-envío no es parte del flujo.
Momento de registro
El SDK de MCP prohíbe añadir una capacidad después de server.connect(transport). Dos patrones admitidos:
Registrar antes de conectar (lo más simple) con
assumeUiSupport: true. Correcto para clientes con capacidad de UI (MCP Inspector, Claude). Esto es lo que hace el POC.Control dinámico por cliente (
assumeUiSupport: "auto", el predeterminado): llama aregisterAuth0Formsdesdeserver.server.oninitializedpara que se conozcan las capacidades del cliente — y construye el servidor con{ capabilities: { tools: {}, resources: {} } }, o registra una herramienta + un recurso antes de conectar, para que el registro posterior a la conexión no intente añadir una nueva capacidad.
Desarrollo
npm install
npm run build # builds all packages (agent-components builds its bridge first)
npm test # unit tests (form→tool, ui-template CSP, bridge status-only contract)Licencia
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Renders dashboards, forms and tables inline in the chat as Angular Material components (MCP App).
112An AI concierge that turns static forms into adaptive AI conversations. From any MCP client.
Connect any AI agent to 1,000+ apps and 27,000+ actions through one remote MCP server (OAuth).
Agent-Native form builder - create, edit, and manage forms
Related MCP Servers
- AlicenseAqualityAmaintenanceHand a human a rich interactive UI by URL from any MCP client and get structured data back — forms, approvals, surveys, pickers, editable lists. Round-trip human-in-the-loop for agents.262 npm7MIT
- AlicenseAqualityBmaintenanceHand a human a rich interactive UI by URL from any MCP client and get structured data back: forms, approvals, surveys, pickers, editable lists. Round-trip human-in-the-loop for agents.201MIT
- FlicenseNot gradedqualityCmaintenanceEnables authenticated MCP apps to expose and interact with Auth0 Forms, submitting form data directly to Auth0 while only completion status is returned to the agent.-
- AlicenseNot gradedqualityAmaintenanceEnables agents to ask users questions through rich, browser-rendered HTML forms and receive structured answers, supporting approvals, choices, free-text, and form inputs.11 npmMIT