Skip to content

Getting started with Flowbrew

Flowbrew turns plain-language workflow descriptions into versioned Cloudflare Workflows and lets those workflows call plugin-provided actions. This page is a short map for someone operating Flowbrew through MCP and then moving on to plugin development.

For exact tool names and inputs, see the MCP reference.

A workspace is the top-level authorization and isolation boundary. An API key or OAuth identity resolves to one workspace, and MCP operations derive that workspace from the credential rather than accepting a caller-supplied workspace ID.

A project is an organizational scope inside a workspace. A workflow may belong to one project or remain workspace-global; deleting a project is blocked while workflows still reference it. Project-scoped connections and triggers can only be used with workflows in the same project, while workspace-scoped resources can be used across the workspace where the operation permits it.

A workflow is created first as a metadata-only shell with a workspace-unique name and an optional project. Each successful description-driven update compiles and publishes a new version, and new instances start from the current version while existing instances retain the version on which they began.

A plugin is a versioned manifest containing bricks, connection types, and trigger definitions. Public plugins are visible to every workspace; private plugins are owned by and installed into the workspace that uploads them.

A brick is a plugin-provided action with an HTTPS endpoint plus input and output schemas. A brick can declare named connection slots, and generated workflow code invokes it by the stable <plugin-slug>.<brick-slug> ID.

A connection type belongs to a plugin version and defines a credential schema, optional fixed plugin configuration, and a same-plugin validation brick. A connection is a user’s encrypted credential instance of that type, scoped to the workspace or to one project; credential creation and rotation happen in the web console.

A plugin manifest declares trigger definitions with lifecycle endpoints, configuration and event schemas, and optionally one required connection type. An MCP-created trigger instance is workspace- or project-scoped, and a trigger subscription connects that instance to a workflow; each instance accepts at most five subscriptions.

  1. Sign in to the web console at https://console.flowbrew.app (or your deployment’s console URL) and create or select a workspace.
  2. Create a workspace API key in API Keys. The raw key is shown only once.
  3. Point an MCP client at https://mcp.flowbrew.app/mcp (or your deployment’s own /mcp endpoint) and authenticate with that key as a bearer token. A deployment with the OAuth bridge enabled can authenticate an MCP client through OAuth instead.

For local or scripted calls from a repository checkout, the repository helper reads the local SST output by default and accepts TASKFLOW_MCP_URL for your Flowbrew MCP endpoint and TASKFLOW_API_KEY for your Flowbrew workspace API key:

Terminal window
TASKFLOW_MCP_URL='https://mcp.flowbrew.app/mcp' \
TASKFLOW_API_KEY='<your-flowbrew-api-key>' bun run mcp:call list_projects '{}'

The current product boundary is:

  • The web console creates and manages workspaces/organizations, membership and invitations, and raw API keys. It also creates, rotates, revokes, and purges credential-bearing connections.
  • MCP owns workflow and trigger-instance/subscription lifecycle. It also owns project lifecycle and can list or revoke existing API keys.
  • MCP can list connection metadata and create a credential-less pending connection with create_connection, but cannot create or rotate credentials. The console does not currently expose workflow or trigger lifecycle routes.

That boundary is slightly less absolute than “all API-key management is in the console”: list_api_keys and revoke_api_key are live MCP tools, but creating a key (and receiving its one-time raw value) remains a console operation.

The normal order is shell, deployment, start, then status polling.

Use list_projects if the workflow should be project-scoped. list_plugins shows visible plugins and their connection types, brick contracts, and trigger definitions. list_connections returns metadata for connections usable at workspace scope or in a selected project.

list_connections requires an explicit projectId: pass null for only workspace-scoped connections, or a project ID for workspace connections plus connections belonging to that project.

Call create_workflow with a name and, optionally, projectId. The result has currentVersionName: null and currentVersionNumber: null; it cannot be started until code is deployed.

Call update_workflow with the shell’s id and a plain-language description. Flowbrew supplies the code generator with the visible brick catalog and the configured connections allowed for the workflow’s scope.

Generation produces a complete TypeScript file, not a patch. The candidate is compiled but not executed; a generation or compilation failure leaves the currently deployed version unchanged.

Name and project changes use the same tool in a separate metadata-only call. Do not combine description with name or projectId.

Call start_workflow with either workflowId or name, a non-empty idempotencyKey, and an optional JSON payload. Caller payload becomes event.payload.input inside the workflow.

The idempotency key is workspace-scoped. Retrying with the same key returns the same instance rather than intentionally starting another one, so use a new key for each new logical run.

start_workflow returns an instanceId immediately; it does not wait for the workflow to finish.

Pass the instanceId to read_instance. One call can long-poll for about 50 seconds and returns the current status, plus output or error when available. Use list_instances to rediscover recent instances or filter them by workflow.

There is no separate “add brick” MCP mutation. Create and validate the connection in the web console, use list_connections to obtain its ID, then describe the desired plugin action in a description-driven update_workflow. Flowbrew generates the brick call and binds required named slots to literal connection IDs; compilation rejects missing, unknown, wrongly typed, or out-of-scope bindings.

Only configured workspace connections and configured connections belonging to the workflow’s project are offered to workflow generation. A workspace-global workflow cannot use a project-owned connection.

Choose a trigger definition from list_plugins, then call create_trigger_instance with its id as triggerDefinitionId and:

  • scope: "workspace" and projectId: null, or scope: "project" and the matching project ID;
  • configuration that matches the definition’s schema; and
  • either the required compatible connectionId or null for a connectionless definition.

Creation calls the plugin’s registration endpoint and becomes active only after the plugin acknowledges it. Then call create_trigger_subscription with the returned trigger-instance ID and the workflow ID. A project-scoped trigger can subscribe only workflows in that project; a workspace-scoped trigger can subscribe workflows anywhere in its workspace.

Call list_trigger_subscriptions, optionally filtered by triggerInstanceId and/or workflowId, to find an existing subscription’s ID before calling delete_trigger_subscription. Remove subscriptions before deleting their trigger instance or workflow.

Start with these code-backed references:

  • packages/plugin-sdk/README.md is the SDK quickstart for manifests, brick handlers, typed connections, trigger lifecycle handlers, and event delivery.
  • packages/e2e-fixture-plugin/src/index.ts contains copyable brick manifests, handlers, and request routing. The smaller trigger-fixture.ts and trigger-fixture-worker.ts show a minimal trigger manifest, lifecycle handler, state, and event delivery path. The adjacent basic-bearer-fixture.ts / basic-bearer-worker.ts and oauth-fixture.ts / oauth-worker.ts pairs exercise connection providers.
  • packages/core-plugin/src/manifest.ts, bricks.ts, and worker.ts are the production-grade reference, with supporting storage and deduplication modules in the same directory. The core plugin declares no connection types; use the SDK README’s issue-tools / Jira example for that shape instead.

Deploy every brick and trigger lifecycle handler at the exact endpoint in the manifest, then upload only the JSON manifest to the authenticated POST /plugins/upload endpoint. This upload route is HTTP, not an MCP tool.

  • create_workflow creates no executable version. Always complete at least one successful description-driven update_workflow before start_workflow.
  • Workflow deployment validation is compile-only. A candidate that compiles can still fail or behave incorrectly at runtime, so start and inspect a real instance after an update.
  • Plugin endpoints must be public HTTPS URLs with no embedded credentials or custom port, and their DNS must resolve to publicly routable addresses. Localhost and private-address endpoints are rejected during upload.
  • A published plugin version is immutable. Re-uploading the same version works only for byte-identical manifest content; changed content needs a greater semantic version. Existing connection-type security semantics cannot be changed across versions.
  • Every connection type needs a same-plugin validation brick with exactly one required slot of that type. configSchema and fixed config must either both be present or both be absent.
  • Trigger registration must persist the ingestion secret and credential generation atomically before acknowledging. The SDK explicitly warns that a bare eventually-consistent KV read/write pair is not a sufficient production state store.