New:Socket for Asana Is Now Available.Learn more
Get Started

@formio/mcp

Package Overview
Dependencies
Maintainers
7
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@formio/mcp - npm Package Compare versions

Comparing version
0.9.0
to
0.10.0
+39
-0
dist/auth.d.ts

@@ -5,3 +5,42 @@ import { ResolvedFormioConfig } from './config.js';

}
/**
* Every CDN asset the login page loads, with the Subresource Integrity digest of
* the exact bytes each URL is expected to serve. This page handles the user's
* portal credentials, so a third-party script on it is pinned twice: to a version
* (jsDelivr serves that release forever) and to a hash (the browser refuses the
* file if the bytes differ).
*
* The digests are data, not decoration — nothing here recomputes them at run time,
* and no test can tell a correct hash from a plausible one by looking. A wrong or
* stale digest costs the whole login flow: the browser blocks the renderer,
* `Formio.createForm` throws `ReferenceError: Formio is not defined`, nothing is
* ever POSTed to /callback, and `authenticate` hangs on a blank page until it
* times out. So the pairs live in one list with one job — `pnpm sync:sri` fetches
* each URL, digests what it gets, and rewrites this list when a bump changes it;
* `pnpm sync:sri --check` verifies it, and login-asset-integrity.test.ts runs that
* check whenever the network is reachable.
*
* The Open Sans stylesheet is deliberately absent. Google Fonts serves
* per-browser CSS, so its bytes vary by request and no fixed digest can match;
* it also carries no script and only chooses a typeface.
*/
export declare const LOGIN_PAGE_ASSETS: {
readonly bootstrapCss: {
readonly url: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css";
readonly integrity: "sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB";
};
readonly bootstrapIconsCss: {
readonly url: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.css";
readonly integrity: "sha384-Bk5cbLkZQ5raZ0+H2/+VbfYx3WpvxvQK4zqXZr7sYODuaX7bKXoSOnipQxkaS8sv";
};
readonly formioCss: {
readonly url: "https://cdn.jsdelivr.net/npm/@formio/js@5.5.1/dist/formio.form.min.css";
readonly integrity: "sha384-/zfd6nkJxXzqXliV/Jlki/NOl+E/K7FujopWT3gKLYXMlIwiratcqMESMZG9ICY2";
};
readonly formioJs: {
readonly url: "https://cdn.jsdelivr.net/npm/@formio/js@5.5.1/dist/formio.form.min.js";
readonly integrity: "sha384-WI14pf615veSnkFtQYllUINR9h5mP1ukKxI47QtGb9DVDYvZlUeaOnWpK/G23Z5x";
};
};
export declare function resetLoginFormCache(): void;
export declare function authenticate(config: ResolvedFormioConfig, options?: AuthenticateOptions): Promise<string>;
+49
-4

@@ -11,2 +11,47 @@ import express from 'express';

const DEFAULT_AUTH_TIMEOUT_MS = 15 * 60 * 1000;
/**
* Every CDN asset the login page loads, with the Subresource Integrity digest of
* the exact bytes each URL is expected to serve. This page handles the user's
* portal credentials, so a third-party script on it is pinned twice: to a version
* (jsDelivr serves that release forever) and to a hash (the browser refuses the
* file if the bytes differ).
*
* The digests are data, not decoration — nothing here recomputes them at run time,
* and no test can tell a correct hash from a plausible one by looking. A wrong or
* stale digest costs the whole login flow: the browser blocks the renderer,
* `Formio.createForm` throws `ReferenceError: Formio is not defined`, nothing is
* ever POSTed to /callback, and `authenticate` hangs on a blank page until it
* times out. So the pairs live in one list with one job — `pnpm sync:sri` fetches
* each URL, digests what it gets, and rewrites this list when a bump changes it;
* `pnpm sync:sri --check` verifies it, and login-asset-integrity.test.ts runs that
* check whenever the network is reachable.
*
* The Open Sans stylesheet is deliberately absent. Google Fonts serves
* per-browser CSS, so its bytes vary by request and no fixed digest can match;
* it also carries no script and only chooses a typeface.
*/
export const LOGIN_PAGE_ASSETS = {
bootstrapCss: {
url: 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css',
integrity: 'sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB',
},
bootstrapIconsCss: {
url: 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.css',
integrity: 'sha384-Bk5cbLkZQ5raZ0+H2/+VbfYx3WpvxvQK4zqXZr7sYODuaX7bKXoSOnipQxkaS8sv',
},
formioCss: {
url: 'https://cdn.jsdelivr.net/npm/@formio/js@5.5.1/dist/formio.form.min.css',
integrity: 'sha384-/zfd6nkJxXzqXliV/Jlki/NOl+E/K7FujopWT3gKLYXMlIwiratcqMESMZG9ICY2',
},
formioJs: {
url: 'https://cdn.jsdelivr.net/npm/@formio/js@5.5.1/dist/formio.form.min.js',
integrity: 'sha384-WI14pf615veSnkFtQYllUINR9h5mP1ukKxI47QtGb9DVDYvZlUeaOnWpK/G23Z5x',
},
};
function styleTag(asset) {
return `<link rel="stylesheet" href="${asset.url}" integrity="${asset.integrity}" crossorigin="anonymous">`;
}
function scriptTag(asset) {
return `<script src="${asset.url}" integrity="${asset.integrity}" crossorigin="anonymous"></script>`;
}
function buildLoginPage(loginFormUrl) {

@@ -19,5 +64,5 @@ const domain = new URL(loginFormUrl).hostname;

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://cdn.form.io/js/5.2.2/formio.full.min.css">
${styleTag(LOGIN_PAGE_ASSETS.bootstrapCss)}
${styleTag(LOGIN_PAGE_ASSETS.bootstrapIconsCss)}
${styleTag(LOGIN_PAGE_ASSETS.formioCss)}
<style>

@@ -45,3 +90,3 @@ body { font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; background: #fff; margin: 0; padding: 2rem 1rem; color: #333; }

</div>
<script src="https://cdn.form.io/js/5.2.2/formio.form.min.js"></script>
${scriptTag(LOGIN_PAGE_ASSETS.formioJs)}
<script>

@@ -48,0 +93,0 @@ var statusEl = document.getElementById('status');

+1
-1
{
"name": "@formio/mcp",
"version": "0.9.0",
"version": "0.10.0",
"mcpName": "io.form/formio-mcp",

@@ -5,0 +5,0 @@ "description": "Form.io MCP Server",

@@ -22,3 +22,3 @@ ## Formio MCP server

| --- | --- | --- |
| stdio | `npx -y @formio/mcp` (or `node dist/stdio.js`) | Claude Code, Claude Desktop, Cursor, VS Code, Codex, Windsurf, Cline — anything that speaks MCP over stdio |
| stdio | `npx -y @formio/mcp@0.10.0` (or `node dist/stdio.js`) | Claude Code, Claude Desktop, Cursor, VS Code, Codex, Windsurf, Cline — anything that speaks MCP over stdio |

@@ -36,3 +36,3 @@ There is no HTTP or SSE transport. The server's only HTTP listener is the temporary browser-login page described under [Authentication](#authentication), which carries no MCP traffic.

"command": "npx",
"args": ["-y", "@formio/mcp"],
"args": ["-y", "@formio/mcp@0.10.0"],
"env": {

@@ -290,3 +290,3 @@ "FORMIO_PROJECT_URL": "https://your-project.form.io"

<sub>\* Not at startup — the server starts, lists every tool, and answers `hello` without it; only the tools that read or write Form.io data error, naming `project_set` and this variable. The alternative is the `project_set` tool, which maps a working directory to a project in `~/.formio/projects.json`. Resolution order: `FORMIO_PROJECT_URL`, then the mapping for the caller's `cwd`, then the error. Map a directory before any client connects with `npx -y @formio/mcp project set --project-url <url> --base-url <url> --cwd <path>`; `project get --cwd <path>` prints what resolves and which source won. It exits `0` when it resolved, `1` when nothing is mapped for that directory, and `2` when the command could not answer (a usage error, a malformed URL, an unreadable `~/.formio/projects.json`) — so a caller can tell "nothing here yet" from "this failed".</sub>
<sub>\* Not at startup — the server starts, lists every tool, and answers `hello` without it; only the tools that read or write Form.io data error, naming `project_set` and this variable. The alternative is the `project_set` tool, which maps a working directory to a project in `~/.formio/projects.json`. Resolution order: `FORMIO_PROJECT_URL`, then the mapping for the caller's `cwd`, then the error. Map a directory before any client connects with `npx -y @formio/mcp@0.10.0 project set --project-url <url> --base-url <url> --cwd <path>`; `project get --cwd <path>` prints what resolves and which source won. It exits `0` when it resolved, `1` when nothing is mapped for that directory, and `2` when the command could not answer (a usage error, a malformed URL, an unreadable `~/.formio/projects.json`) — so a caller can tell "nothing here yet" from "this failed".</sub>

@@ -314,3 +314,3 @@ ---

**Third parties.** The server contacts no third-party service. One exception is worth naming: the browser sign-in page is rendered from a local page that loads styling and the Form.io renderer from `cdn.form.io`, `cdn.jsdelivr.net`, and `fonts.googleapis.com`, so those hosts see your browser's IP address while that page is open. Set `FORMIO_API_KEY` to skip the browser flow entirely and avoid it.
**Third parties.** The server contacts no third-party service. One exception is worth naming: the browser sign-in page is served locally, and the page it renders loads the Form.io renderer and its stylesheets from `cdn.jsdelivr.net`, a webfont from `fonts.googleapis.com`, and the Form.io logo from `portal.form.io`, so those hosts see your browser's IP address while that page is open. Everything else on the page comes from your own deployment. Set `FORMIO_API_KEY` to skip the browser flow entirely and avoid it.

@@ -317,0 +317,0 @@ **Retention.** The files above persist until you delete them. Data held in your Form.io project is governed by your own deployment's retention rules, and by the policy linked above for Form.io-hosted projects.