npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

webflow-mcp

v0.4.0

Published

WebFlow MCP MVP with local flow workspaces and MCP tool exposure

Downloads

603

Readme

WebFlow MCP

Local worker and unified MCP gateway for the WebFlowMCP signed remote automation catalog. A legacy local-authoring mode can still discover .webflow/flows/* and expose each valid flow directly.

Requirements

  • Node 20+
  • npm 10+

SaaS quickstart

npm install -g webflow-mcp

Pair this computer once. The CLI creates both scoped credentials locally: the worker credential stays in the existing owner-only file and the MCP token is stored in the operating system credential manager.

webflow login --app https://app.webflowmcp.es
webflow login --status

Then register the local stdio gateway in your user-global MCP client configuration. For OpenCode:

{
  "mcp": {
    "webflow": {
      "type": "local",
      "command": ["webflow-mcp"]
    }
  }
}

No literal token is needed in supported local stdio clients. Advanced or ephemeral environments may still set both WEBFLOW_RELAY_MCP_URL and WEBFLOW_RELAY_MCP_TOKEN; explicit environment values take priority. To use a separately paired staging endpoint, set only WEBFLOW_RELAY_MCP_URL and the gateway reads that endpoint's token from the OS credential manager. The worker never inherits the MCP token. Start and stop it through start_worker/stop_worker.

Gateway mode exposes a stable catalog surface rather than one dynamic tool per saved flow. Discover with browse_catalog/search_flows, inspect with describe_flow, and execute saved flows with run_flow_with_options. The machine-local repertoire is stored in ~/.webflow/repertoire.json; saving a flow does not create a dynamic MCP tool.

Normal synchronous calls are the primary execution path: they wait and return the final result, including for flagship flows certified for up to 30 minutes. The relay hard job budget is 31 minutes and the local gateway relay-call budget is 32 minutes. The timeout imposed by the external MCP host/caller is outside WebFlowMCP; configure that host for at least 35 minutes where it exposes such a setting. WebFlowMCP sends immediate progress plus a bounded heartbeat while synchronous work is running.

Use start_flow_run only as a fallback for MCP hosts with incompatible caller limits or for disconnect recovery. It returns an exe_... run ID after worker-local durable acceptance without waiting for completion. Use list_recent_flow_runs to recover an ID after a lost response. Production/staging ownership survives relay restarts through Postgres; standalone mode keeps ownership only for the relay process lifetime. Use get_flow_run_status, get_flow_run_result, or cancel_flow_run afterward. Full results are retained only in the expiring worker-local spool (WEBFLOW_RUNS_DIR or ~/.webflow/runs), never in relay/Postgres.

CLI

webflow init
webflow create flow checkout
webflow fork checkout checkout-copy

The workspace contract is:

.webflow/
  flows/
    _template/
    <flow>/
      schema.json
      index.ts
  skills/

Provider profiles are machine-global under ~/.webflow/profiles/; they are not part of a workspace.

Authoring a flow

For development from this repository:

npm install
npm run build

Each flow must export run(ctx, input) from index.ts and define a supported JSON-schema subset in schema.json:

export async function run(ctx, input) {
  return { flow: ctx.flowName, echoed: input.message };
}

Flows with their own input.timeoutMs may declare signed capabilities.executionTimeoutMs. It must be an integer from 1 second through 30 minutes, and runtime rejects input values above that certified bound.

Supported schema keys: type, properties, required, items, enum, description, default.

Legacy local-authoring MCP

The projectRoot argument is the absolute path to the repo you are working in — it decides where downloads land. The flows themselves do not need to live there: if projectRoot has no .webflow/flows, the server automatically uses the flows shipped with this package (Model B). So a single flows repo serves many working repos, and each repo keeps its own outputs.

During development from this repo:

node --import tsx src/mcp/cli.ts /absolute/path/to/your-working-repo

Or after building:

npm run build
node dist/src/mcp/cli.js /absolute/path/to/your-working-repo

For MCP client configuration from another repo, point the entrypoint at this package and the argument at that repo. Flows come from here; downloads stay in that repo:

{
  "mcpServers": {
    "webflow": {
      "command": "node",
      "args": [
        "C:/absolute/path/to/webflow-mcp/dist/src/mcp/cli.js",
        "C:/absolute/path/to/your-other-repo"
      ]
    }
  }
}

To override where flows are loaded from, set WEBFLOW_FLOWS_DIR to a workspace that has .webflow/flows. The server falls back to CLAUDE_PROJECT_DIR then cwd when no argument is given, and prints which flows root, session store, and downloads dir it resolved as startup diagnostics.

On Windows, run-mcp.bat is only a local helper. It requires npm run build first and expects the workspace root as its first argument:

run-mcp.bat C:\absolute\path\to\workspace

Doctor

Use doctor before wiring MCP from another repo:

webflow doctor /absolute/path/to/workspace
node dist/src/cli/index.js doctor /absolute/path/to/workspace

doctor checks Node, the workspace layout, exposed flows, parseable schemas, build output, Playwright/Chromium availability, and warns about fragile flow patterns such as fixed CDP port 9222, taskkill, Profile 1, process.cwd(), hardcoded Windows paths, or connectOverCDP.

Sessions vs downloads

Two things are deliberately decoupled:

  • Login sessions are global. Chrome profiles live in one shared store, default ~/.webflow/profiles (override with WEBFLOW_PROFILES_DIR). Log in once and every workspace reuses the session — you do not re-authenticate per repo.
  • Downloads are per-repo. Each flow writes to <projectRoot>/.webflow/downloads/<flow>/..., so outputs are organized by the workspace you ran from. Point the MCP server's projectRoot at a repo and that repo collects its own downloads while sharing the global login.

The MCP server prints both locations as diagnostics on startup.

Browser Flow Setup

Run webflow setup <flow> once per profile to log in. By default this opens a plain real Chrome window with no automation flags, pointed at the flow's dedicated global profile. Log in, accept any prompts, then close the window — the session persists and is reused by automated runs. This avoids the "unsafe browser" block that strict providers raise against automation-controlled login windows.

webflow setup chatgpt-prompt
webflow setup google-speech-generate --url https://aistudio.google.com

Flows share a profile by declaring the same capabilities.profile (for example chatgpt-prompt and chatgpt-image-generate both use chatgpt), so one login covers the whole provider.

Browser modes

A flow declares how it drives the browser via capabilities.browser:

  • true / 'managed' — Playwright-managed persistent profile (default). Clean, isolated, works headless from any repo. Used by ChatGPT, Gemini app, X, and the scrapers.
  • 'cdp' — the runner attaches to a real Chrome over CDP. Used by strict providers (google-speech-generate for Google AI Studio, adobe-lipsync). The runner launches Chrome against the dedicated profile on a free port, connects, and closes that window when the flow finishes (it owns what it launched). If you instead attach to a Chrome you already had open via cdpUrl, it only disconnects and leaves your window alone. Optional per-run overrides: cdpUrl, chromePath, userDataDir.

Flows consume ctx.page/ctx.browser and are mode-agnostic, so switching a flow between managed and cdp needs no code changes.

Verifying whether a strict provider can use the managed profile

'cdp' is the proven path for AI Studio/Adobe; the managed profile is unverified there. To test whether managed + one-time login is enough (and unify on a single mechanism), run a cdp flow once with:

# PowerShell:  $env:WEBFLOW_CDP_AS_MANAGED = '1'
WEBFLOW_CDP_AS_MANAGED=1 webflow run google-speech-generate --headed --input '{ ... }'

If the provider accepts the login, switch that flow's capabilities.browser to 'managed'. If it rejects, leave it on 'cdp'.

Running multiple agents in parallel

A Chrome user-data-dir can be opened by only one process at a time, so parallel agents cannot share one profile directory. Set WEBFLOW_PROFILE_INSTANCE=<id> per agent: the runner clones the logged-in base profile into a per-instance directory on first use. Off by default (a single agent reuses the shared base profile). Note that some providers may then ask the extra session to re-verify as a new device.

Signed remote flows

Official relays send immutable Ed25519-signed flow releases. The worker verifies the relay-bound public key, manifest and exact code/schema/capability hashes before importing any code. Every new flow digest also requires an explicit local decision. Through the unified MCP, call list_flow_approvals, inspect the full digest/signer/trust domain, ask the user, and then call approve_flow_update with the exact returned identity and confirmed:true. The interactive CLI remains available:

webflow approvals list
webflow approvals approve <flow> --trust-domain <domain>
webflow approvals revoke <flow> --trust-domain <domain>

The remote relay cannot approve a release; MCP approval tools mutate only worker-local state. Their confirmed:true argument is a user-interaction convention, while typing APPROVE in the CLI remains the stronger manual path. Flow source is not installed as a local catalog, but code executed on a user-controlled computer cannot be made impossible for that computer's owner to capture. Signed code still has the worker process's OS permissions; this release does not add a sandbox. Signing keys and release commands are operator-only; end users never generate or manage signing keys.

Verification

npm test
npm run smoke
npm pack --dry-run --json