Skip to main content
Glama
mustafadeel

@auth0/agent-components

by mustafadeel

@auth0/agent-components — Универсальные компоненты Auth0 для агентов

Превратите форму Auth0 в MCP-приложение — интерактивный интерфейс, который сервер Model Context Protocol предоставляет MCP-клиенту, отображаемый в изолированном iframe. Это универсальные компоненты Auth0 для агентов: любая форма Auth0 становится готовым к использованию, вызываемым агентом интерфейсом, без необходимости в Auth0 Action.

Статус: концепция-доказательство. Работает сквозным образом с официальной возможностью MCP Apps (SEP-1865), MCP Inspector и CopilotKit (см. examples/copilotkit-poc).

Зачем

Формы Auth0 обычно отображаются только внутри Auth0 Action во время Universal Login. dx-flows-sdk развязал это: форму можно встраивать через браузерный бандл вне редиректа входа. MCP Apps позволяют серверу передавать клиенту интерактивный HTML для отображения в изолированном iframe. Соедините их — и агент сможет предоставить настоящую, полностью функциональную форму Auth0 — регистрацию, согласие, профиль, оплату — как один из своих инструментов.

Related MCP server: Homespun

Как это работает

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)

Форма владеет своими данными. Форма Auth0 отправляется нативно в свой бэкенд Auth0. Слой MCP никогда не читает и не передает значения полей — он сообщает только статус завершения (completed / cancelled / errored, плюс необязательную цель перенаправления), чтобы агент знал, что пользователь закончил.

Пакеты

Package

What it is

packages/agent-components

@auth0/agent-components — регистрирует формы Auth0 как MCP-приложения на любом McpServer.

packages/mcp-apps-middleware-auth

@auth0/mcp-apps-middleware-auth — добавляет аутентификацию к @ag-ui/mcp-apps-middleware от CopilotKit, который не может прикрепить учетные данные к своим MCP-подключениям.

examples/poc-server

Рабочий MCP-сервер POC; управляйте им из MCP Inspector. Включает scripts/discover-forms.mjs (обнаружение форм тенанта через Auth0 CLI).

examples/copilotkit-poc

CopilotKit как MCP-клиент — реальный вход Auth0 (@auth0/auth0-server-js) → форма отображается и отправляется встроенно. Сквозной процесс.

Использование

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)

Каждая форма регистрирует:

  • инструмент open_form_<slug>, чей _meta.ui.resourceUri указывает на …

  • ресурс ui://agent-components/<formId>, возвращающий HTML формы-приложения + блок CSP.

CSP

Хост отображает ресурс в соответствии со строгой политикой по умолчанию (default-src 'none'). @auth0/agent-components автоматически добавляет ваш tenantOrigin в белый список в обоих случаях:

  • csp.resourceDomains — чтобы forms.js, стили, шрифты, изображения загружались, и

  • csp.connectDomains — чтобы fetch бандла к /forms/api/... работал.

Если шаг формы встраивает iframe другого источника (Stripe, социальный провайдер, капча), объявите его:

ui: { csp: { frameDomains: ["https://js.stripe.com", "https://hooks.stripe.com"] } }

Следите за консолью браузера при первом рендеринге новой формы: любое нарушение CSP точно укажет, какой источник добавить.

Формы, поддерживаемые сеансом (формы flow/router)

Формы с узлом FLOW/ROUTER требуют аутентифицированного сеанса — в противном случае шаг после роутера завершается ошибкой ERR_INVALID_FORM_SESSION. Механизм (подтвержден командой Forms, проверен сквозным образом):

  1. Объявите скрытое поле в форме (например, session_token).

  2. Поток формы читает его — например, действие Update User с user_id: {{fields.session_token}}.

  3. MCP-сервер, действуя как OAuth-ресурсный сервер, проверяет токен Auth0 вызывающей стороны, определяет sub пользователя, выпускает кратковременный доверенный JWT для него (подписанный общим секретом, которому доверяет бэкенд Forms) и внедряет его в скрытое поле для каждого запроса.

Помечайте форму как поддерживающую сеанс:

{
  formId: "ap_...",
  session: { field: "session_token" },   // must match the form's hidden field
}

…и инициализируйте клиент с конфигурацией доверия на уровне сервера и резолвером, который читает проверенную личность (верификатор и subFromExtra приходят из подпути /auth, поддерживаемого @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);

Сервер POC (examples/poc-server) реализует полный поток: createAuth0Verifier (→ @auth0/auth0-api-js), конечная точка метаданных ProtectedResourceMetadataBuilder и requireBearerAuth — так что вызов 401 + WWW-Authenticate позволяет клиенту выполнить поток OAuth Auth0. Токен/sub/выпущенный JWT никогда не попадают в контекст модели MCP — выпущенный токен передается через embed().fields только в бэкенд форм Auth0.

Примечание: завершенный путь Auth0 Forms сегодня одноразовый (повторная отправка использованного пути возвращает ERR_INVALID_FORM_SESSION). Universal Portals EPIC 7 добавляет повторно завершаемые пути. MCP-приложение завершается один раз и сообщает статус, поэтому новый вызов инструмента получает новый путь — повторная отправка не является частью потока.

Время регистрации

MCP SDK запрещает добавлять возможность после server.connect(transport). Два поддерживаемых шаблона:

  • Регистрация до подключения (самый простой способ) с assumeUiSupport: true. Подходит для клиентов с поддержкой UI (MCP Inspector, Claude). Именно так делает POC.

  • Динамическое ограничение по клиенту (assumeUiSupport: "auto", по умолчанию): вызывайте registerAuth0Forms из server.server.oninitialized, чтобы возможности клиента были известны — и создавайте сервер с { capabilities: { tools: {}, resources: {} } }, или зарегистрируйте один инструмент + один ресурс до подключения, чтобы регистрация после подключения не пыталась добавить новую возможность.

Разработка

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)

Лицензия

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables 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.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables agents to ask users questions through rich, browser-rendered HTML forms and receive structured answers, supporting approvals, choices, free-text, and form inputs.
    11 npm
    MIT