@formio/uag 1.13.2 → 2.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -535
- package/bin/uag-eval.js +95 -0
- package/bin/uag.js +73 -0
- package/lib/UAGFormInterface.d.ts +60 -2
- package/lib/UAGFormInterface.js +172 -46
- package/lib/UAGProjectInterface.d.ts +37 -5
- package/lib/UAGProjectInterface.js +166 -33
- package/lib/actionLogs.d.ts +33 -0
- package/lib/actionLogs.js +147 -0
- package/lib/actions/runTask.d.ts +43 -0
- package/lib/actions/runTask.js +323 -0
- package/lib/agent/anonymous.d.ts +34 -0
- package/lib/agent/anonymous.js +98 -0
- package/lib/agent/chat.d.ts +113 -0
- package/lib/agent/chat.js +539 -0
- package/lib/agent/engines.d.ts +13 -0
- package/lib/agent/engines.js +37 -0
- package/lib/agent/index.d.ts +4 -0
- package/lib/agent/index.js +18 -0
- package/lib/agent/remote.d.ts +67 -0
- package/lib/agent/remote.js +229 -0
- package/lib/agent/requestId.d.ts +4 -0
- package/lib/agent/requestId.js +19 -0
- package/lib/agent/router.d.ts +31 -0
- package/lib/agent/router.js +295 -0
- package/lib/agent/stubs.d.ts +26 -0
- package/lib/agent/stubs.js +26 -0
- package/lib/agent/tools.d.ts +10 -0
- package/lib/agent/tools.js +33 -0
- package/lib/config.d.ts +67 -0
- package/lib/config.js +19 -0
- package/lib/database.d.ts +75 -0
- package/lib/database.js +229 -0
- package/lib/formflow.d.ts +40 -0
- package/lib/formflow.js +28 -0
- package/lib/identity.d.ts +53 -0
- package/lib/identity.js +107 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.js +179 -7
- package/lib/router.js +15 -25
- package/lib/runner.d.ts +147 -0
- package/lib/runner.js +345 -0
- package/lib/runs.d.ts +89 -0
- package/lib/runs.js +74 -0
- package/lib/template.js +7 -9
- package/lib/templates/uagComponentNotFound.md +5 -5
- package/lib/tools/SchemaBuilder.d.ts +7 -2
- package/lib/tools/SchemaBuilder.js +11 -3
- package/lib/tools/agentDecide.d.ts +8 -0
- package/lib/tools/agentDecide.js +57 -0
- package/lib/tools/agentProvide.d.ts +13 -0
- package/lib/tools/agentProvide.js +130 -0
- package/lib/tools/collectData.js +1 -1
- package/lib/tools/confirmSubmission.js +1 -1
- package/lib/tools/fetchExternalData.js +8 -17
- package/lib/tools/findSubmission.js +62 -56
- package/lib/tools/getFieldInfo.js +1 -1
- package/lib/tools/getFormFields.js +1 -1
- package/lib/tools/getForms.js +1 -1
- package/lib/tools/index.d.ts +3 -1
- package/lib/tools/index.js +21 -14
- package/lib/tools/submissionUpdate.js +1 -1
- package/lib/tools/submitForm.js +1 -1
- package/package.json +41 -18
- package/lib/tools/agentProvideData.d.ts +0 -3
- package/lib/tools/agentProvideData.js +0 -62
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="./
|
|
2
|
+
<img src="./demo/public/images/logo-formio-uag.png" alt="The Form.io Universal Agent Gateway (UAG)" width="40%">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
@@ -9,632 +9,332 @@
|
|
|
9
9
|
<a href="./LICENSE.txt"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **Unstructured 'chat' input to deterministic form submission**: This capability uses the JSON schema of a Form.io form to produce a deterministic structured data object provided natural language conversational input.
|
|
20
|
-
|
|
21
|
-

|
|
22
|
-
|
|
23
|
-
For a working example of this flow, please try out the [Conversation Form Example](./examples/conversation-form).
|
|
24
|
-
|
|
25
|
-
- **Agentic Form.io Workflows**: UAG provides an AI Agent the ability to take existing submission data + "context" criteria in order to prompt an AI Agent to provide its own data and analysis within a workflow scenario. The following example, which shows a college application process using a Form.io application form, shows how this primary scenario works.
|
|
26
|
-
|
|
27
|
-

|
|
28
|
-
|
|
29
|
-
For more information on Agentic workflows, checkout the dedicated [Agentic Workflows](#agentic-workflows) section. For a working example of this flow, please try out the [Agentic Workflow Example](./examples/agentic-workflow).
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
One of the many benefits that the UAG has to offer is the ability to inject **Dynamic Context** into an AI processing cycle. This is achieved from the dynamic nature of the Form JSON schemas that can easily be modified and deployed to any environment without the need to update your application or re-train the agents within the process. Because of this, dynamic context changes can be injected seamlessly into an existing running process which will automatically update the behaviors of the Agents utilizing the UAG.
|
|
34
|
-
|
|
35
|
-
## Try it out!
|
|
36
|
-
There are three working examples in this repo, each spinning up a Form.io server alongside the UAG with Docker Compose. Pick the one that matches what you are building.
|
|
37
|
-
|
|
38
|
-
| Example | Pattern | Licensing |
|
|
39
|
-
|---------|---------|-----------|
|
|
40
|
-
| **[Custom Module](examples/custom-module)** | **Conversational, existing client.** Connect Claude Desktop to your forms and talk to them: "I would like to add a new customer." Built as a custom module, so roles and permissions decide what the agent may do. | Open Source — free |
|
|
41
|
-
| **[Conversation Form](examples/conversation-form)** | **Conversational, your own UI.** A chat application whose questions come entirely from a form. About 200 lines, no field names in the code — edit the form and the conversation changes. | Open Source — free |
|
|
42
|
-
| **[Agentic Workflow](examples/agentic-workflow)** | **Autonomous.** A submission triggers an agent that scores it against a rubric and writes its decision back, which in turn triggers a second agent. No human, no chat window. | Enterprise |
|
|
43
|
-
|
|
44
|
-
There is also a [Flow Viewer](examples/flow-viewer) — a small proxy that shows every leg of an agentic run live, which is the fastest way to see what an agent is actually doing.
|
|
45
|
-
|
|
46
|
-
## Documentation in this repository
|
|
47
|
-
|
|
48
|
-
This file is the main reference: what the UAG is, how to configure a form for it, how to deploy it, and how to troubleshoot it. The rest of the documentation lives next to the code it describes.
|
|
49
|
-
|
|
50
|
-
| Document | What it covers |
|
|
51
|
-
|----------|----------------|
|
|
52
|
-
| **README.md** (this file) | Concepts, [agentic workflow setup](#agentic-workflows), the [MCP tools](#pre-defined-mcp-tools-providing-dynamic-context), [deployment](#deploying-uag), [environment variables](#environment-variables), and [troubleshooting](#troubleshooting). |
|
|
53
|
-
| [module/Readme.md](./module/Readme.md) | Building a **custom module** — adding your own MCP tools, form actions, pre-defined forms and resources, and configuration overrides, then mounting it into the Docker container. |
|
|
54
|
-
| [integrations/claude/Readme.md](./integrations/claude/Readme.md) | The **Claude integration**: its API endpoints and commands, how to run it with Node or Docker, its environment variables, and how to trigger it from a Form.io Webhook action. |
|
|
55
|
-
| [examples/custom-module/Readme.md](./examples/custom-module/Readme.md) | Example — a custom module driven conversationally from **Claude Desktop**, where roles and permissions govern what the agent may do. |
|
|
56
|
-
| [examples/conversation-form/Readme.md](./examples/conversation-form/Readme.md) | Example — a **chat application of your own** whose questions come entirely from a form. |
|
|
57
|
-
| [examples/agentic-workflow/Readme.md](./examples/agentic-workflow/Readme.md) | Example — an **autonomous, webhook-triggered workflow** with two chained agent personas. |
|
|
58
|
-
| [examples/flow-viewer/Readme.md](./examples/flow-viewer/Readme.md) | A small proxy that shows **every leg of an agentic run live** — the token request, each tool call, and the write-back. The quickest way to see what an agent is doing. |
|
|
59
|
-
| [examples/custom-module/module/templates/Readme.md](./examples/custom-module/module/templates/Readme.md) | Overriding the **response templates** the UAG returns to the agent, using Lodash templates. |
|
|
60
|
-
| [test/e2e/Readme.md](./test/e2e/Readme.md) | The **end-to-end test suite** — its three layers, what each covers, and how to run it. |
|
|
61
|
-
|
|
62
|
-
---
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://ai.form.io/examples"><b>Live demos</b></a> ·
|
|
14
|
+
<a href="https://ai.form.io/developers"><b>Developer docs</b></a> ·
|
|
15
|
+
<a href="https://github.com/formio/ai"><b>Agentic Coding Plugin</b></a> ·
|
|
16
|
+
<a href="#quickstart">Quickstart</a> ·
|
|
17
|
+
<a href="#documentation">All documentation</a>
|
|
18
|
+
</p>
|
|
63
19
|
|
|
64
|
-
|
|
65
|
-
One of the more powerful features of the **UAG** is the `agent_provide_data` tool. This tool provides the ability to instruct a generically trained agent how to analyze existing submission data, and then produce its own data by following a configurable **Criteria**. This behavior historically could only be achieved using a specifically trained agent, which does not provide any benefits of dynamic configurability that the Form.io platform offers. This tool is able to achieve this goal by providing a generally trained agent with the necessary "context" it needs to accurately produce its own data as part of an automated workflow. This feature is particularly helpful if you wish to utilize the UAG within an Agentic Workflow, where the AI Agent is capable of understanding structured data, and then contribute its own data by following the configured **Criteria** "context" provided by the UAG.
|
|
20
|
+
The **Universal Agent Gateway (UAG)** is a server that lets AI agents work with your [Form.io](https://form.io) forms. It does for an agent what the [JavaScript renderer](https://github.com/formio/formio.js) does for a person: it turns Form JSON into something the agent can understand. Then it validates what the agent sends back with the form's own rules, and saves it with the user's own permissions.
|
|
66
21
|
|
|
67
|
-
|
|
22
|
+
The form is the contract. Add a field and agents ask for it; rewrite a task's instructions and the next submission is handled differently. Nothing is redeployed, no prompt changes, no model is retrained.
|
|
68
23
|
|
|
69
|
-
|
|
24
|
+
**Build it with your coding agent.** The [Form.io Agentic Coding Plugin](https://github.com/formio/ai) gives Claude Code, Cursor, Codex and other coding agents a `formio-uag` skill that tags your forms, designs their tasks, deploys the UAG and wires your application to it. Install it in your application's folder with `npx skills add formio/ai`.
|
|
70
25
|
|
|
71
|
-
|
|
26
|
+

|
|
72
27
|
|
|
73
|
-
|
|
74
|
-
- **Criteria**: This is a piece of content that provides the agent the **Criteria** to follow when analyzing the data, but also provides instructions on how the agent should populate the **Required Fields**.
|
|
75
|
-
- **Required Fields**: These are the form fields which the Agent is required to fill out as part of the `agent_provide_data` process.
|
|
28
|
+
## How it works
|
|
76
29
|
|
|
77
|
-
|
|
78
|
-
To configure a form to use the `agent_provide_data` tool, you must first designate a section of your form that will be read and used by the AI Agent. This is similar to what you would see in a form that says "For Office Use Only", but instead of a Human contributing to the values of this section, it will be an automated AI Agent. There are two types of fields that can be added to a form to configure it for use by the `agent_provide_data` tool: **Criteria** and **Agent Fields**
|
|
30
|
+

|
|
79
31
|
|
|
80
|
-
|
|
32
|
+
- **It sits in front of one Form.io project.** At startup the UAG reads the project's `/export` and registers every form tagged `uag`. It re-reads it every `PROJECT_TTL` seconds (default 900). A form without the tag is invisible to agents.
|
|
33
|
+
- **It has three entry points.** `/mcp` serves [MCP](https://modelcontextprotocol.io) tools to agents that bring their own model. `{form}/agent/*`, the **Agent API**, runs a form's tasks inside the UAG with the model **engines** you enable, and saves nothing. The project's own API is served too, so an application can use the UAG's URL as its project URL.
|
|
34
|
+
- **It forwards every submission to Form.io.** Form.io saves it and runs the form's own actions (Save Submission, Webhook, Email, Login, Role, Group). The UAG runs only its own actions, such as **Agent: Run task**, so nothing runs twice.
|
|
35
|
+
- **Every call has a Form.io identity.** A Form.io user token (`x-jwt-token`) is verified with Form.io and forwarded unchanged. MCP clients sign in through OAuth 2.0 with PKCE (`MCP_OAUTH`), and their roles and permissions decide what the agent may read and write for them. Servers using `client_credentials` or an API key act as the project administrator.
|
|
36
|
+
- **Every write goes through the form.** An MCP client's model writes only through tools such as `submit_completed_form`. Engines only answer, and are never given a write tool. The UAG validates every value with the form before it forwards the write.
|
|
81
37
|
|
|
82
|
-
|
|
83
|
-
2. Add the **Criteria** content component that teaches the agent what to do.
|
|
84
|
-
3. Add the **Agent Fields** the agent is allowed to fill.
|
|
85
|
-
4. Add a **Webhook action** to trigger the agent on submission — see the [Claude Integration](./integrations/claude/Readme.md#formio-webhook-setup). This step requires the Enterprise Server, because the action has to set a request header and transform its payload; on Community Edition, trigger the integration from your own code after creating the submission.
|
|
38
|
+

|
|
86
39
|
|
|
87
|
-
|
|
40
|
+
The UAG is built on Form.io's core logic. Every value an agent sends runs through the [`@formio/core`](https://github.com/formio/core) processors, the same validation, conditional and calculation rules Form.io itself applies, so the data it saves is valid and deterministic. More detail: [How the UAG works](https://ai.form.io/developers).
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
The UAG only registers forms that carry the `uag` tag. Any form without it is invisible to every agent and to every tool, including `get_forms`. In the Form Builder this is set under **Form Settings → Tags**; in a form's JSON it looks like this:
|
|
42
|
+
## Three ways to use it
|
|
91
43
|
|
|
92
|
-
|
|
93
|
-
"tags": ["uag"]
|
|
94
|
-
```
|
|
44
|
+

|
|
95
45
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
#### Agent "Criteria" component
|
|
99
|
-
The first thing that needs to be configured is a special **Content Component** that instructs the AI Agent how to interpret the data. For example, here is a Criteria content block that was written to instruct an AI Agent on how to assess the submission of a College Application Essay.
|
|
46
|
+
### Conversation forms
|
|
100
47
|
|
|
101
|
-
|
|
48
|
+
A person talks to Claude, ChatGPT or your own chat app, and the agent fills in a form for them. Build it with the [MCP tools](https://ai.form.io/developers/mcp-tools) or [Connect Claude](https://ai.form.io/developers/connect-claude), or embed a form as a chat in your own page with the [chat widget](https://ai.form.io/developers/chat): `Formio.createChat(element, formUrl)` from [`@formio/uag-js`](./packages/uag-js), with the UAG as the only backend. [Try it](https://ai.form.io/examples/conversation) · [source](./demo/public/apps/conversation/chat.js) · [prompt for your coding agent](https://github.com/formio/ai/blob/main/examples/agents/service-chat.md).
|
|
102
49
|
|
|
103
|
-
The
|
|
50
|
+

|
|
104
51
|
|
|
105
|
-

|
|
106
53
|
|
|
107
|
-
|
|
54
|
+
### Agentic workflows
|
|
108
55
|
|
|
109
|
-
|
|
110
|
-
Anywhere in your form, you can drag and drop fields that can be flagged as Agent fields. Using the example above, imagine your form has a "For Office Use Only" section (maybe a Panel). Within this panel, the first thing you see is a Content Component with instructions on how the following fields should be filled out. This is the `Criteria` we just described. The next thing that follows are the fields that the Agent needs to populate. Any field that with a property of `uag` set to the same value as the `Criteria` content component will be used as the Agent fields.
|
|
56
|
+
An application saves a submission through the UAG; an **Agent: Run task** action runs the form's task after the save and saves the result, which can start the next task. [Try it](https://ai.form.io/examples/workflow) · [source](./demo/server/workflow.mjs) · build it with [Workflows](https://ai.form.io/developers/workflows) · [prompt for your coding agent](https://github.com/formio/ai/blob/main/examples/agents/admissions-workflow.md).
|
|
111
57
|
|
|
112
|
-
|
|
58
|
+

|
|
113
59
|
|
|
114
|
-
|
|
60
|
+
### Agentic Formflow
|
|
115
61
|
|
|
116
|
-
|
|
62
|
+
A person describes what happened, and the form fills itself in: decisions choose the wizard's pages, extraction prefills the rest. [Try it](https://ai.form.io/examples/formflow) · [source](./demo/public/apps/formflow) · build it with the [Agent API](https://ai.form.io/developers/agent-api) and [`@formio/uag-js`](./packages/uag-js) · [prompt for your coding agent](https://github.com/formio/ai/blob/main/examples/agents/claim-formflow.md).
|
|
117
63
|
|
|
118
|
-

|
|
119
65
|
|
|
120
|
-
|
|
121
|
-
It is also possible to "flag" a collection of fields with the `uag` property. This can be done by wrapping all of these fields within a **Nested Component** (such as Panel, Container, Fieldset, etc), and then all the fields within this nested component will be added to the context of that agent with that persona.
|
|
66
|
+
One deployment can serve all three. Conversation forms run on Form.io Open Source with no license; the other two need a license or a hosted project (see [License](#license)). The whole demo site, with its forms and a flow viewer that shows every call the agents make, is in [`demo/`](./demo); these recordings are made from it by [`demo/recordings`](./demo/recordings).
|
|
122
67
|
|
|
123
|
-
|
|
124
|
-
It is also possible to achieve multiple personas per-form. This is very helpful if there are several isolated evaluations that need to occur within a process. For example, if we look at the flow chart diagram shown above, we can see a College Application Form. The first agentic evaluation occurs when the form is submitted by the applicant, where their application is assessed to be accepted or not. From that point, IF the applicant is accepted, a completely different evaluation needs to occur to award Financial Aid or even Scholarships to the applicant. These would require completely different criteria to assess the submission data differently from one another.
|
|
68
|
+
## Quickstart
|
|
125
69
|
|
|
126
|
-
|
|
70
|
+
Form.io Open Source and the UAG in one Compose stack. Replace every `CHANGEME`; `ADMIN_KEY` must match on both services.
|
|
127
71
|
|
|
128
|
-
|
|
72
|
+
```yaml
|
|
73
|
+
services:
|
|
74
|
+
mongo:
|
|
75
|
+
image: mongo:7
|
|
76
|
+
volumes: [mongo-data:/data/db]
|
|
129
77
|
|
|
130
|
-
|
|
131
|
-
|
|
78
|
+
formio: # Form.io Open Source, listening on 3001
|
|
79
|
+
image: formio/formio
|
|
80
|
+
depends_on: [mongo]
|
|
81
|
+
ports: ["3000:3001"]
|
|
82
|
+
environment:
|
|
83
|
+
NODE_CONFIG: '{"mongo": "mongodb://mongo:27017/formio-oss", "jwt": {"secret": "CHANGEME"}, "mongoSecret": "CHANGEME"}'
|
|
84
|
+
ROOT_EMAIL: admin@example.com
|
|
85
|
+
ROOT_PASSWORD: CHANGEME
|
|
86
|
+
ADMIN_KEY: CHANGEME
|
|
87
|
+
healthcheck:
|
|
88
|
+
test: ["CMD", "node", "-e", "fetch('http://localhost:3001/').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"]
|
|
89
|
+
interval: 5s
|
|
90
|
+
retries: 40
|
|
132
91
|
|
|
133
|
-
|
|
92
|
+
formio-uag:
|
|
93
|
+
image: formio/uag
|
|
94
|
+
depends_on:
|
|
95
|
+
formio: { condition: service_healthy }
|
|
96
|
+
ports: ["3200:3200"]
|
|
97
|
+
environment:
|
|
98
|
+
PROJECT: http://formio:3001 # how the UAG reaches Form.io
|
|
99
|
+
ADMIN_KEY: CHANGEME
|
|
100
|
+
JWT_SECRET: CHANGEME
|
|
101
|
+
LOGIN_FORM: http://localhost:3000/user/login
|
|
102
|
+
PROJECT_TTL: 10 # re-read the project every 10 s while you experiment
|
|
134
103
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"name": "webhook", "handler": ["after"], "method": ["update"], "priority": 0,
|
|
138
|
-
"condition": {
|
|
139
|
-
"conjunction": "all",
|
|
140
|
-
"conditions": [
|
|
141
|
-
{ "component": "status", "operator": "isEqual", "value": "scholarshipEvaluation" }
|
|
142
|
-
]
|
|
143
|
-
},
|
|
144
|
-
"settings": {
|
|
145
|
-
"method": "post",
|
|
146
|
-
"url": "http://formio-uag-claude:3300/agent/claude/agent_provide_data",
|
|
147
|
-
"headers": [{ "header": "x-token", "value": "<your project API key>" }],
|
|
148
|
-
"transform": "payload = {formName: 'application', submissionId: payload.submission._id, persona: 'finance'};",
|
|
149
|
-
"block": false
|
|
150
|
-
}
|
|
151
|
-
}
|
|
104
|
+
volumes:
|
|
105
|
+
mongo-data:
|
|
152
106
|
```
|
|
153
107
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
> **Avoid loops.** The second persona also writes to the submission, which fires the same `update` webhook again. Make sure each persona's own write cannot re-match the condition that triggered it — in the example above the finance persona sets `status` to `scholarshipGranted`, which no longer satisfies the condition, so the workflow terminates. A condition that stays true after the persona runs will loop indefinitely and consume API credits until you stop the container.
|
|
157
|
-
|
|
158
|
-
A complete, runnable version of this two-persona workflow is in the [Agentic Workflow example](./examples/agentic-workflow).
|
|
159
|
-
|
|
160
|
-
## Integrations
|
|
161
|
-
In order to aid in the "agentification" of the UAG, we have also provided some "integrations" that can be used to directly communicate with the Generically trained AI Agents to utilize the UAG to accomplish automated AI Agent behaviors. This involves providing a single API endpoint that is capable of triggering the AI Agent process along with the connections to your deployed UAG. These API endpoints can then be triggered using a simple Webhook action within a form to start an Agentic process as the result of a Form submission. Here is a diagram of how specific integrations can be used to achieve a single API call to accomplish an agentic task.
|
|
162
|
-
|
|
163
|
-

|
|
164
|
-
|
|
165
|
-
Each integration runs its own MCP client and connects *out* to the UAG, so the UAG does not need to be publicly accessible for these to work — it only needs to be reachable from the integration, such as over a private Docker network or on `localhost`.
|
|
166
|
-
|
|
167
|
-
These integrations can be found within the **integrations** folder. The following **integrations** are provided to enable automated Agentic workflows.
|
|
168
|
-
|
|
169
|
-
- [Claude Integration](./integrations/claude)
|
|
170
|
-
|
|
171
|
-
Please click on one of these integration links to read how they work.
|
|
172
|
-
|
|
173
|
-
### Integration Version Compatibility
|
|
174
|
-
|
|
175
|
-
Integrations are **versioned independently of the UAG**. They share no code with it — each one runs its own MCP client and talks to the UAG over MCP/HTTP — so an integration release does not imply a UAG release, and vice versa. Matching version numbers between the two would be misleading rather than helpful.
|
|
176
|
-
|
|
177
|
-
Use this matrix to pick a compatible pair. Each row records the UAG range an integration version is known to work against:
|
|
178
|
-
|
|
179
|
-
| Integration | Version | Compatible UAG versions | Notes |
|
|
180
|
-
| ----------- | ------- | ----------------------- | ----- |
|
|
181
|
-
| `@formio/uag-claude` | 1.3.x | >= 1.12.0 | Current. |
|
|
182
|
-
| `@formio/uag-claude` | 1.2.x | 1.10.0 – 1.11.x | |
|
|
183
|
-
|
|
184
|
-
Both artifacts are published on every release where their own version changed:
|
|
185
|
-
|
|
186
|
-
- npm: [`@formio/uag`](https://www.npmjs.com/package/@formio/uag), [`@formio/uag-claude`](https://www.npmjs.com/package/@formio/uag-claude)
|
|
187
|
-
- Docker Hub: [`formio/uag`](https://hub.docker.com/r/formio/uag), [`formio/uag-claude`](https://hub.docker.com/r/formio/uag-claude)
|
|
188
|
-
|
|
189
|
-
**When adding a row:** bump the integration's own `package.json` version. CI publishes it to npm and Docker Hub on the next release tag, and skips it automatically when that version is already published — so a core-only release does not rebuild an unchanged integration.
|
|
190
|
-
|
|
191
|
-
The `examples/` compose files reference `formio/uag` and `formio/uag-claude` without a tag, so they always pull the current release and cannot drift out of date. If you need a reproducible stack, pin both images to a compatible pair from the matrix above.
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Technical Overview
|
|
196
|
-
The UAG can be thought of as consisting of many layers of functionality. Each layer is broadly either serving to fetch dynamic context, or submit deterministic data structures. The following layers are leveraged within the UAG:
|
|
197
|
-
|
|
198
|
-
1. **MCP Interface**: The entry point of the UAG is the MCP interface that sits between the AI agent and the tools that are executed on the server.
|
|
199
|
-
2. **Authorization**: As part of the MCP specification, every interaction between the AI agent and the backend service must pass through an Authorization process leveraging OIDC (PKCE) authentication. The UAG takes this process one step further, however, by adding an OIDC (PKCE) authentication layer on top of the existing authentication flexibilities that Form.io already provides. Because of this, it is possible to authenticate with the UAG if you are using SAML, Form.io Authentication, OIDC, or even Custom Authentication processes through the Form.io platform.
|
|
200
|
-
3. [**Pre-defined MCP Tools providing Dynamic Context**](#pre-defined-mcp-tools-providing-dynamic-context): The UAG utilizes the MCP to provide a number of pre-defined tools that provide AI agents with dynamic context based on the Forms and Resources marked as compatible within the Form.io platform. These tools are described in more detail in a section below.
|
|
201
|
-
4. **Custom Tools** (provided by [Custom Modules](#custom-modules)): This enables developers to introduce any new tools that can leverage Form.io forms and submission data structures to provide additional capabilities introduced to the AI agents. This would allow for custom agent interactions to achieve certain goals for specific use cases.
|
|
202
|
-
5. **Custom Actions** (provided by [Custom Modules](#custom-modules)): Enables developers to create composable middleware that will be executed once all data provided by the AI agent has been sanitized and validated. This provides the ability to interface the data collected from AI agents with any backend system or workflow.
|
|
203
|
-
6. **Built-in Actions**: In addition to any custom actions introduced via a Module, the UAG supports a handful of existing Actions that can be assigned to any form or resource. Actions such as the **Webhook** that will send a REST API call to any endpoint once any submission has been made by an AI agent. This can be used to point to any serverless function to instigate backend workflows that are triggered from the interactions from AI agents.
|
|
204
|
-
7. **Pre-defined Forms and Resources** (provided by [Custom Modules](#custom-modules)): Allows a developer to release a module that provides default data structures to the AI agent. This would be useful if a developer wishes to create a module that achieves a specific goal, where the data structures required for that goal need to follow a pre-determined set of fields provided by a form or resource. For example, if a developer wishes to release a CRM module for the UAG, then it would make sense that the module would also provide the default **Customer** and **Company** resources that commonly accompany most CRM implementations.
|
|
205
|
-
8. **Custom Database** (provided by [Custom Module](#custom-modules)): By default, the UAG performs the data collection and retrieval via a "Submission Proxy", whereas the data is submitted via REST API to either the Enterprise Server project or the Open Source server. This, however, could be modified to send the data directly to and from a Database. This can be achieved via the Database Interface provided from the UAG. For more information, see the **Module** documentation. This feature does require that the UAG is connected to the Enterprise Server.
|
|
206
|
-
|
|
207
|
-
Here is a diagram to understand how all of these layers are organized to make up the UAG.
|
|
108
|
+
```bash
|
|
109
|
+
docker compose up -d
|
|
208
110
|
|
|
209
|
-
|
|
111
|
+
# Get a token, then list the MCP tools.
|
|
112
|
+
TOKEN=$(curl -s -X POST http://localhost:3200/auth/token -H 'Content-Type: application/json' \
|
|
113
|
+
-d '{"grant_type":"client_credentials","client_id":"formio-oss-x-admin-key","client_secret":"CHANGEME"}' \
|
|
114
|
+
| node -pe 'JSON.parse(require("fs").readFileSync(0)).access_token')
|
|
210
115
|
|
|
211
|
-
|
|
212
|
-
|
|
116
|
+
curl -s -X POST http://localhost:3200/mcp -H "Authorization: Bearer $TOKEN" \
|
|
117
|
+
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
|
|
118
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
|
119
|
+
```
|
|
213
120
|
|
|
214
|
-
|
|
215
|
-
|-----------------|----------------------|
|
|
216
|
-
| get_forms | Provides the AI agent with a list of available forms. <br/>It will only return forms that have been tagged `uag`. |
|
|
217
|
-
| get_form_fields | When the AI agent infers the user intends to use a specific form, this tool provides the agent with a high level overview of all the fields needed (along with the field data path) to submit that form. |
|
|
218
|
-
| get_field_info | Once the fields have been determined using `get_form_fields`, this tool provides specific information about the requested fields, such as validation, conditionals, input formats, etc. <br/>This tool instructs the AI agent on how to format and structure the data that is sent to the MCP server. |
|
|
219
|
-
| collect_field_data | Provides the AI agent with a mechanism to dynamically collect the required information from the user. It can parse the user's input into multiple fields at once, and will identify additional inputs from the user if needed. <br/>This tool supports complex and structured data collection and is compatible with nested or multi-value fields like nested forms, data grids, etc. |
|
|
220
|
-
| confirm_form_submission | This tool is used to provide a summary of all data collected before a submission is made to the form. |
|
|
221
|
-
| submit_completed_form | Provides the AI agent with the ability to submit all of the data collected from the user to create the form submission. |
|
|
222
|
-
| find_submissions | Enables the agent to parse a user's natural language request into a query for a submission, or a specific field of a particular submission. |
|
|
223
|
-
| submission_update | Provides the AI agent with the ability to update an existing submission, either by supplying unfilled fields or updating existing ones if allowed. Provides the AI agent with the context of the existing field values, allowing inline changes or edits. |
|
|
224
|
-
| agent_provide_data | Enables an AI Agent to be able to analyze existing submission data according to rules defined with a configurable **Criteria**. It will then instruct the Agent to provide generated data for fields configured for a specific **persona** using the `submission_update` tool. Please read the [**Agentic Workflows**](#agentic-workflows) section for more information about this toolset. |
|
|
225
|
-
| fetch_external_data | This tool enables an AI Agent to pull external data into a form workflow through the use of either a Resource component, Select with URL, or a Data Source component. |
|
|
121
|
+
Then tag a form `uag` (in the portal, **Form Settings → Tags**) and connect an agent. The [Quickstart](https://ai.form.io/developers/quickstart) covers a hosted Form.io project, a first tool call and the Agent API, and [Connect Claude](https://ai.form.io/developers/connect-claude) connects Claude Desktop or claude.ai. Or have your coding agent do all of it with the [Agentic Coding Plugin](https://github.com/formio/ai).
|
|
226
122
|
|
|
227
|
-
###
|
|
228
|
-
While the UAG can be used as a stand-alone system to enable the interaction between AI agents and dynamic JSON forms, the true power of this platform will be realized when developers extend the capabilities of this platform to solve industry specific use cases through the use of Custom Modules and Tools. It is possible for a developer to create a **Module** that introduces a number of custom tools, actions, and pre-defined resources and forms to achieve interactions with industry specific technologies. They are able to achieve this custom integration capabilities through the use of the following mechanisms:
|
|
123
|
+
### Run the whole demo locally
|
|
229
124
|
|
|
230
|
-
|
|
231
|
-
For example, imagine a module includes a Customer resource with "First Name", "Last Name", and "Email" fields. If you then simply ask an AI agent, "I would like to add a new Customer" the agent will automatically be aware of the context for the customer data structures and know exactly what your intent is when making that request.
|
|
232
|
-
2. **Custom Actions**: Actions can be thought of as composable middleware functions that allow for configurable Express.js middleware functions to be attached to any Form and Resource, and then to be executed once the data being submitted by an AI agent has passed through the proper data validations and sanitization. These can be used to provide custom integrations to backend processes and workflows.
|
|
233
|
-
3. **Custom Tools**: In addition to providing custom actions, a Module can also introduce custom MCP Tools to provide bespoke interaction capabilities between the UAG and the AI agents for any industry specific purposes.
|
|
234
|
-
4. **Custom Authentication**: A module can also modify the "authentication" landing page to assist with any custom requirements that are needed around Authentication.
|
|
235
|
-
5. **Behavior Overrides**: A module also has the ability to "override" any default behavior from the UAG. This ensures that whomever is using a certain module can "tweak" certain tools and responses to achieve better results as it pertains to their industry specific needs.
|
|
125
|
+
With Docker, a Form.io Enterprise license and a license that includes the UAG, one command runs the demo site with all three examples, Form.io Enterprise and its portal, and the UAG built from this checkout:
|
|
236
126
|
|
|
237
|
-
|
|
127
|
+
```bash
|
|
128
|
+
yarn install
|
|
129
|
+
yarn demo:start 3430 # the site on :3430, Form.io and its portal on :3431, the UAG on :3432
|
|
130
|
+
```
|
|
238
131
|
|
|
239
|
-
|
|
240
|
-
Once a custom module is developed, anyone can install that module (via NPM) and then easily use your module in the following way...
|
|
132
|
+
It creates the demo project and its forms itself, and prints where everything is and how to sign in to the portal. It reads `LICENSE_KEY` and your model keys from the root `.env`; the portal password and the other secrets come from there too when you set them, and are random otherwise. See [the demo's README](./demo/README.md#the-whole-demo-on-your-machine-self-hosted-yarn-demostart-port).
|
|
241
133
|
|
|
242
|
-
|
|
243
|
-
```js
|
|
244
|
-
import { UAGServer } from '@formio/uag';
|
|
245
|
-
import { ExampleUAG } from '@example/uag';
|
|
246
|
-
import Express from 'express';
|
|
247
|
-
try {
|
|
248
|
-
(async function () {
|
|
249
|
-
const server = new UAGServer();
|
|
250
|
-
server.use(ExampleUAG);
|
|
251
|
-
const app = Express();
|
|
252
|
-
app.use(await server.router());
|
|
253
|
-
const port = process.env.PORT || 3200;
|
|
254
|
-
app.listen(port, () => {
|
|
255
|
-
console.log(`Form.io UAG server running on port ${port}`);
|
|
256
|
-
console.log(`Visit http://localhost:${port} to access the application`);
|
|
257
|
-
});
|
|
258
|
-
})();
|
|
259
|
-
} catch (error) {
|
|
260
|
-
console.error('Failed to start server:', error);
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
```
|
|
134
|
+
## Tasks
|
|
264
135
|
|
|
265
|
-
|
|
136
|
+
A **task** teaches an agent to fill part of a form, with instructions written in the form itself. It is defined entirely by custom properties on components (**API → Custom Properties** in the form builder), and a form can have several.
|
|
266
137
|
|
|
267
|
-
|
|
268
|
-
The following sections describe the process of creating a running instance of UAG, connecting it to the Form.io Platform, and configuring an AI agent to use it.
|
|
138
|
+

|
|
269
139
|
|
|
270
|
-
|
|
140
|
+
| Property | On | Meaning |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| `uag: <task>` | Any field, or a panel, container or fieldset | The field belongs to the task. On a container, every field inside it does too, except fields in data grids and edit grids. |
|
|
143
|
+
| `uagField: criteria` | A content component with `uag: <task>` | The task's instructions. Write them like a brief for a new employee, including the role the agent acts in, exact option values and formats. |
|
|
144
|
+
| `uagField: input` | A field with `uag: <task>` | The text the task reads. Without one, the task reads the submission, except its own fields; `{form}/agent/extract` then needs `text`. |
|
|
145
|
+
| `uagContext`, `uagTools` | The criteria component | Extra data paths sent to the engines; read-only MCP tools the agent may research with. |
|
|
146
|
+
| `uagEngine` | A task field, or the criteria component | Which engine answers that field, or the whole task. |
|
|
147
|
+
| `uagThreshold`, `uagAuthoritative`, … | A task field | How confident a decision must be; whether the server owns the value, so no client can set it. |
|
|
271
148
|
|
|
272
|
-
|
|
273
|
-
Before deploying, it is worth deciding **which side opens the connection** to the UAG's `/mcp` endpoint, because that single decision determines whether the UAG needs to be publicly accessible.
|
|
149
|
+
Every property, with its default: [Form properties](https://ai.form.io/developers/form-properties). How tasks, decision fields and value fields work: [Concepts](https://ai.form.io/developers/concepts).
|
|
274
150
|
|
|
275
|
-
|
|
276
|
-
|------------------|-------------------------|------------------------------------|
|
|
277
|
-
| **Local MCP client** | Your own application or integration, running alongside the UAG | **No.** The UAG only needs to be reachable from that process — `http://localhost:3200` or a private Docker network address is fine. |
|
|
278
|
-
| **Remote MCP client** | A hosted agent that dials into your UAG (Claude.ai and Claude Desktop connectors, the Anthropic MCP connector, or any other remote MCP host) | **Yes.** The agent must be able to reach `/mcp` and the OAuth discovery endpoints over the public internet. |
|
|
151
|
+
> **No form, no error.** A form missing the `uag` tag simply is not there for agents, and a new tag or criteria edit reaches them after the next `PROJECT_TTL` refresh. Restart the UAG to pick changes up at once.
|
|
279
152
|
|
|
280
|
-
|
|
153
|
+
## Agentic workflows
|
|
281
154
|
|
|
282
|
-
|
|
155
|
+
A workflow is a task that the **Agent: Run task** action runs on a submission the UAG receives. The demo's college application runs two tasks, and the second is started by the first one's save:
|
|
283
156
|
|
|
284
|
-
|
|
157
|
+

|
|
285
158
|
|
|
286
|
-
|
|
159
|
+
To set one up on **Form.io Enterprise**:
|
|
287
160
|
|
|
288
|
-
|
|
289
|
-
|
|
161
|
+
1. **Connect a portal stage to the UAG.** Set `PORTAL_SECRET` on the UAG, then in the portal connect a stage to it as an on-premise environment. In that stage the portal lists the UAG's own actions next to Form.io's. See [Deployment → Connecting the Enterprise portal](https://ai.form.io/developers/deployment#connecting-the-enterprise-portal).
|
|
162
|
+
2. **Add "Agent: Run task" to the form.** Choose the **Task**, what to **Answer** (the whole task, or its decision fields only) and **When** (after the save, in the background, or before it, while the submitter waits), with Form.io's usual methods and conditions. Mark the fields the agent owns `uagAuthoritative`, so no client can set them.
|
|
163
|
+
3. **Point the application at the UAG.** Use the UAG's URL as the project URL in the renderer or your API calls. Login and registration are forwarded to Form.io, and its tokens work unchanged.
|
|
290
164
|
|
|
291
|
-
|
|
165
|
+
On **Form.io Open Source**, which has no portal stages, add the same action with Form.io's action API (`POST /form/{formId}/action`) or in a module's project template, and point the application at the UAG. Run task is Agentic Formflow, so it needs a license that includes the UAG, or a project on Form.io's hosted service.
|
|
292
166
|
|
|
293
|
-
|
|
294
|
-
POST /auth/token
|
|
295
|
-
Content-Type: application/json
|
|
167
|
+
The demo's second action, from [`demo/module/project.json`](./demo/module/project.json):
|
|
296
168
|
|
|
169
|
+
```json
|
|
297
170
|
{
|
|
298
|
-
"
|
|
299
|
-
"
|
|
300
|
-
"
|
|
171
|
+
"title": "Agent: Run task (finance)", "name": "agentRunTask",
|
|
172
|
+
"handler": ["before", "after"], "method": ["update"],
|
|
173
|
+
"condition": {
|
|
174
|
+
"conjunction": "all",
|
|
175
|
+
"conditions": [
|
|
176
|
+
{ "component": "status", "operator": "isEqual", "value": "scholarshipEvaluation" },
|
|
177
|
+
{ "component": "awardLevel", "operator": "isEmpty" }
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"settings": { "task": "finance", "answer": "task", "when": "after" }
|
|
301
181
|
}
|
|
302
182
|
```
|
|
303
183
|
|
|
304
|
-
|
|
184
|
+
What one run after the save does:
|
|
305
185
|
|
|
306
|
-
|
|
186
|
+

|
|
307
187
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
188
|
+
- **Tasks run only for submissions sent to the UAG.** A submission sent straight to Form.io runs no task.
|
|
189
|
+
- **After the save, the submitter does not wait.** The task's results are saved as an update through the UAG, so the form's update actions, including other Run task actions, run on it. A run that changes nothing saves nothing.
|
|
190
|
+
- **Guard update actions with a condition on a field the task sets**, as above. Check operator names: Form.io treats a clause with an unknown operator as always true.
|
|
191
|
+
- **Who the agent acts as.** With no **Agent role**, the task saves with the credential the submission was sent with. With one, and the same `JWT_SECRET` as Form.io Enterprise, the UAG acts for the user with that role, so Form.io's permissions keep users off the agent's fields. See [Project setup for agents](https://ai.form.io/developers/project-setup).
|
|
312
192
|
|
|
193
|
+
Full guide: [Workflows](https://ai.form.io/developers/workflows).
|
|
313
194
|
|
|
314
|
-
|
|
315
|
-
Running the UAG in Docker enables a wide range of deployment options into common hosting environments such as AWS and Azure. Additionally, it allows for the use of common orchestration runtimes such as Kubernetes and Docker Compose. The container that you will run the UAG is as follows:
|
|
195
|
+
## Agent API
|
|
316
196
|
|
|
317
|
-
|
|
318
|
-
formio/uag
|
|
319
|
-
```
|
|
197
|
+
The Agent API runs a form's tasks inside the UAG and returns validated values. It reads no stored submission and saves nothing; saving is the job of submissions sent to the UAG. Applications call the same endpoints whichever models are behind them.
|
|
320
198
|
|
|
321
|
-
|
|
322
|
-
- [**Docker-Compose.yml**](#docker-compose-recommended) - The recommended method, deploys as a multi-container Docker Compose stack.
|
|
323
|
-
- [**Docker Run**](#docker-run) - a standalone container using the common `docker run` command.
|
|
199
|
+
A form's operations are under the form's URL on the UAG, `{form}`: the form's path, or `form/{formId}`, under the project's URL on the UAG (the UAG's root on Form.io Open Source; `/{projectName}` or `/project/{projectId}` on Enterprise and the hosted service).
|
|
324
200
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
mongo:
|
|
333
|
-
image: mongo
|
|
334
|
-
restart: always
|
|
335
|
-
volumes:
|
|
336
|
-
- ./data/db:/data/db
|
|
337
|
-
environment:
|
|
338
|
-
- MONGO_INITDB_ROOT_USERNAME
|
|
339
|
-
- MONGO_INITDB_ROOT_PASSWORD
|
|
340
|
-
formio:
|
|
341
|
-
image: formio/formio:rc
|
|
342
|
-
restart: always
|
|
343
|
-
links:
|
|
344
|
-
- mongo
|
|
345
|
-
depends_on:
|
|
346
|
-
- mongo
|
|
347
|
-
environment:
|
|
348
|
-
PORT: 3000
|
|
349
|
-
DEBUG: formio.*
|
|
350
|
-
NODE_CONFIG: '{"mongo": "mongodb://mongo:27017/formio-oss", "jwt": {"secret": "CHANGEME"}, "mongoSecret": "CHANGEME"}'
|
|
351
|
-
ROOT_EMAIL: admin@example.com
|
|
352
|
-
ROOT_PASSWORD: CHANGEME
|
|
353
|
-
ADMIN_KEY: CHANGEME
|
|
354
|
-
ports:
|
|
355
|
-
- "3000:3000"
|
|
356
|
-
formio-uag:
|
|
357
|
-
image: formio/uag
|
|
358
|
-
restart: always
|
|
359
|
-
links:
|
|
360
|
-
- formio
|
|
361
|
-
depends_on:
|
|
362
|
-
- formio
|
|
363
|
-
environment:
|
|
364
|
-
PORT: 3200
|
|
365
|
-
DEBUG: formio.*
|
|
366
|
-
PROJECT: http://formio:3000
|
|
367
|
-
ADMIN_KEY: CHANGEME
|
|
368
|
-
JWT_SECRET: CHANGEME
|
|
369
|
-
JWT_EXPIRE_TIME: 525600
|
|
370
|
-
LOGIN_FORM: http://localhost:3000/user/login
|
|
371
|
-
# The address clients reach the UAG at — this is the UAG's own port,
|
|
372
|
-
# not the Form.io server's. See the BASE_URL section below.
|
|
373
|
-
BASE_URL: http://localhost:3200
|
|
374
|
-
ports:
|
|
375
|
-
- "3200:3200"
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
This can be run by typing the following...
|
|
379
|
-
|
|
380
|
-
```
|
|
381
|
-
docker compose up -d
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
#### Docker Run
|
|
385
|
-
Here are some examples of running the UAG using the ```docker run``` command.
|
|
386
|
-
|
|
387
|
-
**UAG pointed to an Open Source server**
|
|
388
|
-
```
|
|
389
|
-
docker run -d \
|
|
390
|
-
-e "PROJECT=https://forms.mysite.com" \
|
|
391
|
-
-e "ADMIN_KEY=CHANGEME" \
|
|
392
|
-
-e "JWT_SECRET=CHANGEME" \
|
|
393
|
-
-e "BASE_URL=https://forms.mysite.com" \
|
|
394
|
-
-e "LOGIN_FORM=https://forms.mysite.com/user/login" \
|
|
395
|
-
-e "PORT=3200" \
|
|
396
|
-
--restart unless-stopped \
|
|
397
|
-
--network formio \
|
|
398
|
-
--name formio-uag \
|
|
399
|
-
-p 3200:3200 \
|
|
400
|
-
formio/uag
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
**UAG pointed to a Form.io Enterprise Server**
|
|
404
|
-
```
|
|
405
|
-
docker run -d \
|
|
406
|
-
-e "PROJECT=https://forms.mysite.com/myproject" \
|
|
407
|
-
-e "PROJECT_KEY=CHANGEME" \
|
|
408
|
-
-e "UAG_LICENSE=YOUR-LICENSE" \
|
|
409
|
-
-e "JWT_SECRET=CHANGEME" \
|
|
410
|
-
-e "PORTAL_SECRET=CHANGEME" \
|
|
411
|
-
-e "BASE_URL=https://forms.mysite.com" \
|
|
412
|
-
-e "LOGIN_FORM=https://forms.mysite.com/myproject/user/login" \
|
|
413
|
-
-e "PORT=3200" \
|
|
414
|
-
--restart unless-stopped \
|
|
415
|
-
--network formio \
|
|
416
|
-
--name formio-uag \
|
|
417
|
-
-p 3200:3200 \
|
|
418
|
-
formio/uag
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
Once it is running, you can then navigate to the following to access both the OSS Deployment + UAG Server
|
|
422
|
-
- http://localhost:3000: The Form.io OSS Server
|
|
423
|
-
- http://localhost:3200: The UAG Server
|
|
424
|
-
|
|
425
|
-
In both the Node.js runtime environment as well as Docker, the way to control the UAG is through the use of **Environment Variables** and **Modules**.
|
|
426
|
-
|
|
427
|
-
### Environment Variables
|
|
428
|
-
This module can be configured in many ways. One of those ways is through the use of Environment Variables, which are documented as follows.
|
|
429
|
-
|
|
430
|
-
| Variable | Description | Example |
|
|
431
|
-
|----------|-------------|---------|
|
|
432
|
-
| PROJECT | **Required.** The API Endpoint to either an Enterprise project endpoint, or the OSS server url. | http://localhost:3000 |
|
|
433
|
-
| PROJECT_KEY | (Enterprise Only) The API Key of the project this UAG is bound to, found in **Project Settings → API Keys**. Open Source deployments use `ADMIN_KEY` instead. | CHANGEME |
|
|
434
|
-
| ADMIN_KEY | (Open Source Only) Allows you to provide the ADMIN_KEY to install and connect to the OSS Server. | CHANGEME |
|
|
435
|
-
| UAG_LICENSE | The license to run the UAG against a Form.io Enterprise Deployment. | |
|
|
436
|
-
| PROJECT_TTL | The project cache TTL in seconds. This controls the amount of time to check for any "changes" that have been made to the project to refresh any forms and resources within the UAG. | 900 |
|
|
437
|
-
| PORT | The port you wish to run the server on. | 3200 |
|
|
438
|
-
| DEBUG | Variable used to perform debug logs of server activity | formio.* |
|
|
439
|
-
| PORTAL_SECRET | Enterprise Only: Allows you to connect to the UAG from the Form.io Enterprise Portal. | CHANGEME |
|
|
440
|
-
| JWT_SECRET | **Required.** A secret used to generate and validate JWT tokens generated through the authentication process of the UAG. This does not need to match the JWT_SECRET of the Enterprise Server that it is connected to. | CHANGEME |
|
|
441
|
-
| JWT_EXPIRE_TIME | The expiration for the jwt secret. | 3600 |
|
|
442
|
-
| MONGO | (Enterprise Only) Allows you to connect the UAG directly to a mongo database, rather than having to redirect the submissions to the Form.io Submission APIs. | |
|
|
443
|
-
| MONGO_CONFIG | JSON configuration for the Node.js Mongo Driver. | |
|
|
444
|
-
| BASE_URL | **Required.** The URL that the UAG is reachable at *by its clients*. It is published in the `.well-known` OIDC (PKCE) definitions and used for authentication callbacks. This must be a public URL when remote agents connect in; for a local MCP client, a private or localhost URL is fine. | https://forms.yoursite.com |
|
|
445
|
-
| LOGIN_FORM | The URL to the Login Form JSON endpoint, loaded by the `/auth/authorize` page. Only used by the browser-based login flow, so it must be reachable by that browser. | https://mysite.com/project/user/login |
|
|
446
|
-
| CORS | The cors domain, or the JSON configuration to configure the "cors" node.js module cross domain resource sharing. | *.* |
|
|
447
|
-
| NODE_TLS_REJECT_UNAUTHORIZED | Standard Node.js variable. Set to `0` when `PROJECT` is an `https` URL secured by a self-signed or otherwise untrusted certificate, which is common for local and internal deployments — without it the UAG cannot connect to the server and every tool call fails. Never set this on a deployment reachable from outside your network, since it disables certificate verification for all outbound requests. | 0 |
|
|
448
|
-
|
|
449
|
-
### Project Cache and TTL
|
|
450
|
-
By default, the UAG uses a TTL to "fetch" any of the project assets and register them and cache them into the UAG. What this means is that if you make any changes to your underlying project forms and resources (either directly or through a deployment), you need to wait a maximum of the TTL setting (in seconds) to see any updates that have been made. For example, if the TTL is set to 900 (or 15 minutes), and you make a change to any forms and resources, you must wait at most 15 minutes to see any of these changes take effect into the UAG. It should be noted that when a "refresh" occurs, an API call to the "export" method is called on the underlying project endpoint. This is a processor intensive API call, so it is not recommended to set the TTL to any value less than 60. A value of 0 is interpreted as "No TTL", which means the only way to refresh the project forms and resources, a UAG reboot is necessary.
|
|
451
|
-
|
|
452
|
-
Here is a table explaining how this parameter can be used.
|
|
453
|
-
|
|
454
|
-
| Environment Variable | Value | Result |
|
|
455
|
-
|----------|-------------|---------|
|
|
456
|
-
| PROJECT_TTL | 0 | No TTL (refresh) will occur. This can be used to "disable" any refresh and ensure the ONLY way to refetch updated forms and resources, you must reboot the UAG server. |
|
|
457
|
-
| PROJECT_TTL | 60 | Check for changes every minute |
|
|
458
|
-
| PROJECT_TTL | 3600 | Check for changes every hour |
|
|
459
|
-
|
|
460
|
-
This cache is the reason a form edit does not appear to take effect immediately. Anything that changes what the agent knows — adding the `uag` tag, rewriting a **Criteria** content component, adding or removing **Agent Fields** — only reaches the agent after the next expiry. When you are actively iterating on criteria, restarting the UAG re-registers the project immediately instead of waiting:
|
|
201
|
+
| Endpoint | Does | Saves |
|
|
202
|
+
|---|---|---|
|
|
203
|
+
| `POST {form}/agent/extract` | Fills a task's fields from free text (`text`, or the task's input field in `data`). Streams results with `Accept: text/event-stream`, each engine group as it finishes, so fast decisions usually come first. | No |
|
|
204
|
+
| `POST {form}/agent/decide` | Answers a task's closed-set fields from `data`, with a calibrated confidence when a decision engine answers. | No |
|
|
205
|
+
| `POST {form}/agent/generate` | Writes a task's open values (dates, amounts, text) from `data`. | No |
|
|
206
|
+
| `POST {form}/agent/chat` | One turn of a conversation that fills the form in: the next message, and the values taken from the person's words, checked against the form. What the [chat widget](https://ai.form.io/developers/chat) calls. Conversation forms: no Agentic Formflow license. | No |
|
|
207
|
+
| `GET /agent/capabilities` (at the UAG's root) | Lists the enabled engines, the operations they serve, the edition, the license state, and whether durable runs (`durableRuns`) and remote MCP sign-in (`mcpOAuth`) are available. | No |
|
|
461
208
|
|
|
462
209
|
```bash
|
|
463
|
-
|
|
210
|
+
curl -s -X POST https://uag.example.com/claim/agent/extract \
|
|
211
|
+
-H "x-jwt-token: $FORMIO_TOKEN" -H 'Content-Type: application/json' \
|
|
212
|
+
-d '{"task": "triage", "text": "I rear-ended a car at the light on Main St yesterday around 5pm."}'
|
|
464
213
|
```
|
|
465
214
|
|
|
466
|
-
|
|
467
|
-
There are 3 different "domain" environment variables that matter, and it is important to understand how to configure them depending on your use case. Whether any of them need to be *public* depends on how agents connect — see [How Agents Connect](#how-agents-connect).
|
|
215
|
+
Each field comes back with its `value`, a `status` (`confident`, `uncertain`, `suggested` or `missing`), the engine and model that answered, and a `confidence` where the engine gives one. Values are only answered for empty fields unless `overwrite` is `true`.
|
|
468
216
|
|
|
469
|
-
|
|
217
|
+
The operations take the same credentials as the form's submissions: the signed-in user's Form.io token (`x-jwt-token`), or a portal team member's remote token (`x-remote-token`), and Form.io permissions apply. A UAG bearer token (`Authorization: Bearer`) works too. Servers may send `x-token: <PROJECT_KEY>` or `x-admin-key: <ADMIN_KEY>` instead; the UAG refuses those on any request with an `Origin` or `Sec-Fetch-Site` header, so they never work from a browser. Visitors with no credential are answered only by a form that sets `uagAnonymous: "true"` and lets Anonymous create submissions, within per-address and total rate limits. To decide on the server whatever a browser sent, add **Agent: Run task** to the form with its decision fields only, before the save.
|
|
470
218
|
|
|
471
|
-
|
|
472
|
-
The ```PROJECT``` environment variable is used to establish a connection from the UAG server to the project endpoint (for Enterprise) or OSS base url. This does NOT need to be a public DNS entry, but rather a URL that connects the UAG container to the Server container. The following examples illustrate how this would be configured.
|
|
219
|
+
Every field, status code and setting: [Agent API](https://ai.form.io/developers/agent-api). Measure decision accuracy on your own forms before going live: [Evaluation](https://ai.form.io/developers/evaluation).
|
|
473
220
|
|
|
474
|
-
|
|
475
|
-
If you are using a local connection, such as within a Docker Compose file, you can configure the ```PROJECT``` environment variable to point directly to the local url as follows.
|
|
221
|
+
## Engines and routing
|
|
476
222
|
|
|
477
|
-
|
|
478
|
-
```
|
|
479
|
-
services:
|
|
480
|
-
formio:
|
|
481
|
-
image: formio/formio:rc
|
|
482
|
-
restart: always
|
|
483
|
-
environment:
|
|
484
|
-
PORT: 3000
|
|
485
|
-
ADMIN_KEY: CHANGEME
|
|
486
|
-
formio-uag:
|
|
487
|
-
image: formio/uag
|
|
488
|
-
restart: always
|
|
489
|
-
links:
|
|
490
|
-
- formio
|
|
491
|
-
depends_on:
|
|
492
|
-
- formio
|
|
493
|
-
environment:
|
|
494
|
-
PROJECT: http://formio:3000
|
|
495
|
-
ADMIN_KEY: CHANGEME
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
In this example, we have Docker Compose launching the OSS Form.io container with the ADMIN_KEY set for this deployment, the UAG is connected using ```http://formio:3000``` which is the local Docker network name (provided using the "links" property in the docker compose file).
|
|
499
|
-
|
|
500
|
-
##### Local Connection to Enterprise Server Project
|
|
501
|
-
If you are using the Enterprise Form.io server within a local environment to the UAG, then you will need to ensure that the UAG connects to an independent project using the PROJECT_KEY as follows.
|
|
502
|
-
|
|
503
|
-
docker-compose.yml
|
|
504
|
-
```
|
|
505
|
-
services:
|
|
506
|
-
formio-enterprise:
|
|
507
|
-
image: formio/formio-enterprise
|
|
508
|
-
restart: always
|
|
509
|
-
environment:
|
|
510
|
-
PORT: 3000
|
|
511
|
-
formio-uag:
|
|
512
|
-
image: formio/uag
|
|
513
|
-
restart: always
|
|
514
|
-
links:
|
|
515
|
-
- formio-enterprise
|
|
516
|
-
depends_on:
|
|
517
|
-
- formio-enterprise
|
|
518
|
-
environment:
|
|
519
|
-
PROJECT: http://formio-enterprise:3000/myproject
|
|
520
|
-
PROJECT_KEY: CHANGEME
|
|
521
|
-
```
|
|
223
|
+
An **engine** connects the UAG to a model provider. Each engine type is its own npm package, and the `formio/uag` image includes all of the official ones. None runs until you name it in `UAG_ENGINES`.
|
|
522
224
|
|
|
523
|
-
|
|
524
|
-
|
|
225
|
+
| Kind | Answers | Engines |
|
|
226
|
+
|---|---|---|
|
|
227
|
+
| **Decision** | Closed-set fields (radio, select, checkbox, select boxes, survey, single resource selects) within the engine's option limit, with a calibrated confidence | [`jev`](./engines/jev), [`openai`](./engines/openai#decisions) with `kind: decision` |
|
|
228
|
+
| **Agent** | Everything else, marked `suggested`; may first research with read-only tools the task allows | [`claude`](./engines/claude), [`openai`](./engines/openai), [`grok`](./engines/grok), [`gemini`](./engines/gemini) |
|
|
525
229
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
restart: always
|
|
532
|
-
environment:
|
|
533
|
-
PROJECT: https://forms.mydomain.com/myproject
|
|
534
|
-
PROJECT_KEY: CHANGEME
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
docker-compose.yml: Connected to Open Source (formio/formio)
|
|
538
|
-
```
|
|
539
|
-
services:
|
|
540
|
-
formio-uag:
|
|
541
|
-
image: formio/uag
|
|
542
|
-
restart: always
|
|
543
|
-
environment:
|
|
544
|
-
PROJECT: https://forms.mydomain.com
|
|
545
|
-
ADMIN_KEY: CHANGEME
|
|
230
|
+
```bash
|
|
231
|
+
UAG_ENGINES=jev,fast:claude,deep:claude # instances; <name>:<type> runs one type twice
|
|
232
|
+
UAG_ENGINE_FAST_MODEL=claude-haiku-5-5 # UAG_ENGINE_<NAME>_<SETTING> configures one instance
|
|
233
|
+
TYPESAFE_API_KEY=... # then each engine's own variables
|
|
234
|
+
CLAUDE_API_KEY=...
|
|
546
235
|
```
|
|
547
236
|
|
|
548
|
-
|
|
549
|
-
The ```BASE_URL``` tells the UAG what URL it is reachable at. This value is published within the ```.well-known``` definitions for the OIDC (PKCE) authentication, and is used for the authentication callbacks.
|
|
550
|
-
|
|
551
|
-
**```BASE_URL``` is always required**, including for local clients. The UAG's authentication provider is only enabled when it is set, so if you omit it, ```/mcp``` returns a 401 for every request and the ```/auth/token``` and ```/.well-known/*``` endpoints do not exist at all (404). A 404 on ```/auth/token``` is the clearest signal that ```BASE_URL``` is missing.
|
|
552
|
-
|
|
553
|
-
What it needs to be set to depends on how agents connect:
|
|
237
|
+
Decision fields go to a decision engine, and fall back to an agent engine (reported `calibrated: false`) when it fails, times out, is over its rate limit, or none is enabled. A radio, single select or survey with more options than the decision engine accepts (255 for Jev) goes to an agent engine. Override the choice per field, or per task on its criteria, with `uagEngine`.
|
|
554
238
|
|
|
555
|
-
|
|
556
|
-
- **Local MCP client only**: set it to the address your client uses to reach the UAG. A private or localhost URL is fine — for example ```BASE_URL: http://localhost:3200``` or ```BASE_URL: http://formio-uag:3200``` within a Docker network.
|
|
239
|
+
Engines run inside the UAG, or on an [engine server](./packages/engine-server) (`formio/uag-engines`) so model keys and model traffic stay out of the UAG: name the instance with the `remote` type. To write your own, see the [Engine SDK](./packages/engine-sdk). Full guide: [Engines](https://ai.form.io/developers/engines).
|
|
557
240
|
|
|
558
|
-
|
|
241
|
+
## License
|
|
559
242
|
|
|
560
|
-
|
|
561
|
-
|
|
243
|
+
| You run | You need |
|
|
244
|
+
|---|---|
|
|
245
|
+
| MCP and conversation forms (including a form's chat, `{form}/agent/chat`), on Form.io Open Source or a hosted project | Nothing |
|
|
246
|
+
| MCP and conversation forms, on a self-hosted Form.io Enterprise project | A Form.io license in `LICENSE_KEY` (development hostnames such as `localhost` excepted) |
|
|
247
|
+
| Agentic workflows and Agentic Formflow (the Agent API's `extract`, `decide` and `generate`, the **Agent: Run task** action, the `agent_decide` and `agent_provide` tools, `uag-eval`) on a self-hosted project, Open Source or Enterprise | A Form.io license that includes the UAG, in `LICENSE_KEY` |
|
|
248
|
+
| The same on a project on Form.io's hosted service (`https://*.form.io`) | Nothing, as the project runs under Form.io's license; except `uag-eval`, which runs offline and needs `LICENSE_KEY` |
|
|
249
|
+
| The UAG's own database (`MONGO`), and with it remote MCP sign-in (`MCP_OAUTH`), on any project | A Form.io license that includes the UAG, unless the project and the database are both on development hosts (`localhost`, `*.localhost`, `lvh.me`, `*.local`) |
|
|
250
|
+
| The Agent API, Run task and `uag-eval` with only the stub engines (`UAG_ENGINES=stub-decision,stub-agent`), to try them out | Nothing. The `agent_decide` and `agent_provide` tools still need a license or a hosted project. |
|
|
562
251
|
|
|
563
|
-
|
|
252
|
+
A hosted project needs a license after all when the UAG weakens the proof that it is talking to form.io: `NODE_TLS_REJECT_UNAUTHORIZED=0`, or extra certificate authorities. Without a license, `MONGO` is not used: the UAG starts with its database features off and says why. Unlicensed requests get `403` with `code: "license_required"`, and `GET /agent/capabilities` always reports the edition and why. `UAG_LICENSE` is deprecated in favour of `LICENSE_KEY`, and still read until UAG 3.0. Details: [Deployment → Licensing](https://ai.form.io/developers/deployment#licensing).
|
|
564
253
|
|
|
565
|
-
|
|
566
|
-
- Enterprise Example: ```LOGIN_FORM: https://forms.mysite.com/myproject/user/login```
|
|
567
|
-
- OSS Example: ```LOGIN_FORM: https://forms.mysite.com/user/login```
|
|
254
|
+
## Extending the UAG
|
|
568
255
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
```npm install --save @formio/uag```
|
|
573
|
-
|
|
574
|
-
or
|
|
575
|
-
|
|
576
|
-
```yarn add @formio/uag```
|
|
577
|
-
|
|
578
|
-
You can then mount the UAG within your Express application, as seen in the following example:
|
|
256
|
+
- **Modules** add MCP tools, override the built-in tools and their response templates, add form actions (the UAG runs a module's own actions; Form.io runs its own), and ship a project template of forms and resources that the UAG installs. Mount one over `/app/module` in the container, or name it in `UAG_MODULE` for the `uag` command. See [Modules](https://ai.form.io/developers/modules), [`module/Readme.md`](./module/Readme.md) and the [Claude Desktop example](./demo/samples/custom-module).
|
|
257
|
+
- **Node.js.** Embed the UAG in an Express application, or run it with `npx uag`:
|
|
579
258
|
|
|
580
259
|
```js
|
|
581
|
-
import 'dotenv/config';
|
|
582
260
|
import Express from 'express';
|
|
583
261
|
import { UAGServer } from '@formio/uag';
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
app.listen(port, () => {
|
|
591
|
-
console.log(`Form.io UAG server running on port ${port}`);
|
|
592
|
-
console.log(`Visit http://localhost:${port} to access the application`);
|
|
593
|
-
});
|
|
594
|
-
})();
|
|
595
|
-
} catch (error) {
|
|
596
|
-
console.error('Failed to start server:', error);
|
|
597
|
-
process.exit(1);
|
|
598
|
-
}
|
|
262
|
+
|
|
263
|
+
const server = new UAGServer(); // configured by the environment variables below
|
|
264
|
+
// server.use(MyModule); // optional modules
|
|
265
|
+
const app = Express();
|
|
266
|
+
app.use(await server.router());
|
|
267
|
+
app.listen(process.env.PORT || 3200);
|
|
599
268
|
```
|
|
600
269
|
|
|
601
|
-
|
|
270
|
+
Run Node 22 or newer with `--no-node-snapshot` (isolated-vm, which runs form logic, needs it), and install the engines you use next to the UAG (`npm install @formio/uag-claude`). See [Node.js API](https://ai.form.io/developers/node-api).
|
|
271
|
+
- **[`@formio/uag-js`](./packages/uag-js)** connects a formio.js application to the UAG. Register it once with `Formio.use(UAG('https://uag.example.com'))`: submissions of forms tagged `uag` are then saved through the UAG, and Agent Input fills those forms from what the user wrote, through `{form}/agent/extract`, when they leave the input, pause, move to the next page, or press a button. `Formio.createChat(element, formUrl)` renders any of them as a chat instead, templated, translated and themed like a formio.js form. See [JavaScript (formio.js)](https://ai.form.io/developers/renderer) and [Chat widget](https://ai.form.io/developers/chat).
|
|
272
|
+
|
|
273
|
+
## Deployment
|
|
602
274
|
|
|
603
|
-
|
|
604
|
-
When using the UAG with the Form.io Enterprise Server, you unlock several benefits with regards to managing the Forms and Resources within the UAG. Some of the features that you gain with our Enterprise Server include:
|
|
275
|
+
### How agents connect
|
|
605
276
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
277
|
+
| The MCP client is | Example | The UAG must be |
|
|
278
|
+
|---|---|---|
|
|
279
|
+
| **Local**: your own process connects out to the UAG | Your backend, an engine server, a script | Reachable from that process only. `localhost` or a private network address is fine. |
|
|
280
|
+
| **Remote**: a hosted agent connects in | claude.ai and Claude Desktop connectors, other remote MCP hosts | Public over HTTPS, with `MCP_OAUTH=true` and its database (`MONGO`, licensed), for the `/.well-known` OAuth endpoints. |
|
|
609
281
|
|
|
610
|
-
|
|
611
|
-
In order to run the UAG against an Enterprise Server, you need to provide a few Environment variables that are different from the OSS runtime of this module. The following environment variables are required to run against an Enterprise Project.
|
|
282
|
+
A local client has no browser, so it exchanges a key for a token at the UAG's `/auth/token` with the `client_credentials` grant, as in the [Quickstart](#quickstart); this needs no `BASE_URL`, `MONGO` or `MCP_OAUTH`. The `client_id` is `formio-oss-x-admin-key` with `ADMIN_KEY` on Open Source, and `<project name>-x-token` with `PROJECT_KEY` on Enterprise or a hosted project, where the name is the project's `name` setting. A wrong `client_id` or secret answers `400`. Tokens last `JWT_EXPIRE_TIME` minutes; cache and refresh them.
|
|
612
283
|
|
|
613
|
-
|
|
614
|
-
|----------|-------------|---------|
|
|
615
|
-
| PROJECT | For the Enterprise Server, this points to the Project Endpoint you wish to bind the UAG to. | https://mydeployment.com/myproject |
|
|
616
|
-
| PROJECT_KEY | An API Key for that project, provided within the Project Settings | CHANGEME |
|
|
617
|
-
| UAG_LICENSE | This is the license provided to you from the Form.io License team. Contact support@form.io to acquire a "temporary" or full license. | |
|
|
284
|
+
### Main settings
|
|
618
285
|
|
|
619
|
-
|
|
286
|
+
| Variable | Meaning |
|
|
287
|
+
|---|---|
|
|
288
|
+
| `PROJECT` | **Required.** How the UAG reaches Form.io: the Open Source server's URL, or an Enterprise or hosted project's endpoint. A container-to-container address is fine. |
|
|
289
|
+
| `ADMIN_KEY` or `PROJECT_KEY` | **Required.** `ADMIN_KEY` for Open Source; a project API key (**Project Settings → API Keys**) for Enterprise or hosted. Setting `PROJECT_KEY` is what makes the UAG treat `PROJECT` as an Enterprise project. |
|
|
290
|
+
| `JWT_SECRET` | **Required.** Signs the tokens the UAG issues. The same as the Form.io Enterprise server's lets an agent act on users' behalf (see [Project setup for agents](https://ai.form.io/developers/project-setup)). |
|
|
291
|
+
| `MONGO`, `UAG_DATABASE` | Optional. The UAG's own database (default name `uag`; it can share Form.io's MongoDB), for run records in Action Logs, runs that survive a restart, remote MCP sign-in and the license grace period. It holds only `uag-*` collections, never submissions. Needs a license. |
|
|
292
|
+
| `MCP_OAUTH` | `true` turns on OAuth sign-in for remote MCP clients. Needs `MONGO`. |
|
|
293
|
+
| `TRUST_PROXY` | Optional. Set behind a reverse proxy, so the UAG reads its public URL from the forwarded headers. `BASE_URL`, also optional, overrides that URL. |
|
|
294
|
+
| `PORTAL_SECRET` | Enterprise. Lets a portal stage connect to the UAG, so you can add Run task actions there. |
|
|
295
|
+
| `LOGIN_FORM` | The project's login form JSON URL, for the browser sign-in at `/auth/authorize`. Defaults to `{PROJECT}/user/login`, which a browser often cannot reach, so set it to a public URL. |
|
|
296
|
+
| `LICENSE_KEY` | A Form.io license that includes the UAG. See [License](#license). |
|
|
297
|
+
| `UAG_ENGINES` | Engine instances to enable. See [Engines and routing](#engines-and-routing). |
|
|
298
|
+
| `PROJECT_TTL` | Seconds between project refreshes. Default `900`; `0` disables them. |
|
|
299
|
+
| `UAG_MODULE` | Path to a module, for the `uag` command (`npx uag`). The Docker image loads `/app/module` instead. |
|
|
300
|
+
|
|
301
|
+
Every variable, Docker and Kubernetes examples, Enterprise and hosted setups, a smaller image with fewer engines, and the production checklist: [Deployment](https://ai.form.io/developers/deployment). Before exposing the UAG: [Security](https://ai.form.io/developers/security).
|
|
620
302
|
|
|
621
303
|
## Troubleshooting
|
|
622
|
-
Most UAG problems are configuration, not code, and they tend to surface far from their cause — a missing tag looks like a missing form, and a missing `BASE_URL` looks like a permissions error. The table below maps the symptoms you are likely to see back to what actually produces them.
|
|
623
304
|
|
|
624
305
|
| Symptom | Likely cause |
|
|
625
|
-
|
|
626
|
-
|
|
|
627
|
-
| `/
|
|
628
|
-
|
|
|
629
|
-
|
|
|
630
|
-
|
|
|
631
|
-
|
|
|
632
|
-
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
306
|
+
|---|---|
|
|
307
|
+
| An agent says a form does not exist | The form is not tagged `uag`, or the project has not refreshed yet (`PROJECT_TTL`). |
|
|
308
|
+
| Every `/mcp` call is `401` | The client sends no token: exchange a key at `/auth/token` first. |
|
|
309
|
+
| A remote agent cannot sign in | `MCP_OAUTH` is off, the UAG has no usable database (`MONGO` with a license; its startup log says why), or the discovery documents name an address the agent cannot reach (set `TRUST_PROXY`, or `BASE_URL`). |
|
|
310
|
+
| Every tool fails; the UAG cannot reach Form.io | `PROJECT` is not reachable from inside the UAG container, or its certificate is not trusted. |
|
|
311
|
+
| A task fills some fields but not others | Their `uag` value does not exactly match the task's name, or they already had a value (see `excluded` in the response). |
|
|
312
|
+
| A Run task action never runs | The submission went to Form.io's URL instead of the UAG's, the action's method or conditions do not match, or the UAG has no license (see its log). |
|
|
313
|
+
| A task runs again on every update | The update Run task action has no condition on a field the task sets. |
|
|
314
|
+
|
|
315
|
+
The full table, with the Agent API's errors: [Troubleshooting](https://ai.form.io/developers/troubleshooting).
|
|
316
|
+
|
|
317
|
+
## Packages and versions
|
|
318
|
+
|
|
319
|
+
| Package | Version | Works with UAG | What it is |
|
|
320
|
+
|---|---|---|---|
|
|
321
|
+
| [`@formio/uag`](https://www.npmjs.com/package/@formio/uag), image [`formio/uag`](https://hub.docker.com/r/formio/uag) | 2.x | — | The UAG. The image includes every official engine. |
|
|
322
|
+
| `@formio/uag-jev`, `-claude`, `-openai`, `-grok`, `-gemini` | 2.x | ≥ 2.0.0 | The [engines](./engines), versioned independently of the UAG. |
|
|
323
|
+
| [`@formio/uag-sdk`](./packages/engine-sdk) | 2.x | ≥ 2.0.0 | Engine contract version 1, remote engine protocol version 1. |
|
|
324
|
+
| [`@formio/uag-engines`](./packages/engine-server), image `formio/uag-engines` | 2.x | ≥ 2.0.0 | The engine server. |
|
|
325
|
+
| [`@formio/uag-js`](./packages/uag-js) | 2.x | ≥ 2.0.0 | The formio.js module: saves `uag` forms through the UAG, adds Agent Input, and renders forms as a chat. Runs in the browser. |
|
|
326
|
+
| `@formio/uag-claude` | 1.3.x | ≥ 1.12.0 | The retired Claude integration. Security fixes only; see [MIGRATING-2.0.md](./MIGRATING-2.0.md). |
|
|
327
|
+
|
|
328
|
+
`@formio/uag-claude` 2.x is the Claude *engine*, not the 1.x integration; pin `@formio/uag-claude@^1` if you still install the integration. Upgrading from 1.x: [MIGRATING-2.0.md](./MIGRATING-2.0.md).
|
|
329
|
+
|
|
330
|
+
## Documentation
|
|
331
|
+
|
|
332
|
+
The developer documentation is published at [ai.form.io/developers](https://ai.form.io/developers), from the Markdown in [`demo/content/developers`](./demo/content/developers).
|
|
333
|
+
|
|
334
|
+
| | Site | In this repository |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| **Start here** | [How the UAG works](https://ai.form.io/developers) · [Agentic Coding Plugin](https://ai.form.io/developers/agentic-coding) · [Quickstart](https://ai.form.io/developers/quickstart) | [Demo site](./demo/README.md) |
|
|
337
|
+
| **Concepts** | [Concepts](https://ai.form.io/developers/concepts) · [Form properties](https://ai.form.io/developers/form-properties) | |
|
|
338
|
+
| **Build** | [MCP tools](https://ai.form.io/developers/mcp-tools) · [Agent API](https://ai.form.io/developers/agent-api) · [Workflows](https://ai.form.io/developers/workflows) · [JavaScript (formio.js)](https://ai.form.io/developers/renderer) · [Chat widget](https://ai.form.io/developers/chat) · [Connect Claude](https://ai.form.io/developers/connect-claude) | [`@formio/uag-js`](./packages/uag-js/README.md) · [Claude Desktop module](./demo/samples/custom-module/Readme.md) |
|
|
339
|
+
| **Extend** | [Node.js API](https://ai.form.io/developers/node-api) · [Modules](https://ai.form.io/developers/modules) · [Engines](https://ai.form.io/developers/engines) · [Engine SDK](https://ai.form.io/developers/engine-sdk) · [Engine server](https://ai.form.io/developers/engine-server) | [Modules](./module/Readme.md) · [Response templates](./demo/samples/custom-module/module/templates/Readme.md) · [Engines](./engines) · [Engine SDK](./packages/engine-sdk/README.md) · [Engine server](./packages/engine-server/README.md) · [Engine setups](./demo/samples/engines/Readme.md) |
|
|
340
|
+
| **Operate** | [Security](https://ai.form.io/developers/security) · [Deployment](https://ai.form.io/developers/deployment) · [Evaluation](https://ai.form.io/developers/evaluation) · [Troubleshooting](https://ai.form.io/developers/troubleshooting) | [Docker Hub](./DOCKERHUB.md) · [Migrating to 2.0](./MIGRATING-2.0.md) · [Security policy](./SECURITY.md) · [End-to-end tests](./test/e2e/Readme.md) |
|