{"id":50535541,"url":"https://github.com/formio/ai","last_synced_at":"2026-06-03T16:01:45.739Z","repository":{"id":355924605,"uuid":"1221068931","full_name":"formio/ai","owner":"formio","description":"Form.io concepts for Agentic Coding platforms.","archived":false,"fork":false,"pushed_at":"2026-06-01T16:25:23.000Z","size":896,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-01T18:09:29.802Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/formio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T17:58:36.000Z","updated_at":"2026-05-29T19:20:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/formio/ai","commit_stats":null,"previous_names":["formio/ai"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/formio/ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formio%2Fai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formio%2Fai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formio%2Fai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formio%2Fai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/formio","download_url":"https://codeload.github.com/formio/ai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formio%2Fai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33872298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T16:01:45.386Z","updated_at":"2026-06-03T16:01:45.713Z","avatar_url":"https://github.com/formio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Form.io Agentic Coding Toolset\n\n**Build compliance-ready apps with Form.io, in your agentic coding environment.**\n\nWith Form.io, define a data model once and leverage it in multiple ways at runtime. A singular data model can be rendered as a form for humans to fill out, leveraged as the auto-generated API a system calls, or provide context for AI agents to execute workflows. One model, every surface.\n\nThat's what makes Form.io the data standardization layer for enterprises in regulated industries around the world. Form.io enables developers and AI coding agents to build applications using forms as infrastructure for compliance-ready solutions in any industry.\n\n`@formio/ai` is what brings Form.io into your agentic coding environment. A Claude Code plugin, an MCP server (`@formio/mcp`), and a skill library so your agent works in Form.io primitives: forms, resources, nested data structures, role-based access, group permissions, server-side actions.\n\nThe result: every app your agent builds inherits the model, the governance, RBAC, and the audit trail by default.\n\n\u003e **Note on scope.** This repo is for AI coding agents while writing code. Form.io also provides a Universal Agent Gateway (UAG) for governing agentic workflows running in production. [More on Form.io UAG here.](https://form.io/uag)\n\n## What you get\n\n- **Claude Code plugin: `@formio/ai`.** One-command install. Bundles the MCP server and skill library, registers them with Claude Code.\n- **MCP server: `@formio/mcp`.** Form.io operations (`form_*`, `role_*`, `action_*`, `project_*`) as MCP tools. Works with any MCP-aware client: Claude Code, Claude Desktop, VS Copilot, and whatever comes next.\n- **Skills library:** Eight activatable skills covering app orchestration, resource planning, Angular scaffolding, JSON-schema authoring, action configuration, authentication \u0026 authorization, the `@formio/js` SDK surface, and the full Form.io REST surface.\n\n## Why this exists\n\nForm.io has been the data standardization layer for enterprise data for a decade. With the proliferation of AI coding agents, that standardization matters more, not less.\n\n**Build on the Form.io platform, not from scratch.** The agent builds complete applications including the data models, forms, workflows, and business logic. Form.io is the platform it builds on. The APIs, data patterns, RBAC, audit infrastructure, and form management capabilities are production-grade and already there. The agent uses them as tools to build applications better.\n\n**Standardization across every AI-built app.** One model, one set of rules, one audit trail, regardless of which team or which agent built it. With a standardization layer, multiple teams ship multiple applications, all with defensible, reconcilable data layers across the enterprise.\n\n**Governance built in.** RBAC, group permissions, change history, audit trails — all emitted on the first pass. Every app lands inside the same compliance envelope the enterprise already runs on.\n\n---\n\n## Table of contents\n\n- [What this library is for](#what-this-library-is-for)\n- [Use cases](#use-cases)\n- [Quickstart — Claude Code plugin](#quickstart--claude-code-plugin)\n- [Quickstart — standalone MCP server](#quickstart--standalone-mcp-server)\n- [How it works](#how-it-works)\n  - [Skill routing map](#skill-routing-map)\n  - [The `formio-application` flow](#the-formio-application-flow)\n  - [The `formio-resource-planner` two-phase flow](#the-formio-resource-planner-two-phase-flow)\n  - [The planner ↔ `formio-auth` handoff](#the-planner--formio-auth-handoff)\n  - [The `formio-angular` five-phase flow](#the-formio-angular-five-phase-flow)\n- [Sample resource maps](#sample-resource-maps)\n  - [Task manager (group-via-join)](#task-manager-group-via-join)\n  - [CRM with transitive group access](#crm-with-transitive-group-access)\n- [Skills library](#skills-library)\n- [MCP server tools](#mcp-server-tools)\n- [Authentication](#authentication)\n- [Environment variables](#environment-variables)\n- [Development](#development)\n- [Spec-driven development with OpenSpec](#spec-driven-development-with-openspec)\n- [License](#license)\n\n---\n\n## What this library is for\n\n`@formio/ai` introduces Form.io to agentic coding workflows. The skills cover the full mental model an enterprise Form.io developer carries — and the MCP tools give the agent direct, authenticated access to the running platform — so the agent can:\n\n- **Reason about the data model** as resources, sub-resources, and join resources rather than generic tables.\n- **Apply RBAC correctly** by default — Roles, Group Assignment actions, field-based `submissionAccess`, owner-vs-group-vs-role-vs-tenant access strategies, transitive group propagation through hidden calculated mirrors.\n- **Wire authentication** via the built-in `user` resource or a custom user resource, with Login + Role Assignment actions, self-register vs admin-invite flows, and the right anonymous/authenticated/admin role layering.\n- **Configure server-side behavior** through actions — email, webhook, save, login, role assignment, group assignment, reset password — with the right handler/method/priority/condition combinations.\n- **Author and edit form JSON** — every component type, validation rule, conditional logic expression, calculated value, and field-based access block.\n- **Operate the running platform** through first-party MCP tools (`form_*`, `role_*`, `action_*`, `project_*`) instead of brittle raw HTTP, with implicit JWT auth via the portal-login flow.\n- **Navigate the full REST surface** — platform admin, project admin, runtime/end-user, PDF — when an MCP tool does not yet cover an operation.\n\nAgents loaded with `@formio/ai` produce enterprise-grade applications: every resource ships with a Save Submission action so submissions actually persist; every authenticated role inherits its access through documented Group / Field-based / Role mechanics; every front-end component is scaffolded against `@formio/angular` with `FormioAuthConfig` and `FormioResourceConfig` derived directly from the planner's `template.json`.\n\n---\n\n## Use Cases\n\nWhat you can do with these tools: Five real prompts, paste-ready in Claude Code. Each one shows a different shape of work the agent handles natively.\n\n### Build a complete app from one prompt\n\n\u003e \"Build me a CRM where sales reps only see accounts owned by the teams they belong to.\"\n\nThe agent plans the data model, imports it into Form.io, and scaffolds an Angular front-end wired to the project. Approval gate at every step. At the end you have a running application — not a prototype.\n\n### Extend a running app\n\n\u003e \"Also let customers leave reviews on each completed booking, and let providers reply to them.\"\n\nIn a workspace that's already wired to a Form.io project, the agent plans only what's new and adds it without touching what works. Existing project content stays intact.\n\n### Plan a data model from plain language\n\n\u003e \"Plan the resource structure for a multi-tenant booking system where customers book services from providers, providers belong to one or more locations, and admins manage everything.\"\n\nThe agent runs a structured interview, produces an ER diagram and access matrix for review, and emits a project template ready to import. You see the architectural shape before any code or schema gets written.\n\n### Tighten access controls on an existing resource\n\n\u003e \"Currently anyone authenticated can read every Account. Lock it down so reps only see Accounts owned by their Team.\"\n\nThe agent reads the resource, modifies the access rules, and ensures the supporting role assignments are in place. The diff lands for your review before anything ships.\n\n### Inspect and operate a live project\n\n\u003e \"List every form in this project that doesn't have a Save Submission action attached.\"\n\nThe agent queries the live project through the MCP server, surfaces what's missing, and offers to fix it. This is operational work — not building from scratch, but keeping a running system clean.\n\n---\n\n## Quickstart — Claude Code plugin\n\nThe fastest way to get started. From inside Claude Code:\n\n```text\n/plugin marketplace add git@github.com:formio/ai.git\n/plugin install formio-ai@formio\n```\n\nClaude Code prompts for `FORMIO_BASE_URL` and `FORMIO_PROJECT_URL` on install. Then describe what you want:\n\n\u003e \"Build me a task manager where each project has its own team of users, and users only see tasks inside projects they belong to.\"\n\nThe `formio-application` skill activates, runs the planner, captures URLs, imports the template, and hands off to `formio-angular` to scaffold the Angular front-end. Each step has an approval gate.\n\nTo extend an existing app, just describe the new feature in the same workspace:\n\n\u003e \"Also let team members add comments to each task.\"\n\nThe same skill switches to **modify-existing** mode — plans only the new resources (delta `template.json`), additively imports them, and hands off to the Angular extend sub-skill to scaffold modules for exactly the new resources.\n\n---\n\n## Quickstart — standalone MCP server\n\nThe MCP server (`@formio/mcp`) is independently usable from any MCP-aware client. From a clone of this repo:\n\n```bash\npnpm install\npnpm --filter @formio/mcp dev\n```\n\nThe server starts on port 3000. Override with the `PORT` env var.\n\n### Transports\n\n| Transport | Endpoint | Compatible with |\n| --- | --- | --- |\n| Streamable HTTP | `POST /mcp` | Claude Code, VS Copilot, modern MCP clients |\n| SSE | `GET /sse` + `POST /messages` | Claude Desktop, legacy MCP clients |\n| stdio | `node dist/stdio.js` | `.mcp.json` spawn-mode clients |\n\n### Connect to Claude Code\n\n```json\n{\n  \"mcpServers\": {\n    \"formio-mcp\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3000/mcp\"\n    }\n  }\n}\n```\n\n### Connect to Claude Desktop\n\n`claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"formio-mcp\": {\n      \"url\": \"http://localhost:3000/sse\"\n    }\n  }\n}\n```\n\n### Spawn via `.mcp.json` (stdio)\n\n```json\n{\n  \"mcpServers\": {\n    \"formio-mcp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@formio/mcp\"],\n      \"env\": {\n        \"FORMIO_BASE_URL\": \"https://api.form.io\",\n        \"FORMIO_PROJECT_URL\": \"https://your-project.form.io\"\n      }\n    }\n  }\n}\n```\n\nIn standalone (non-plugin) mode, `FORMIO_BASE_URL` and `FORMIO_PROJECT_URL` are required env vars. In plugin mode, the plugin manages both via Claude Code's user-config + per-cwd `~/.formio/projects.json` mapping.\n\n---\n\n## How it works\n\nThree skills do the heavy lifting on a build: the orchestrator (`formio-application`) routes work, the planner (`formio-resource-planner`) designs the data model, and the framework implementor (`formio-angular`) scaffolds the front-end. Four more skills are pulled in on demand — `formio-auth` (authentication \u0026 authorization), `formio-schema` (project / form / submission JSON), `formio-actions` (server-side behavior), `formio-sdk` (the `@formio/js` runtime), and `formio-api` (raw REST) — whenever the build or a direct question touches their domain.\n\n### Skill routing map\n\nClaude activates the skill whose `description` matches the request. Build-an-app intent enters through `formio-application`, which delegates to the planner, hands off to `formio-auth` when the data model needs auth beyond default roles, and routes to `formio-angular` for the front-end. The reference skills (`formio-schema`, `formio-actions`, `formio-sdk`, `formio-api`) activate directly on a matching question, or are consulted mid-build.\n\n```mermaid\nflowchart TD\n    User([User request]) --\u003e Router{Claude routes\u003cbr/\u003eby skill description}\n\n    Router --\u003e|\"\u0026quot;build / extend an app\u0026quot;\"| App[formio-application\u003cbr/\u003eorchestrator]\n    Router --\u003e|\"\u0026quot;plan / model the data\u0026quot;\"| Planner[formio-resource-planner]\n    Router --\u003e|\"\u0026quot;login, SSO, RBAC, JWT\u0026quot;\"| Auth[formio-auth]\n    Router --\u003e|\"\u0026quot;Angular front-end\u0026quot;\"| Ng[formio-angular]\n    Router --\u003e|\"\u0026quot;form / submission / project JSON\u0026quot;\"| Schema[formio-schema]\n    Router --\u003e|\"\u0026quot;email / webhook / login action\u0026quot;\"| Actions[formio-actions]\n    Router --\u003e|\"\u0026quot;Formio.* / Utils.* in JS\u0026quot;\"| Sdk[formio-sdk]\n    Router --\u003e|\"\u0026quot;call a REST endpoint\u0026quot;\"| Api[formio-api]\n\n    App --\u003e|Step 2: Plan| Planner\n    Planner -.-\u003e|\"non-default auth\u003cbr/\u003e(SSO / Custom JWT / groups)\"| Auth\n    App --\u003e|Step 6: Framework| Ng\n    Ng -.-\u003e|per-resource modules| NgRes[formio-angular/resources]\n\n    Planner -.-\u003e|consults| Schema\n    Planner -.-\u003e|emits| Actions\n    Ng -.-\u003e|runtime calls| Sdk\n    App -.-\u003e|MCP tools| MCP[(\"@formio/mcp\u003cbr/\u003eform_* role_* action_* project_*\")]\n    Ng -.-\u003e|MCP tools| MCP\n\n    style Router fill:#67b346,color:#fff\n    style App fill:#e8f5e4\n    style Planner fill:#e8f5e4\n    style Auth fill:#fff4e0\n    style Ng fill:#e8f5e4\n    style MCP fill:#fff4e0\n```\n\n### The `formio-application` flow\n\n`formio-application` is the default \"build me an app\" entry point. It runs a six-step orchestration with approval gates at every write. **Build-new** runs all six. **Modify-existing** skips Deployment + MCP Config (URLs already known) but still plans (delta) and still imports (additive).\n\n```mermaid\nflowchart TD\n    User([User intent:\u003cbr/\u003e\u0026quot;build me a CRM\u0026quot; OR \u0026quot;also track attendees\u0026quot;]) --\u003e Intent{Step 1: Intent\u003cbr/\u003ebuild-new or modify-existing?}\n\n    Intent --\u003e|build-new| PlanFull[Step 2: Plan\u003cbr/\u003eformio-resource-planner\u003cbr/\u003efull-project template.json]\n    Intent --\u003e|modify-existing| PlanDelta[Step 2: Plan\u003cbr/\u003eformio-resource-planner\u003cbr/\u003edelta template.json\u003cbr/\u003eonly new resources]\n\n    PlanFull --\u003e Deploy[Step 3: Deployment\u003cbr/\u003ecapture FORMIO_BASE_URL\u003cbr/\u003e+ FORMIO_PROJECT_URL]\n    Deploy --\u003e MCPConfig[Step 4: MCP Config\u003cbr/\u003ewrite ./.mcp.json\u003cbr/\u003eapproval gate]\n    MCPConfig --\u003e Restart[/Halt — user restarts\u003cbr/\u003eClaude Code or /mcp reconnect/]\n    Restart --\u003e ImportFull[Step 5: Import\u003cbr/\u003eproject_import full template\u003cbr/\u003efirst call triggers portal login]\n\n    PlanDelta --\u003e ReadURLs[Steps 3 + 4 SKIPPED\u003cbr/\u003eread URLs from workspace\u003cbr/\u003eFormioAppConfig]\n    ReadURLs --\u003e ImportDelta[Step 5: Import\u003cbr/\u003eproject_import delta template\u003cbr/\u003eadditive merge into existing project]\n\n    ImportFull --\u003e FrameworkNew[Step 6: Framework routing\u003cbr/\u003escaffold new app]\n    ImportDelta --\u003e FrameworkExtend[Step 6: Framework routing\u003cbr/\u003eextend sub-skill\u003cbr/\u003escaffolds only new resource modules]\n\n    FrameworkNew --\u003e Angular[formio-angular]\n    FrameworkExtend --\u003e AngularResources[formio-angular/resources]\n\n    Angular --\u003e App([Running app])\n    AngularResources --\u003e App\n\n    style Intent fill:#67b346,color:#fff\n    style PlanFull fill:#e8f5e4\n    style PlanDelta fill:#e8f5e4\n    style MCPConfig fill:#fff4e0\n    style ImportFull fill:#fff4e0\n    style ImportDelta fill:#fff4e0\n    style FrameworkNew fill:#e8f5e4\n    style FrameworkExtend fill:#e8f5e4\n    style Angular fill:#e8f5e4\n    style AngularResources fill:#e8f5e4\n    style App fill:#67b346,color:#fff\n```\n\n| Step | Build-new | Modify-existing |\n| --- | --- | --- |\n| 1. Intent | Identify build-new | Identify modify-existing |\n| 2. Plan | Full-project `template.md` + `template.json` | Delta — only new resources/fields/actions |\n| 3. Deployment | Capture URLs (one batched `AskUserQuestion`) | Skipped — read URLs from workspace `FormioAppConfig` |\n| 4. MCP Config | Write `./.mcp.json`, halt for restart | Skipped — `.mcp.json` already in place |\n| 5. Import | Additive `project_import` (first call triggers portal login) | Additive `project_import` of delta |\n| 6. Framework | Scaffold full app (Angular today) | Hand list of new resources to extend sub-skill |\n\nImport is **additive**: existing project content is preserved; only matching machine-names are overwritten. Authentication is implicit — the first authenticated MCP tool call triggers the browser portal-login flow on a cache miss.\n\n### The `formio-resource-planner` two-phase flow\n\nThe planner is interview-driven and emits two artifacts in lockstep — `template.md` (architectural intent, ER + Access Flow diagrams) and `template.json` (the structured Form.io export, every resource + role + form + action). Phase A always blocks on user approval before Phase B writes any file.\n\n```mermaid\nflowchart TD\n    Req([User requirement:\u003cbr/\u003e\u0026quot;Task manager — projects, tasks, teams of users\u0026quot;]) --\u003e Entities[Round 1\u003cbr/\u003eextract named entities]\n    Entities --\u003e Rels[Round 2\u003cbr/\u003edetermine relationships\u003cbr/\u003e1:1 / 1:N / N:N]\n    Rels --\u003e Auth[Round 3\u003cbr/\u003euser / auth model\u003cbr/\u003ebuilt-in user vs custom]\n    Auth --\u003e Access[Round 4\u003cbr/\u003eaccess model\u003cbr/\u003eowner / group / role / tenant]\n\n    Access --\u003e PhaseA[Phase A\u003cbr/\u003eResource Map\u003cbr/\u003eASCII ER + Access Flow]\n    PhaseA --\u003e Gate{User\u003cbr/\u003eapproves?}\n    Gate --\u003e|revise| Rels\n    Gate --\u003e|approve| PhaseB[Phase B\u003cbr/\u003eWrite template.md +\u003cbr/\u003etemplate.json paired set\u003cbr/\u003eMermaid diagrams]\n    PhaseB --\u003e Done([Ready for project_import])\n\n    style PhaseA fill:#fff4e0\n    style Gate fill:#67b346,color:#fff\n    style PhaseB fill:#e8f5e4\n    style Done fill:#67b346,color:#fff\n```\n\nEvery emitted `template.json` includes a top-level `actions` map with at minimum a `Save Submission` action per resource (omitting it produces a project where forms accept submissions but never store them — the planner treats that as a hard failure).\n\n### The planner ↔ `formio-auth` handoff\n\nThe contract between the two auth-aware skills is explicit. `formio-resource-planner` owns the **data model** — roles, the `user` resource, login/registration forms, group joins — and emits the canonical `template.json` shapes for the Login, Role Assignment, and Group Assignment actions plus the `access` / `submissionAccess` arrays. `formio-auth` owns the **auth configuration that runs on top of that model** — SSO (OIDC / OAuth / SAML / LDAP) with provider role mapping, Token Swap, Custom JWT signed with `JWT_SECRET`, passwordless email-token auth, and JWT / session / 2FA / reCAPTCHA mechanics. Action JSON shapes are never duplicated; `formio-auth` references the planner's `references/template-json.md` by path.\n\n```mermaid\nflowchart TD\n    Map[Resource Map approved\u003cbr/\u003eUsers \u0026amp; Auth section] --\u003e Q{Auth beyond\u003cbr/\u003eresource login + Role + Group?}\n    Q --\u003e|no| Planner[formio-resource-planner\u003cbr/\u003eemits template.json\u003cbr/\u003eLogin / Role / Group actions]\n    Q --\u003e|\"SSO ≠ none, Custom JWT,\u003cbr/\u003eToken Swap, passwordless, 2FA\"| Auth[formio-auth\u003cbr/\u003econfigures auth layer\u003cbr/\u003eon top of the model]\n    Planner --\u003e Import([project_import])\n    Auth -.-\u003e|references template-json.md| Planner\n    Auth --\u003e Import\n\n    style Q fill:#67b346,color:#fff\n    style Auth fill:#fff4e0\n    style Planner fill:#e8f5e4\n    style Import fill:#67b346,color:#fff\n```\n\nHand off to `formio-auth` immediately after the Resource Map is approved whenever its `Users \u0026 Auth` section emits a non-`none` `SSO` field, a `Custom JWT: yes`, or any auth concern beyond resource-backed login plus Role and Group Assignment.\n\n### The `formio-angular` five-phase flow\n\nInvoked either as a handoff from `formio-application` (URLs and `template.json` already in hand) or directly when the user names Angular explicitly. Each phase has its own approval gate.\n\n```mermaid\nflowchart TD\n    Entry{Invoked by} --\u003e|formio-application handoff| Handoff[SETUP confirms handoff context\u003cbr/\u003eURLs + template paths already known]\n    Entry --\u003e|user names Angular directly| Direct[SETUP runs full URL interview]\n\n    Handoff --\u003e Bootstrap\n    Direct --\u003e Bootstrap\n\n    Bootstrap{Phase 2\u003cbr/\u003eBOOTSTRAP\u003cbr/\u003eangular.json present?}\n    Bootstrap --\u003e|no| Install[Install angular/skills lib\u003cbr/\u003edelegate to angular-new-app\u003cbr/\u003einstall @formio/angular + @formio/js\u003cbr/\u003eBootstrap 5 + zone.js]\n    Bootstrap --\u003e|yes| Config\n\n    Install --\u003e Config[Phase 3\u003cbr/\u003eCONFIG\u003cbr/\u003egenerate src/app/config.ts\u003cbr/\u003eFormioAppConfig]\n    Config --\u003e AuthPhase[Phase 4\u003cbr/\u003eAUTH\u003cbr/\u003eAuthModule + login/register\u003cbr/\u003eroute guards on protected routes\u003cbr/\u003elogin-success notification]\n    AuthPhase --\u003e Resources[Phase 5\u003cbr/\u003eResources sub-skill\u003cbr/\u003eper-resource NgModule\u003cbr/\u003eFormioResourceConfig + guarded Routes]\n    Resources --\u003e Done([Running Angular app])\n\n    style Bootstrap fill:#67b346,color:#fff\n    style Config fill:#e8f5e4\n    style AuthPhase fill:#e8f5e4\n    style Resources fill:#e8f5e4\n    style Done fill:#67b346,color:#fff\n```\n\nGenerated workspaces use NgModule-based components (`standalone: false`) to match the official `@formio/angular` demo, with Bootstrap 5 + Bootstrap Icons wired via `angular.json`. The AUTH phase wires a `FormioAuthService`-backed login/register experience and attaches route guards so protected resource routes redirect unauthenticated users to login (with a login-success notification on return). UI-touching files consult Claude's built-in `frontend-design` skill before authoring templates or styles.\n\n---\n\n## Sample resource maps\n\nThese are real outputs from `formio-resource-planner`'s `references/examples/`. Both ship with paired `template.md` and `template.json` artifacts under [`plugin/skills/formio-resource-planner/references/examples/`](./plugin/skills/formio-resource-planner/references/examples/).\n\n### Task manager (group-via-join)\n\nA multi-user task manager where each Project has a team of Users and users only see Tasks inside Projects they belong to. Demonstrates **group permissions via a join resource** (`ProjectUser`) and **field-based ACL inheritance** (`Task.project`).\n\n```mermaid\nerDiagram\n    User ||--o{ ProjectUser : \"member of\"\n    Project ||--o{ ProjectUser : \"has members\"\n    Project ||--o{ Task : \"contains\"\n\n    User {\n        string email \"login identifier (unique)\"\n        string password \"login secret\"\n    }\n    Project {\n        string name \"required\"\n    }\n    Task {\n        string description\n        select project \"ref=Project, field-based access\"\n    }\n    ProjectUser {\n        select project \"ref=Project\"\n        select user \"ref=User\"\n        action GroupAssignment \"group=project, user=user\"\n    }\n```\n\n```mermaid\nflowchart TD\n    Admin[[administrator]] --\u003e All[[every resource]]\n    Auth[[authenticated]] --\u003e|\"membership row\"| PU[/ProjectUser/]\n    PU --\u003e|\"Group Assignment\u003cbr/\u003egroup=project\u003cbr/\u003euser=user\"| P[Project]\n    P --\u003e|\"field-based submissionAccess\u003cbr/\u003eon Task.project\"| T[Task]\n    Auth --\u003e|\"Submission Access: read_own, update_own\"| U[User]\n```\n\n| Resource | Actor | create | read | update | delete | Notes |\n| --- | --- | :-: | :-: | :-: | :-: | --- |\n| Project | administrator | all | all | all | all | full admin |\n| Project | authenticated | — | group | group | — | group-via-ProjectUser |\n| Task | administrator | all | all | all | all |  |\n| Task | authenticated | group | group | group | — | inherits via `Task.project` |\n| ProjectUser | administrator | all | all | all | all | admin-managed membership |\n| ProjectUser | authenticated | — | own | — | — | user sees their own memberships |\n| User | administrator | all | all | all | all |  |\n| User | authenticated | — | own | own | — | owner-level on own record |\n\n### CRM with transitive group access\n\nA multi-team CRM where the group (`Team`) sits **two levels above** the bottom of the hierarchy. The direct child (`Account`) uses a normal group-reference select; grandchildren (`Contact`, `Deal`, `Activity`) use a hidden, calculated `team` mirror field to propagate the ACL one more hop.\n\n```mermaid\nerDiagram\n    User ||--o{ TeamUser : \"member of\"\n    Team ||--o{ TeamUser : \"has members\"\n    Team ||--o{ Account : \"owns (direct group)\"\n    Account ||--o{ Contact : \"has\"\n    Account ||--o{ Deal : \"has\"\n    Account ||--o{ Activity : \"has\"\n    Deal ||--o{ Activity : \"optional back-ref\"\n\n    Team { string name \"required\" }\n    TeamUser {\n        select team \"ref=Team\"\n        select user \"ref=User\"\n        action GroupAssignment \"group=team, user=user\"\n    }\n    Account {\n        string name \"required\"\n        select team \"ref=Team, field-based access (direct group)\"\n    }\n    Contact {\n        string firstName\n        select account \"ref=Account\"\n        select team \"HIDDEN calculated mirror: data.account.data.team\"\n    }\n    Deal {\n        string title\n        select account \"ref=Account\"\n        select team \"HIDDEN calculated mirror\"\n    }\n    Activity {\n        string subject\n        select account \"ref=Account\"\n        select team \"HIDDEN calculated mirror\"\n    }\n```\n\n```mermaid\nflowchart TD\n    Admin[[administrator]] --\u003e All[[every resource]]\n    SR[[salesRep]] --\u003e|\"Role Assignment on userRegister\"| SR\n    SR --\u003e|\"membership row (one per Team)\"| TU[/TeamUser/]\n    TU --\u003e|\"Group Assignment\u003cbr/\u003egroup=team\u003cbr/\u003euser=user\"| Team[Team]\n    Team --\u003e|\"field-based submissionAccess\u003cbr/\u003eon Account.team\"| Account[Account]\n    Account --\u003e|\"hidden calculated mirror\u003cbr/\u003evalue = data.account.data.team\"| Contact[Contact]\n    Account --\u003e|\"hidden calculated mirror\"| Deal[Deal]\n    Account --\u003e|\"hidden calculated mirror\"| Activity[Activity]\n```\n\nRuntime propagation:\n\n1. User self-registers on `userRegister` → Save writes into `user` resource → Role Assignment grants `salesRep` → Login issues JWT.\n2. Admin creates a `TeamUser(team, user)` row → Group Assignment writes an ACL entry onto the Team submission.\n3. `Account.team` carries field-based `submissionAccess` (4 entries, empty roles) → Form.io propagates the Team's ACL onto each Account whose `team` matches.\n4. `Contact` / `Deal` / `Activity` each carry a hidden `team` select with `calculateValue: value = data.account.data.team;`, `refreshOn: account`, `hidden: true`, plus the same field-based `submissionAccess` block — propagating the ACL one more hop on every save.\n\n---\n\n## Skills library\n\nEight activatable skills under [`plugin/skills/`](./plugin/skills/). Claude routes between them based on what the user asked for (see the [skill routing map](#skill-routing-map)).\n\n### Orchestration \u0026 framework skills\n\n| Skill | Purpose |\n| --- | --- |\n| [`formio-application`](./plugin/skills/formio-application/) | Default \"build me an app\" orchestrator. Six-step pipeline: Intent → Plan → Deployment → MCP Config → Import → Framework routing. Build-new runs all six; modify-existing runs Plan (delta) + Import (additive) + Framework (extend sub-skill), skipping only Deployment + MCP Config. |\n| [`formio-resource-planner`](./plugin/skills/formio-resource-planner/) | Turns plain-language requirements into a Form.io project `template.md` + `template.json` pair — resources, fields, roles, actions, access model. Two-phase: Resource Map (review) → paired artifacts (after explicit approval). Encodes when to model something as a resource vs a plain form, and the access-model anti-patterns to avoid. Hands non-default auth off to `formio-auth`. |\n| [`formio-angular`](./plugin/skills/formio-angular/) | Angular framework implementor. Five-phase scaffold flow over `@formio/angular` (NgModule-based, `standalone: false`, Bootstrap 5). Sub-skill at [`resources/`](./plugin/skills/formio-angular/resources/) handles per-resource NgModule generation and modify-existing extension. |\n\n### Schema, action \u0026 SDK skills\n\n| Skill | Purpose |\n| --- | --- |\n| [`formio-schema`](./plugin/skills/formio-schema/) | Comprehensive JSON schema reference for **projects, forms (and resources), and submissions** — component types, validation, conditional logic, project settings/integrations, submission `data`/`access`/`metadata`/state. Consulted when reading, writing, or editing any Form.io JSON. (Absorbs the former `formio-form` skill.) |\n| [`formio-actions`](./plugin/skills/formio-actions/) | Deep reference for configuring Form.io server-side actions — email, login, webhook, role assignment, save, reset password — including handler/method, priorities, and conditions. |\n| [`formio-auth`](./plugin/skills/formio-auth/) | Authentication \u0026 authorization specialist — resource-backed login (Login + Role Assignment actions), the eight RBAC permission types, group permissions (single-level + transitive), SSO via OIDC/OAuth/SAML/LDAP with role mapping, Token Swap, Custom JWT (`JWT_SECRET`), passwordless email-token auth, and JWT/session/2FA/reCAPTCHA mechanics. Peer to the planner; owns the auth layer the planner's data model runs on. |\n| [`formio-sdk`](./plugin/skills/formio-sdk/) | Source-derived reference for the `@formio/js` SDK, `@formio/js/utils` Utilities, and `@formio/core` helpers — static \u0026 instance `Formio.*` methods, VanillaJS rendering (`Formio.createForm`, `Formio.builder`), the plugin lifecycle, and the `Utils` surface (Evaluator, traversal, conditions, JSONLogic, mask/sanitize). Mandates ESM imports. |\n\n### API skill + reference library\n\n| Skill | Purpose |\n| --- | --- |\n| [`formio-api`](./plugin/skills/formio-api/) | Single activatable skill covering every endpoint in the [Form.io API Postman collection](https://documenter.getpostman.com/view/684631/2sBXiok9LB) — platform admin, project admin, runtime/end-user, PDF. Activates on any Form.io REST question and navigates into the relevant reference doc. |\n\nThe endpoint detail lives under [`plugin/skills/formio-api/references/`](./plugin/skills/formio-api/references/) — one Markdown file per capability group (no frontmatter, not independently activatable, read via links from the router). The groups:\n\n- **Platform scope** (`${FORMIO_BASE_URL}/`): `platform-auth`, `platform-projects`, `platform-teams`, `platform-staging`, `platform-tenants`, `server-status`\n- **Project scope** (`${FORMIO_PROJECT_URL}/`): `project-auth`, `project-roles`, `project-forms`, `project-form-revisions`, `project-actions`\n- **Runtime scope** (`${FORMIO_PROJECT_URL}/`): `runtime-auth`, `runtime-custom-users`, `runtime-access-control`, `runtime-reports`, `runtime-submissions`\n- **PDF scope** (`${FORMIO_PROJECT_URL}/pdf-proxy/`): `pdf-api`\n\nTwo automated checks guard the skill library (both also run under the repo-wide `turbo run test`):\n\n- **Plugin bundle structure** — `pnpm --filter @formio/mcp test` runs [`packages/mcp-server/src/__tests__/plugin-build.test.ts`](./packages/mcp-server/src/__tests__/plugin-build.test.ts), which asserts the right skills ship in `dist/plugin/skills/` (e.g. `formio-api` and `formio-schema` present, the retired `formio-form` and the `openspec-*` / `tdd-*` skills excluded) and that `plugin.json` and the bundled stdio server are well-formed. (Run `pnpm build:plugin` first to populate `dist/plugin/`.)\n- **SDK example execution** — `pnpm --filter @formio/skill-tests test` runs the [`@formio/skill-tests`](./packages/skill-tests/) package, which executes the code examples shipped in `formio-sdk`'s reference docs against the real `@formio/js` / `@formio/core` at runtime, so a doc that drifts from the SDK's actual export shape fails a test with a pointer to the bad example.\n\nTerminology in the skills is strict (a convention, not test-enforced): `baseUrl`/`base_url` always means `FORMIO_BASE_URL`; `projectUrl`/`project_url` always means `FORMIO_PROJECT_URL`.\n\n---\n\n## MCP server tools\n\nThe bundled `@formio/mcp` server exposes these tools. Skills prefer these over raw HTTP whenever an operation is covered.\n\n### Forms\n\n| Tool | Purpose |\n| --- | --- |\n| `form_create` | Create a new form. Use the `formio-schema` skill first to build the JSON definition. |\n| `form_get` | Fetch a single form definition by ID or path. |\n| `form_list` | List forms with optional filtering and pagination. |\n| `form_update` | Update an existing form. Call `form_get` first, edit with `formio-schema`, then update. |\n| `form_revisions_list` | List the immutable published revision summaries for a form (`_vid`, `_id`, `modified`, `user`, `_vnote`). Requires form revisions to be enabled. |\n| `form_revision_get` | Fetch a single immutable form revision by `_vid` or revision document `_id`. |\n\n### Roles\n\n| Tool | Purpose |\n| --- | --- |\n| `role_create` | Create a new project role. |\n| `role_list` | List all project roles. |\n| `role_update` | Full-replacement update of a role. Include all fields you want preserved. |\n\n### Actions\n\n| Tool | Purpose |\n| --- | --- |\n| `action_types_list` | List all action types available on the server. |\n| `action_type_get` | Get an action type's settings schema. |\n| `action_create` | Attach a new action to a form. |\n| `action_list` | List actions on a form. |\n| `action_get` | Get a single action by ID. |\n| `action_update` | Update an action. |\n| `action_delete` | Detach an action from a form. |\n\n### Project\n\n| Tool | Purpose |\n| --- | --- |\n| `project_export` | Export the project's complete template (roles, resources, forms, actions) as a portable JSON document. Use before `project_import` to snapshot. |\n| `project_import` | Import a template JSON — additively merges roles, resources, forms, and actions in one call. **Same-machine-name items are overwritten in place; everything else is preserved.** |\n| `project_set` | Plugin-mode only — persist a per-cwd Project URL mapping in `~/.formio/projects.json`. Never exposed standalone (the standalone server binds to `FORMIO_PROJECT_URL` via env instead). |\n\n### Diagnostic\n\n| Tool | Purpose |\n| --- | --- |\n| `hello` | Smoke-test tool. Returns a static greeting; useful for verifying MCP wiring before any authenticated call. |\n\n---\n\n## Authentication\n\nThe MCP server supports two authentication modes:\n\n- **JWT mode (default).** A short-lived local Express server renders the Form.io portal login form; the user signs in once, the JWT comes back via a `/callback` endpoint, and `formioFetch` attaches `x-jwt-token` on every subsequent request. The flow is implicit — the **first authenticated tool call** triggers it on a cache miss. No explicit `authenticate` tool exists.\n- **API-key mode.** Set `FORMIO_API_KEY`. All requests attach `x-token`; the browser flow is skipped entirely.\n\n### Login-form auto-resolution\n\nWhen `FORMIO_LOGIN_FORM` is unset, the server probes these candidates on the first login attempt and caches the first one that responds (1.5-second timeout per candidate):\n\n1. `${FORMIO_BASE_URL}/formio/user/login` (portal-base)\n2. `${FORMIO_PROJECT_URL}/admin/login` (project admin)\n3. `${FORMIO_PROJECT_URL}/user/login` (project user)\n\nThe probe runs lazily — only when the local auth page is actually served.\n\n---\n\n## Environment variables\n\n| Name | Required | Default | Purpose | Hosted SaaS example | Self-hosted example |\n| --- | :-: | --- | --- | --- | --- |\n| `FORMIO_BASE_URL` | yes | — | Full base URL of your Form.io deployment. | `https://api.form.io` | `https://forms.example.com` |\n| `FORMIO_PROJECT_URL` | yes\\* | — | Full URL of your Form.io project. In plugin mode, only used as the pre-filled default offered when prompting for an unmapped cwd. | `https://myproject.form.io` | `https://forms.example.com/myproject` |\n| `FORMIO_API_KEY` | no | `undefined` | Long-lived project API key. When set, the server skips the browser login flow. | `CHANGEME` | `CHANGEME` |\n| `FORMIO_LOGIN_FORM` | no | Auto-resolved | Override the portal login form URL used by the JWT login flow. | `https://formio.form.io/user/login` | `https://forms.example.com/formio/user/login` |\n| `FORMIO_PLUGIN_CONTEXT` | no | `0` | Set by the plugin manifest. When `1`, the server enables `project_set` and reads `FORMIO_PROJECT_URL` from `~/.formio/projects.json` per cwd instead of env. |  |  |\n| `FORMIO_INSECURE_TLS` | no | `false` | When `true`, skips TLS certificate verification (sets `NODE_TLS_REJECT_UNAUTHORIZED=0`) — for self-hosted deployments behind self-signed certs. Do not use against production. | — | `true` |\n\n\\* In plugin context, `FORMIO_PROJECT_URL` is captured per-cwd by the `project_set` tool and persisted to `~/.formio/projects.json`. The `verify-project-url` `SessionStart`/`PreToolUse` hook offers `formio_default_project_url` (from plugin user-config) as the default the first time you enter a workspace.\n\n---\n\n## Development\n\nThis is a [pnpm](https://pnpm.io/) + [Turborepo](https://turbo.build/) monorepo.\n\n### Prerequisites\n\n- Node.js \u003e= 20\n- pnpm 10.x\n\n### Common commands\n\n```bash\npnpm install        # install workspace deps\npnpm build          # build all packages\npnpm dev            # run all packages in watch mode\npnpm test           # run all tests (Vitest across @formio/mcp + @formio/skill-tests + plugin build/smoke)\npnpm lint           # type-check all packages\npnpm format         # prettier --write .\npnpm clean          # clean build artifacts\npnpm build:plugin   # bundle the plugin into dist/plugin/\npnpm test:plugin    # run plugin smoke tests\n```\n\n### MCP server only\n\n```bash\npnpm --filter @formio/mcp dev         # start with hot reload (port 3000)\npnpm --filter @formio/mcp test        # run tests once\npnpm --filter @formio/mcp test:watch  # run tests in watch mode\npnpm --filter @formio/mcp build       # compile to dist/\n```\n\n### Skill SDK tests\n\n```bash\npnpm --filter @formio/skill-tests test   # run formio-sdk doc examples against the real @formio/js\n```\n\n[`@formio/skill-tests`](./packages/skill-tests/) executes the code examples in `formio-sdk`'s reference docs against the live SDK — a failing test means a reference doc has drifted from the SDK's actual surface. See [`packages/skill-tests/README.md`](./packages/skill-tests/README.md).\n\n### Definition of Done\n\nWork is not complete until all of the following pass:\n\n- **Tests** — `pnpm test`\n- **Type-check** — `pnpm lint`\n- **Formatting** — `pnpm format`\n\nTDD is mandatory. Write failing tests first, then implement the minimum code to make them pass.\n\n### Local plugin testing\n\nSee [`examples/basic-app/README.md`](./examples/basic-app/README.md) for the full local-plugin loop — building the plugin, registering the local marketplace, and exercising it from inside Claude Code without publishing to npm.\n\n### Iterating on skills\n\nSome skills (`formio-resource-planner`, `formio-angular`) ship their own eval harness under `evals/`. The standard layout:\n\n- `skills/\u003cskill\u003e/evals/evals.json` — test prompts + expected outputs\n- `skills/\u003cskill\u003e/evals/grade.py` — structural assertions; reads `.eval-artifacts/\u003cskill\u003e/iteration-N/` and writes `grading.json`\n- `skills/\u003cskill\u003e/evals/README.md` — teammate-facing runbook (seed fixtures → spawn subagents → grade → aggregate)\n\nWhen iterating on, testing, or measuring a skill change, **read that skill's `evals/README.md` first** — don't improvise. The standard loop is the same across skills, but each README documents skill-specific add-ons.\n\n---\n\n## Spec-driven development with OpenSpec\n\nThis project uses [OpenSpec](https://openspec.dev/) for spec-driven development. Specs live in `openspec/specs/` organized by capability; change proposals are generated in `openspec/changes/`.\n\n```bash\nnpm install -g @fission-ai/openspec@latest\n```\n\nWorkflow:\n\n1. **Explore** — read existing specs in `openspec/specs/` for context.\n2. **Propose** — `/openspec:propose` plans a change with design rationale, specs, and tasks before implementing.\n3. **Implement** — `/openspec:apply` works through the generated tasks.\n4. **Archive** — `/openspec:archive` finalizes a completed change.\n\n---\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformio%2Fai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fformio%2Fai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformio%2Fai/lists"}