Accelerator · Fuuz package
Fuuz for VS Code
Fuuz for VS Code (Open Beta) β connect VS Code to Fuuz over MCP: resources, ERDs, flows, data queries, installable platform skills, and UI validation in a real browser.
π§ͺ Open Beta β Part of the Fuuz Apps repository, which is in open beta. Actively developed and usable; features and APIs may change and you may hit rough edges.
Connect VS Code to your Fuuz environments. Add a connection from an API key, and the extension registers the Fuuz MCP server so your AI coding assistant β the Claude VS Code extension or GitHub Copilot agent mode β can work with your app, pulls in what the server exposes, and gives you runtime actions (execute flows, send webhooks).
Some features depend on your Fuuz subscription including MCP β see Subscription & feature availability.
Requirements
- VS Code 1.101+ (for the MCP server-definition API).
- A Fuuz API key for the tenant you want to connect (the key encodes the tenant/enterprise/environment). Keys can expire or be deactivated β the extension flags a rejected key and offers Replace API Key.
- For the AI features: an MCP-capable AI assistant β the Claude VS Code extension or GitHub Copilot agent mode β and a Fuuz subscription that includes MCP.
Install (team)
Share the packaged .vsix and install it:
code --install-extension fuuz-vscode-extension-<version>.vsix
(.vsix installs don't auto-update β re-run on new versions. See
Publishing for the Marketplace alternative.)
Tip: add
.fuuz/to your repo's.gitignore(the generatedAVAILABLE.mdis tenant-specific)..vscode/mcp.jsonis safe to commit β the token is referenced via a password prompt, not stored.
Permissions (important)
Connecting and listing MCP tools needs no special authorization β but using the tools (loading resources, querying data, running flows) requires the API key's API User to be authorized inside Fuuz, per tenant/app.
In each Fuuz tenant/app you want to use, assign a policy or policy group directly to the API User record that owns the key, granting at least the read/query actions for the modules the extension reads:
accessControlβ environment/current-user infoconfigurationβ module groups, modules, screens, the model catalogdataModelingβ data modelsorchestrationβ data flows- (plus any business modules whose data you want to Query Data Model)
To execute flows, send webhooks, or deploy, the API User also needs the corresponding write/execute permissions for those modules.
After granting policies, issue a new API key for that tenant and update the connection with Replace API Key. An existing key does not pick up newly-assigned policies β permissions are bound when the key is issued.
If the API User isn't authorized, the MCP server still lists the tools, so the MCP Tools section appears β but every data call is rejected with "not authorized to execute the query actionβ¦", leaving the Application, System Data Models, and Environment sections empty. The extension shows these denials under a "Couldn't load some resources" node and in the Fuuz output channel (View β Output β Fuuz). The fix is to grant the policy in Fuuz β it is not a VS Code/extension setting. Authorization is per tenant, so it must be assigned in each tenant/app separately.
Quick start
- Install the extension and open the Fuuz icon in the activity bar.
- Click Add Connection by API Key and paste a Fuuz API key.
- The extension decodes the key (tenant, enterprise and environment), validates it against the MCP server, stores the token securely, sets it active, and auto-loads resources into the Resources view.
That's it β no manual host/tenant entry. You can also run Fuuz: Add Connection by API Key from the Command Palette.
How a connection is defined
Each enterprise is identified by an environment slug β the {env}.{account}
segment of the host, e.g. build.mfgx or admin. Every endpoint derives from
https://api.{slug}.fuuz.app:
| Purpose | URL | Notes |
|---|---|---|
| MCP server | β¦/mcp |
Registered with VS Code; used to validate keys and load resources |
| Flow execution | β¦/orchestration/executeFlow |
Execute Flow action |
| Webhook | β¦/webhook/post/{topic} |
Send Webhook action |
When you onboard with an API key, the slug, tenant and enterprise are read from
the token's claims. Any endpoint can be overridden per enterprise in the config
panel (Edit environment & endpoints). Every call authenticates with the
tenant's Bearer token, stored in VS Code SecretStorage β never in
settings.json or source control.
GraphQL has no runtime endpoint. Saved queries/mutations are run by building a data flow that references the operation and executing that flow.
What you get
- Add by API key β auto-detects tenant/enterprise/environment, validates, and stores the token securely.
- Per-endpoint health β onboarding and the per-tenant Test endpoints action probe MCP, flow execution and webhook independently and show which are available for your key (hover a badge for the exact URL checked).
- Native MCP registration β each enabled tenant with a token is registered as
an HTTP MCP server so Copilot/agent mode can use it. Write MCP Server Config
also emits a portable
.vscode/mcp.json(the token is referenced via a passwordinput, not written to disk). - Register with Claude β VS Code's MCP registration is only visible to VS
Code's own Copilot; Claude reads its own config. Register MCP Server with
Claude writes the Fuuz servers into Claude Code (
.mcp.jsonand/or user~/.claude.json) and Claude Desktop. See Use with Claude. - Auto-loaded resources β on connect, the extension opens an MCP session and pulls the environment/context info and the catalog of available MCP tools into the Resources view.
- Runtime actions β Execute Flow (
{ flowId, payload }; also inline on Flow nodes) and Send Webhook ({topic}+ JSON body). Responses open in a JSON editor; theFuuzoutput channel logs each call. Flows are grouped by type (Edge / Webflow / Backend); web flows run in the Fuuz web UI, so Execute is hidden for them. - Connection management β set active, Replace key, Disable/Enable, and remove connections from the config panel.
- Agent tool control β the config panel's Agent Tools section lists the
tools the MCP server exposes β System (
system_*platform tools) and Custom (Data Flows) (data_flow_*and any tenant flow) β and lets you mark tools disabled. Disabled tools are flagged in the Resources tree and left out of the generated App Context File, steering your assistant away from them. (Servers register as direct streamable-HTTP; the former stdio gating proxy that hard-blocked calls has been removed.) Data models lazy-load their fields when expanded. - Fuuz skills for your assistant β Install Fuuz Skills copies the bundled
platform skills into
.claude/skills/, where your AI assistant discovers them by name: data models, flows and flow nodes, screens and screen elements, expressions, GraphQL, integration, styling β plus UI validation (below). Each of the three build areas carries a field notes reference of platform behaviour that fails silently, so your assistant does not rediscover it at your expense. See Skills. - UI validation in a real browser β Start UI Session opens one signed-in Chrome you log into once; Validate UI with Claude hands that same window to Claude over CDP, so it can drive the app, the designers and the screen runner without ever asking you to sign in again. See UI validation.
- App context file β Generate App Context File writes
.fuuz/AVAILABLE.md, a snapshot of the active tenant that your AI coding assistant can read.
Sidebar
The Fuuz activity-bar container has two stacked views:
- Connections β your enterprises and their tenants; click one to make it active. On a fresh install it shows a welcome with setup buttons.
- Resources β populated for the active tenant after a sync. With MCP it shows:
- Environment β context/tenant details from the server
- MCP Tools β the server's available tools (capabilities)
- the flow-configured module-group hierarchy when present:
moduleGroup
ββ module
β ββ screens
β ββ flows
β ββ data models
ββ documents
ββ scripts
ββ graphql (queries / mutations)
Use with Claude (Claude Code / Claude Desktop)
VS Code's MCP registration (registerMcpServerDefinitionProvider) is consumed
only by VS Code's own Copilot/agent mode β Claude can't see it. Each MCP
client reads its own config, so to make Fuuz reachable from Claude the extension
writes the servers into Claude's config files.
Automatic (default)
With fuuz.claudeAutoRegister set to userAndDesktop (the default), the
extension keeps Claude in sync for you: whenever you add a connection,
replace a key, or enable/disable one, it rewrites the Claude config. So
the whole flow is just connect an API key β restart Claude. No command, no
env vars, no copy/paste.
| Target | Where it writes | Token |
|---|---|---|
| Claude Code β user | ~/.claude.json |
Embedded (private home-dir config, mode 600, never committed) |
| Claude Desktop | claude_desktop_config.json |
Embedded as a direct streamable-HTTP entry |
The live token is embedded into these private files exactly the way every other
MCP server stores its auth β and it's refreshed automatically when you
Replace API Key. Set fuuz.claudeAutoRegister to user (Claude Code only)
or off (manual only) to change this. Only fuuz-* keys are managed; everything
else in the files is preserved.
Restart Claude after a change β Claude loads MCP servers at startup, so a running session won't see new/updated Fuuz servers until it's restarted.
Both Claude Code and Claude Desktop now receive a direct streamable-HTTP entry (embedded Bearer token) β no local Node proxy process is involved.
Project scope (shareable, opt-in)
Run Fuuz: Register MCP Server with Claude and also tick Claude Code β this
project to write a .mcp.json at the workspace root. This file is meant to be
committed and shared, so the token is never embedded β entries reference
Bearer ${FUUZ_TOKEN_<ENTERPRISE>_<TENANT>}. The command's Copy export
commands action copies the matching export FUUZ_TOKEN_β¦='<token>' lines to
your clipboard; paste them into your shell profile (e.g. ~/.zshrc) and restart
Claude.
A project-scope server shadows a user-scope server with the same name in Claude Code. If you commit a project
.mcp.json, make sure collaborators export the env vars, or that entry won't connect.
Skills
Fuuz: Install Fuuz Skills copies the bundled skills to .claude/skills/.
That is where Claude Code discovers project skills β the copy is also yours to
edit and commit, so a team can extend them.
| skill | covers |
|---|---|
fuuz-data-model |
model definitions, fields, relations, triggers, sequences, indices β plus deploy-rules.md |
fuuz-data-flow |
flow structure, environments, patterns β plus runtime-rules.md |
fuuz-data-flow-nodes |
every node type's exact data schema, by category |
fuuz-screen-design |
Craft.js node maps, transforms, queries, patterns β plus silent-failures.md |
fuuz-screen-elements |
per-element props, by category |
fuuz-screen-styling |
the design-system tokens and how styles resolve |
fuuz-expressions |
JSONata and JavaScript in the platform, and the context bound to each |
fuuz-graphql |
queries, predicates, pagination |
fuuz-integration |
connectors, REST, databases |
fuuz-ui-validation |
driving the real UI in a real browser (below) |
The three field-notes files are the part that saves the most time. They document platform behaviour that produces no error β where a deploy reports success and serves an incomplete schema, a flow runs and writes nothing, or a screen renders blank. Each entry was found by a failure on a live tenant, so your assistant can recognise the symptom instead of debugging its own correct code. A few examples of what they will stop you losing an afternoon to:
- A data-model name may not contain digits, and may not end in
Node,EdgeorDocument. AnIDfield's name must end inIdβ and the error names neither the field nor which of the two identifiers to change. - Deployment is asynchronous, and a reverse collection to a not-yet-deployed child
is dropped silently. The only proof a deploy worked is introspecting
<Name>Node { fields }. The most recently deployed version serves, not the highest number. - A flow's request payload is out of scope after the first node, so a
modegate written after an HTTP call is always false β every run becomes a silent dry run that reports success. - The node type is
mutate, notmutation. An invalid type deploys clean, reportsdeployed: true, and then answersNotFoundError, which reads like a propagation problem. - A screen component missing
type: "canvas"deploystrueand renders a completely empty page; an element missingelementNameis dropped; a filter form with nothing callingfn.search()filters nothing. format: "currency"ignoresformatString, and numeral's%multiplies by 100 β so a percentage stored as80renders as8000%.
UI validation: a real, signed-in browser
Pushing a screen over MCP proves the platform accepted it. It does not prove it renders, binds, queries or saves β and a screen can deploy clean and render blank with no error at all. So the extension makes "go and look" a two-command job.
1. Fuuz: Start UI Session (Browser) β installs the harness into .fuuz/ui,
then opens a headed Chrome with its own persistent profile and the DevTools port
open. Sign in once and leave the window open. The browser is spawned
detached, so it outlives the command β a browser launched as a child process
would die with it, and the next attach would look like a failed login.
2. Fuuz: Validate UI with Claude β describe what to check. The extension
writes an MCP config that points the Playwright MCP at that already-signed-in
window (--cdp-endpoint), adds your tenant's Fuuz MCP so the agent can verify by
reading the record back, and launches Claude with the fuuz-ui-validation skill.
Choose whether it confirms before writes or runs with full authority.
Why attach instead of launching a fresh browser: a second Chrome comes up signed out, and an agent that meets a login page tends to report it as a broken screen. Attaching also means the session survives between sessions β you log in in the morning, not per task.
The same session is drivable from the terminal, which is the right tool for a loop or a whole-panel read:
node .fuuz/ui/fuuz-ui.cjs status # alive? which tenant/role?
node .fuuz/ui/fuuz-ui.cjs open 'screen:<versionId>' # the screen-runner route
node .fuuz/ui/fuuz-ui.cjs console 'screen:<id>' --for 20
node .fuuz/ui/fuuz-ui.cjs shot 'screen:<id>' shots/loaded.png
node .fuuz/ui/fuuz-ui.cjs run probes/my-probe.cjs # your script gets the live page
Needs an installed Chrome/Chromium/Edge and the playwright package resolvable
from the workspace (npm i -D playwright) β the session uses your system
browser over CDP, so Playwright's downloaded browsers are not required.
What the skill insists on, because each cost a real session to learn: one profile reused in place (cloning it retires the session it copies); a login form is an abort, never a retry, because every read after one comes back empty and looks like a broken feature; and verification is reading the record back, never looking at the canvas β a designer save can complete with no error and create nothing.
.fuuz/ui/profile/ holds a live session and is gitignored for you. Nothing is
written to disk that a screenshot would not show, and the tenant token is passed
on the terminal environment, referenced by name in the MCP config.
Subscription & feature availability
The Fuuz MCP server is gated by your subscription. If your subscription does not include MCP, MCP-dependent features are unavailable:
- registering the Fuuz MCP server for your AI copilot,
- automatic resource loading (environment + tool catalog),
- validating a key via the MCP handshake.
A connection's Test endpoints badges show exactly which endpoints your key can reach. When MCP isn't available, you can still configure connections and use flow execution / webhooks (subject to your key's permissions), and the Resources view falls back to a manual state β you provide resource details by configuring flows in Fuuz. Per-endpoint results can also differ by key: a key may be valid for MCP but not for flow/webhook (or vice-versa), and the badges make that explicit.
Separately from your subscription, what the extension can load depends on the API User's authorization in Fuuz β see Permissions. MCP reachable but resources empty almost always means the API User lacks the read/query policy in that tenant.
Commands
- Fuuz: Add Connection by API Key β onboard a connection from a key
- Fuuz: Configure Connections β open the connection management panel
- Fuuz: Select Active Tenant β quick-pick the active enterprise/tenant
- Fuuz: Sync Tenant Data β refresh the Resources view for the active tenant
- Fuuz: Restart Fuuz MCP β drop pooled MCP sessions, re-resolve the registered servers, and re-sync β recover a stale connection without reloading the window
- Fuuz: Show ERD / Show Module ERD / Show Application ERD β interactive entity-relationship diagrams (drag nodes, expand fields, persisted layout)
- Fuuz: Find Data Model β quick-pick search that opens a model's ERD
- Fuuz: Query Data Model β read-only data query (pick fields + JSON filter)
- Fuuz: Execute Flow β run a data flow
- Fuuz: Send Webhook β post to a webhook topic
- Fuuz: Deploy Component Version β guarded deploy (screen / data flow / data model / saved transform); off until you enable
fuuz.enableDeploy - Fuuz: Open in Fuuz β open the active tenant's app
- Fuuz: Write MCP Server Config (.vscode/mcp.json) β emit/refresh workspace MCP config
- Fuuz: Register MCP Server with Claude β write the Fuuz servers into Claude Code / Claude Desktop config
- Fuuz: Install Fuuz Skills (for your AI assistant) β copy the bundled skills to
.claude/skills/ - Fuuz: Start UI Session (Browser) β one signed-in Chrome for UI validation; log in once, leave it open
- Fuuz: Validate UI with Claude β hand that window to Claude over CDP with the
fuuz-ui-validationskill - Fuuz: Generate App Context File β write
.fuuz/AVAILABLE.md - Fuuz: Replace API Key / Open Settings
Troubleshooting
- Key reports unauthorized / "not active" β the per-endpoint badges show the HTTP status and server message per endpoint. An inactive/expired key returns 401; request a fresh key.
- Only "MCP Tools" show / Application & data models empty β the API User isn't authorized in that tenant. Open the "Couldn't load some resources" node (or View β Output β Fuuz); messages like "not authorized to execute the query action on β¦ in the configuration module" tell you exactly which modules to grant. Assign the read/query policy/policy group to the API User in Fuuz for that tenant β see Permissions β then Sync Tenant Data.
- Resources view still empty after granting access β run Sync Tenant Data (it clears caches). If MCP itself isn't available for your subscription, the view falls back to a manual state; configure flows in Fuuz instead.
- MCP server not appearing for Copilot β confirm the tenant is enabled (not
disabled) and has a token, then reload the window. You can also run Write MCP
Server Config to materialize
.vscode/mcp.json.
Development
npm install # install dev dependencies
npm run compile # tsc β dist/ AND bundle the ERD webview β media/erd/
npm run watch # rebuild extension host on change
npm run watch:webview # rebuild the ERD webview on change
npm run lint # eslint
npx @vscode/vsce package --no-dependencies # build a .vsix
The extension host has no runtime dependencies β it uses the VS Code API
and the runtime's global fetch. The ERD webview is a separate React + React
Flow app under src/webview/erd/, bundled by esbuild into media/erd/ (a build
asset, like an image); React etc. are devDependencies, not host runtime deps.
Requires VS Code 1.101+ (for the MCP server definition API). Run npm test
for the unit suite (pure parsing/derivation/ERD helpers, via node:test).
Publishing
Distribute the .vsix directly, or publish under the cscott publisher:
npx @vscode/vsce login cscott # one-time, needs a Marketplace PAT
npx @vscode/vsce publish
publisher is intentionally personal (not the company) so it isn't tied to an
org SLA. To re-home it, change publisher in package.json.
Architecture
- Services
tenantConfigurationManager.tsβ enterprises/tenants in settings; endpoint derivationtokenStore.tsβ tokens in SecretStorageconnectionImporter.tsβ decode JWT, validate, upsert connectionfuuzMcpClient.tsβ MCP session (initialize/tools), endpoint probing, MCP snapshotfuuzApiClient.tsβ flow execution / webhook POST clientmcpServerProvider.tsβ registers Fuuz MCP servers with VS CodemcpJsonWriter.tsβ generates.vscode/mcp.jsonclaudeMcpWriter.tsβ registers the Fuuz servers into Claude Code / Claude Desktop configcontextDocWriter.tsβ generates.fuuz/AVAILABLE.mdtenantDataService.tsβ sync + cache resourcesworkspaceAssets.tsβ installs the bundled skills to.claude/skills/and the UI harness to.fuuz/ui- Providers:
tenantSelectorProvider.ts(Connections),resourceTreeProvider.ts(Resources) - UI:
ui/configPanel.ts(webview),ui/statusBar.ts,ui/runtimeCommands.ts,ui/erdPanel.ts(hosts the ERD webview) - ERD webview:
src/webview/erd/β React + React Flow app, bundled tomedia/erd/by esbuild; consumes theErdGraphfromutil/erdTypes.ts - QA / UI:
qa/driver.ts(per-run headed QA browser),qa/uiSession.ts(the reusable signed-in session Claude attaches to over CDP) - Bundled assets:
resources/skills/(installed as project skills),resources/ui-harness/(installed as.fuuz/ui) - Entry point:
extension.ts
License
See LICENSE file in the root of the repository.