Sign inSign up
uag logo

formio/uag

Verified Publisher

By Form.io

•Updated about 9 hours ago

The Form.io Universal Agent Gateway — an MCP server for agentic form automation with AI agents.

Image
Machine learning & AI
Developer tools
0

10K+

formio/uag repository overview

⁠Form.io Universal Agent Gateway (UAG)

The UAG is a server that sits in front of one Form.io⁠ project and lets AI agents work with its forms. It turns each form tagged uag into context a model can use, validates every value an agent sends with the form's own rules, and forwards every write to Form.io with the caller's own permissions.

Also published as @formio/uag⁠ on npm and listed in the official MCP Registry⁠ as io.form/formio-uag.

⁠What it enables

Conversation to a validated submission. An agent collects data through natural language and produces a deterministic, schema-valid Form.io submission — no bespoke parsing, and the form's own validation still applies.

Agentic workflows. Applications send submissions to the UAG instead of the Form.io project URL. The UAG forwards each one to Form.io, which saves it and runs the form's own actions, and an Agent: Run task action on the form runs one of its tasks before or after the save: review steps, enrichment, triage, and similar automation driven by a form submission. A task's results are saved as an update through the UAG, which can start the next task.

⁠Quick start

Against a Form.io Open Source server:

docker run -d --name formio-uag -p 3200:3200 \
  -e PROJECT=https://forms.example.com \
  -e ADMIN_KEY=your-admin-key \
  -e JWT_SECRET=your-jwt-secret \
  -e LOGIN_FORM=https://forms.example.com/user/login \
  --restart unless-stopped \
  formio/uag

Against a project on Form.io's hosted service, use PROJECT_KEY in place of ADMIN_KEY, and set no license:

docker run -d --name formio-uag -p 3200:3200 \
  -e PROJECT=https://myproject.form.io \
  -e PROJECT_KEY=your-project-api-key \
  -e JWT_SECRET=your-jwt-secret \
  --restart unless-stopped \
  formio/uag

Against a self-hosted Form.io Enterprise project, add a Form.io license that includes the UAG, in LICENSE_KEY, whose endpoint allowlist includes PROJECT's host; for an offline license, also set LICENSE_REMOTE=true:

docker run -d --name formio-uag -p 3200:3200 \
  -e PROJECT=https://forms.example.com/myproject \
  -e PROJECT_KEY=your-project-api-key \
  -e LICENSE_KEY=your-license \
  -e JWT_SECRET=your-jwt-secret \
  --restart unless-stopped \
  formio/uag

Docker Compose is the recommended path for anything beyond a single container. The README's Quickstart⁠ runs the UAG beside a Form.io Open Source server in one Compose file. The repository's custom module sample⁠ is a fuller stack to start from: Form.io Open Source, MongoDB and the UAG with a module of its own, and the engine setups⁠ add engines to a stack like it.

⁠Connecting an agent

The MCP endpoint is http://<host>:<port>/mcp, served over Streamable HTTP (default port 3200).

A local client (your own server, or a script) exchanges ADMIN_KEY or PROJECT_KEY for a token at /auth/token with the client_credentials grant, which needs no other setting. Remote clients that connect in, such as claude.ai and Claude Desktop connectors, sign in through OAuth: they need the UAG public over HTTPS, MCP_OAUTH=true and MONGO, which needs a license that includes the UAG. Behind a reverse proxy, set TRUST_PROXY so the OAuth discovery documents name the public URL, or set BASE_URL.

Engine servers (formio/uag-engines) run their own MCP client and connect outward to the UAG for research, so the UAG does not need to be publicly reachable for them — only reachable from the engine server, such as over a private Docker network.

⁠Agent API and engines

Besides MCP, the UAG serves an HTTP Agent API for a form's tasks: POST {form}/agent/extract, {form}/agent/decide and {form}/agent/generate, under the form's URL on the UAG (for example https://uag.example.com/supportrequest/agent/decide), which read no stored submission, save nothing and take the same credentials as the form's submissions; and GET /agent/capabilities at the UAG's root, which lists the enabled engines. The operations, and the Run task action, need an engine; with none enabled the operations return 503. The image bundles the official engines, and UAG_ENGINES names the ones to enable:

EngineWhat it doesNeeds
jevDecides closed-set fields (radio, select, checkbox and similar) with a confidence, using TypeSafe Jev.TYPESAFE_API_KEY
claudeExtracts and generates open values, researching with a task's read-only tools when it lists them.CLAUDE_API_KEY
openaiExtracts and generates open values on OpenAI, or any OpenAI-compatible server (Ollama, vLLM, OpenRouter). With UAG_ENGINE_<NAME>_KIND=decision, decides closed-set fields on OpenAI's Decisions API.OPENAI_MODEL, and OPENAI_API_KEY (sent only to OpenAI) or OPENAI_BASE_URL (with UAG_ENGINE_<NAME>_API_KEY when that server needs a key)
grokExtracts and generates open values with xAI's Grok models.XAI_API_KEY, XAI_MODEL
geminiExtracts and generates open values with Google's Gemini models.GEMINI_API_KEY, GEMINI_MODEL
remoteAn engine hosted by an engine server (formio/uag-engines), so the model's API key stays in that container.UAG_ENGINE_<NAME>_URL, UAG_ENGINE_<NAME>_KEY, and JWT_SECRET for research

With the quick-start settings in an uag.env file (on a self-hosted project, with a LICENSE_KEY that includes the UAG):

docker run -d --name formio-uag -p 3200:3200 \
  --env-file uag.env \
  -e UAG_ENGINES=jev,claude \
  -e TYPESAFE_API_KEY=your-typesafe-key \
  -e CLAUDE_API_KEY=your-claude-key \
  formio/uag

The Agent API and Run task are Agentic Formflow. A project on Form.io's hosted service runs it with real engines and no license. On a self-hosted project, Open Source or Enterprise, real engines need a license in LICENSE_KEY that includes the UAG for the project's endpoint: an online license whose key has the uagServer scope, or an offline license with the uag option (with LICENSE_REMOTE=true). UAG_LICENSE still works, but is deprecated. Conversation forms need no license, and run on Form.io Open Source: the MCP tools, and a form's chat ({form}/agent/chat, which Formio.createChat in @formio/uag-js embeds in a page) with any agent engine. The stub engines (stub-decision, stub-agent) run without one, for trying the API out. Unlicensed requests answer 403 with code: "license_required", and GET /agent/capabilities reports the edition and formflow.reason. See the licensing documentation⁠.

Callers send the signed-in user's Form.io token (x-jwt-token), a portal team member's remote token (x-remote-token) or a UAG bearer token, and Form.io's permissions apply; servers may send x-token / x-admin-key instead, which are refused from browsers. A form that sets uagAnonymous: "true" and lets Anonymous create submissions also answers visitors with no credential, within the anonymous rate limits. jev and claude send submission data to their provider's hosted API. Field properties, routing and the Run task action are covered in the Agent API⁠ and Workflows⁠ documentation.

⁠Configuration

VariableDescription
PROJECTRequired. API endpoint of the Enterprise project or the OSS server.
JWT_SECRETRequired. Secret used to sign and validate the UAG's own JWTs, including the scoped tokens a remote engine's server uses to call /mcp. Set it to the Form.io Enterprise server's for a Run task action with an agent role to act on users' behalf.
BASE_URLOptional. The URL clients reach the UAG at, for the OAuth discovery documents remote MCP clients read. Derived from each request when unset.
TRUST_PROXYExpress's trust proxy (true, a number of hops, or addresses). Set it behind a reverse proxy, so the UAG reads its public URL from the forwarded headers.
MCP_OAUTHtrue turns on OAuth sign-in for remote MCP clients (the /auth/authorize page, client registration and /.well-known/*). Needs MONGO, with its license; otherwise the UAG starts with it off and says why. /auth/token (client_credentials) and API keys work without it.
MONGOOptional. The UAG's own database, for run records, runs that survive a restart, and remote MCP sign-in. Holds only uag-* collections, never submissions. Needs a license that includes the UAG, on every project; without one the UAG starts with its database features off and says why.
UAG_DATABASEThe database to use on the MONGO connection, selected by name. Default uag.
MONGO_CONFIGMongoDB driver options for MONGO, as JSON.
TASK_RUN_RETENTION_DAYSDays run records are kept. Default 90; 0 keeps them forever.
PROJECT_KEYEnterprise only. Project API key, from Project Settings → API Keys.
ADMIN_KEYOpen Source only. Used instead of PROJECT_KEY.
LICENSE_KEYThe Form.io license. One that includes the UAG, and whose endpoint allowlist includes PROJECT's host, is required to run against a self-hosted Form.io Enterprise project; leave it unset for a project on Form.io's hosted service (https://*.form.io), which also runs Agentic Formflow without one, unless the UAG has its own database. A license that includes the UAG enables Agentic Formflow (the Agent API's extract, decide and generate, the Run task action, agent_decide and agent_provide) with real engines, on Open Source too; without it these answer 403, except against a hosted PROJECT, and the Agent API and Run task also run with only the stub engines. It also lets the UAG use its database (MONGO), on every edition.
LICENSE_REMOTEtrue when LICENSE_KEY is an offline license.
UAG_LICENSEDeprecated: use LICENSE_KEY. Still read until UAG 3.0.
PORTServer port. Default 3200.
PROJECT_RETRIESAttempts to load the project (the first try included), for a Form.io server that is still starting. Also used for each refresh and for finding remote engines. Default 5.
PROJECT_RETRY_DELAYMilliseconds before the first retry; the delay doubles on each attempt, up to 60 seconds. Default 5000.
PROJECT_TTLSeconds between project refreshes. Default 900; 0 disables refresh entirely. Values under 60 are not recommended — a refresh calls the project export API, which is expensive.
TEMPLATE_SYNCWhen a module's template is installed into the project: boot at startup (default), refresh also on every PROJECT_TTL refresh, or off never. Only what the project is missing is installed.
LOGIN_FORMURL of the login form JSON used by the browser login flow, so it must be reachable by that browser. Default {PROJECT}/user/login.
JWT_EXPIRE_TIMELifetime of the tokens the UAG issues, in minutes. Default 60.
PORTAL_SECRETEnterprise only. Lets a Form.io Enterprise portal stage connect to the UAG, where you add Run task actions to forms.
CORStrue (the default) allows every origin, false turns CORS off, and any other value is the allowed origin, such as https://app.example.com, or several separated by commas.
DEBUGDebug log filter, e.g. formio:*.
UAG_ENGINESComma-separated Agent API engine instances to enable, each <type> or <name>:<type>: jev, claude, openai, grok, gemini, remote (and stub-decision / stub-agent for testing). Unset enables none.
UAG_ENGINE_<NAME>_<SETTING>One instance's setting, such as UAG_ENGINE_FAST_MODEL. For a remote instance, _URL (the engine server) and _KEY (its key, at least 32 characters).
UAG_ENGINE_PATHAbsolute directories with more engine packages installed, such as a mounted volume.
AGENT_ANONYMOUS_RATE_LIMITAnonymous Agent API requests allowed per client address a minute, on forms that set uagAnonymous. Default 10; 0 turns anonymous use off.
AGENT_ANONYMOUS_TOTAL_RATE_LIMITAnonymous Agent API requests allowed in total a minute. Default 100; 0 turns anonymous use off.
TYPESAFE_API_KEYRequired for jev.
TYPESAFE_MODELJev model version. Default jev-1.13.0; keep it pinned.
TYPESAFE_BASE_URLTypeSafe API base URL. Default: the SDK's.
CLAUDE_API_KEYRequired for claude (ANTHROPIC_API_KEY also works).
CLAUDE_MODELDefault claude-opus-5-5.
CLAUDE_EFFORT / CLAUDE_RESEARCH_EFFORTEffort for extraction (default low) and for research with a task's read-only tools (default medium).
CLAUDE_FALLBACKSdefault re-runs a refused request on a fallback model server-side; off disables that.
NODE_TLS_REJECT_UNAUTHORIZEDSet to 0 only when PROJECT is an HTTPS URL with a self-signed or otherwise untrusted certificate, which is common for local and internal deployments. Never set it on a deployment reachable from outside your network — it disables certificate verification for all outbound requests.

To customize the image, mount a module⁠ at /app/module (forms, MCP tools, actions, settings), and folders of plugins⁠ under /app/plugins, each with an index.mjs (-v ./my-plugins:/app/plugins/my-plugins:ro; or name a file or folder with UAG_PLUGINS; off loads none), for converters and other plugins. Add-ons such as formio/uag-documents fill such a folder through a volume. Full list of variables: https://github.com/formio/uag/blob/main/demo/content/developers/deployment.md#environment-variables⁠.

Treat every key, secret, and license as sensitive: supply them through an .env file or your platform's secret store rather than inline in a committed file.

⁠Caching behaviour worth knowing

Forms and resources are cached and refreshed on the PROJECT_TTL interval, so a change to a form can take up to that long to appear to an agent. Set PROJECT_TTL=0 to disable refreshing entirely, in which case a restart is the only way to pick up changes.

Tag summary

Content type

Image

Digest

sha256:fdd8a9611…

Size

116.4 MB

Last updated

about 9 hours ago

docker pull formio/uag

This week's pulls

Pulls:

519

Last week