* feat: render mcp run tools as an mcp apps run card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: back off run card polling and pin its run summary Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep the run card polling after a failed get_run Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: add run details, run form, diff and item views to the mcp card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: guard the mcp card's run form and diff errors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: honour the host's dark theme in the mcp card without its colours Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep untouched run form arguments and drop stale run refreshes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: let the run form re-send references and label diff links by target Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: parse literals typed over run form references by field type Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: version the mcp card uri and declare its empty csp Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: keep the mcp card to runs, group loop and branch steps, restyle it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: say when the mcp card cannot read a finished run's details Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: show runs, run tables and deploy reviews through dedicated mcp tools Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: review the whole draft before deploying from the mcp card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: follow host card guidelines: header link, collapsible steps, review summary, no run form Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep fullscreen review diffs whole and match drafts by storage path first Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: link to windmill where a host has no fullscreen, cap inline logs, shrink the card back Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: say in the review summary why a draft cannot be deployed from the card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: link the review to compare and deploy, cap inline tables, open long results Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: flag a cut result or log by what was kept, keep a lone log line Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mark the mcp card's fullscreen buttons with the expand icon Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: capitalize the mcp card's windmill link labels Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: add a show_item card for workspace items, collapsible sections in fullscreen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: apply windmill brand guidelines to the mcp card and show errors as windmill does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: show more windmill result kinds in the mcp run card Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: tidy the mcp card layout and let oversized drafts deploy from the review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: name a shown run by its summary, cap long item values, drop variable cards Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: link an app draft's card to its editor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: show a running flow's progress in the mcp card, open cut blocks on click, link each step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: read only a running step's log tail and skip the preprocessor in the progress bar Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp card headers carry a kind icon, and a summary names the item over its path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: skip result streams in log tail reads, keep the cut-result link when it fits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: link app drafts and agents to their own pages, offer Cancel only to tokens that can cancel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: simple inline mcp cards with a tabbed fullscreen run view and step drill-in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: draw the mcp card's tabs as windmill's underlined tabs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: link to windmill for what an mcp card hides when the host has no fullscreen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp run card steps as a tree beside the selected step, nested progress, danger cancel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: draw image results in the mcp run card, and a collapse control in fullscreen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: copy controls on the mcp card's results, logs and code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp card links read as text, hover tint only on buttons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: windmill's names, icons, status colours and type scale in the mcp card, within the hosts' rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep images out of mcp run table rows, and re-read only single-field image results Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: measure a re-read mcp image result as postgres prints it, so wrapped images draw Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp review deploys the selected drafts, loops list every iteration's result, branches and subflows named Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp review diffs open on demand, as on the compare page Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp script cards fade their code in inline, item sections open whole in fullscreen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp item cards link what a schedule or trigger runs, show a trigger's key settings and a schedule's arguments as rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp card lists a loop's latest 10 iterations, trigger topics by name Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp trigger cards open their other settings from a last table row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp draft badge in windmill's indigo without a spinner, show-more as a list's last row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: consistent mcp cards: one expand icon and rule, aligned tables, path titles, error and empty states Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp item cards offer fullscreen for cut values and overflowing code, name script steps by path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp cards show ai agents: their answer, named tool calls, what a waiting agent asks, saved agents Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp saved-agent runs label tool calls by tool, never by the internal root step Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: a saved agent's run card names its steps tab Tool calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: an mcp card says an agent waits only while its run is going Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp card paths wrap at slashes beside their icon; oauth approval offers all workspaces to a user in none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp card view read carries the cache hints 2026-07-28 clients require Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: mcp card leaves leaving fullscreen to the host's own close control Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp cards name a saved agent's test run by the agent's path, without .chat Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf: mcp get_run builds no card data; the run card refreshes through show_run Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp show_deploy_review refuses a token that cannot deploy, not only hides from it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp session tools carry a title and explicit read-only, destructive and open-world hints Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp run card reads only the end of a run's log; create_datatable_migration is destructive Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp run card counts log offsets from 1 and reads a finished run's archived log in full Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp item card rechecks clipped code on resize; oauth hint hides once the toggle is on Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: mcp item card uncuts a code block once a wider card fits it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Open-source, self-hostable code-first platform for workflows, apps and AI agents, running on the fastest self-hostable orchestrator. Engineers write code in 20+ languages and sync it with Git. Business teams build on the same platform with AI, while review, promotion between environments and isolated workers keep engineers in control of what ships. Self-hostable alternative to Lovable, Retool, n8n and a simplified Temporal.
Scripts are turned into sharable UIs, APIs and cron jobs automatically, and can be composed together into flows, data pipelines, AI agents or full-code React and Svelte apps. Supported languages: Python, TypeScript, Go, Bash, SQL, GraphQL, PowerShell, Rust, and more.
Try it - Website - Docs - Discord - Hub - Contributing
Windmill - Code-first platform for workflows, apps and AI agents
Windmill is fully open-sourced (AGPLv3) and Windmill Labs offers dedicated instances and commercial support and licenses.
https://github.com/user-attachments/assets/d80de1d9-64de-4d89-aacd-6df23fa81fc4
- Windmill - Code-first platform for workflows, apps and AI agents
Build with AI, ship with review
Business teams and engineers build on the same Windmill instance. What the AI builds is an ordinary script, flow or app, and goes through the same review as code written by engineers:
- AI sessions build scripts, flows and apps with AI in a workspace fork, with a live preview and a diff to review before deploying.
- Workspace roles decide what each team can author, and folders scope the resources, skills and MCP servers its AI can reach.
- Protection rulesets block direct deployment, so changes reach production only after an engineer reviews and deploys them.
- Dev workspaces keep their own credentials, and promote to prod through Compare & Deploy or a Git pull request.
- Worker groups run AI-built code on its own workers, or on a separate instance.
See let business teams build with AI safely for the full setup. Engineers keep writing code locally with the CLI, the VS Code extension and their coding agent, synced with Git.
Main Concepts
- Define a minimal and generic script in Python, TypeScript, Go or Bash that solves a specific task. The code can be defined in the provided Web IDE or synchronized with your own GitHub repo (e.g. through VS Code extension): provided Web IDE or synchronized with your own GitHub repo (e.g. through VS Code extension):
- Your scripts parameters are automatically parsed and generate a frontend.
- Make it flow! You can chain your scripts or scripts made by the community shared on WindmillHub.
- Build complex UIs on top of your scripts and flows.
Scripts and flows can be triggered by schedules, webhooks, HTTP routes, Kafka, WebSockets, emails, and more.
Build your entire infra on top of Windmill!
What the code looks like
A script is a plain function. Its typed arguments become a generated form, an HTTP endpoint and a CLI command:
import * as wmill from "windmill-client";
import dayjs from "dayjs"; // any npm package, resolved and pinned automatically
export async function main(
customerId: string,
plan: "starter" | "pro", // a union of strings becomes a dropdown
trialDays = 14 // defaults infer the type
) {
const trialEnd = dayjs().add(trialDays, "day").toISOString();
// a data table: the workspace's Postgres, queried without a connection string
const sql = wmill.datatable();
await sql`INSERT INTO trials (customer_id, plan, trial_end) VALUES (${customerId}, ${plan}, ${trialEnd})`.fetch();
// secrets are permissioned by path
const slackToken = await wmill.getVariable("f/sales/slack_token");
await fetch("https://slack.com/api/chat.postMessage", {
method: "POST",
headers: { Authorization: `Bearer ${slackToken}`, "Content-Type": "application/json" },
body: JSON.stringify({ channel: "#sales", text: `New ${plan} trial: ${customerId}` }),
});
console.log(`Trial started for ${customerId}`); // logs stream live in the UI
return { customerId, plan, trialEnd }; // returned as JSON
}
Workflows are code too. Each task runs as its own job with its own logs, and waiting for an approval releases the worker:
import { task, waitForApproval, workflow } from "windmill-client";
async function plan(env: string) {
return { env, changes: 3 };
}
async function apply(plan: { env: string; changes: number }) {
return `applied ${plan.changes} changes to ${plan.env}`;
}
export const main = workflow(async (env: string) => {
const changes = await task(plan)(env);
const approval = await waitForApproval({ timeout: 3600 });
if (!approval.approved) {
return `rejected by ${approval.approver}`;
}
return await task(apply)(changes);
});
Flows can also be built in the visual flow editor or as YAML, with scripts like the first one as steps. See workflows as code.
Data: data tables, DuckDB and DuckLake
- Data tables give each workspace managed Postgres tables, queried with type-checked SQL from TypeScript, Python and DuckDB scripts without exposing a connection string.
- DuckDB scripts query S3 and Azure Blob files (CSV, Parquet, JSON), data tables, Postgres, MySQL and BigQuery in SQL, on your workers.
- DuckLake stores large datasets as lakehouse tables in your workspace object storage, queried in plain SQL.
- Pipelines (alpha) wire scripts by the data they read and write instead of a hand-drawn DAG. This script runs whenever
eventsis materialized, and materializes its own table:
-- pipeline
-- on ducklake://main/events
-- materialize ducklake://main/events_by_kind
ATTACH 'ducklake://main' AS dl;
SELECT kind, count(*) AS n
FROM dl.events
GROUP BY kind;
Existing dbt projects run unmodified as scripts. See the pipelines quickstart.
Develop locally or in the browser
Engineers work from their editor and coding agent, business teams build with AI in the browser, and both land in the same workspace:
| Tool | Description |
|---|---|
| CLI | Sync a workspace with local files and Git, run scripts and flows from the command line. wmill init generates AGENTS.md and skill files for Claude Code, Cursor and other AI tools |
| VS Code extension | Edit and test scripts and flows from VS Code or Cursor with full IDE support |
| Git sync | Two-way sync between a workspace and your Git repository |
| MCP server | Let coding agents and AI clients run scripts, manage resources and monitor jobs in a workspace |
| AI sessions | The same agent loop in the browser, with nothing to install: plan mode, skills and MCP servers, a live preview, and a diff to review before deploying, in a fork of the workspace |
https://github.com/user-attachments/assets/c541c326-e9ae-4602-a09a-1989aaded1e9
You can run scripts locally by passing the right environment variables for the wmill client library to fetch resources and variables from your instance. See local development docs.
Stack
- Database: Postgres (compatible with Aurora, Cloud SQL, Neon, Azure PostgreSQL)
- Backend: Rust - stateless API servers and workers pulling jobs from a Postgres queue
- Frontend: Svelte 5
- Sandboxing: nsjail and PID namespace isolation
- Runtimes:
- TypeScript/JavaScript: Bun (default); Deno only on the
windmill-fullimages - Python: python3 with uv for dependency management
- PHP: only on the
windmill-fullimages - Go, Bash, PowerShell, Rust, C#, Java, Ansible
- TypeScript/JavaScript: Bun (default); Deno only on the
Fastest Self-Hostable Workflow Engine
We have compared Windmill to other self-hostable workflow engines (Airflow, Prefect & Temporal) and Windmill is the most performant solution for both benchmarks: one flow composed of 40 lightweight tasks & one flow composed of 10 long-running tasks.
All methodology & results on our Benchmarks page.
Security
- Sandboxing: nsjail for filesystem/resource isolation, and PID namespace isolation (enabled by default) to prevent jobs from accessing worker process memory
- Secrets: One encryption key per workspace for credentials stored in Windmill's K/V store. We recommend encrypting the Postgres database as well.
See Security documentation for details.
Performance
Once a job started, there is no overhead compared to running the same script on the node with its corresponding runner (Deno/Go/Python/Bash). The added latency from a job being pulled from the queue, started, and then having its result sent back to the database is ~50ms. A typical lightweight deno job will take around 100ms total.
Architecture
Stateless API servers and workers share a PostgreSQL database that holds the job queue and all workspace state (remote agent workers go through the API servers instead). Workers pull jobs by tag, so each worker group can run in its own network, for example dev workers that only reach dev systems and prod workers that only run reviewed code.
How to self-host
For detailed setup options, see Self-Host documentation.
Docker compose
Deploy Windmill with 3 files (docker-compose.yml, Caddyfile, .env):
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/docker-compose.yml -o docker-compose.yml
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/Caddyfile -o Caddyfile
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/.env -o .env
docker compose up -d
Go to http://localhost - default credentials: admin@windmill.dev / changeme
Using an external database: Set DATABASE_URL in .env to point to your managed Postgres (AWS RDS, GCP Cloud SQL, Azure, Neon, etc.) and set db replicas to 0.
Kubernetes (Helm charts)
helm repo add windmill https://windmill-labs.github.io/windmill-helm-charts/
helm install windmill-chart windmill/windmill --namespace=windmill --create-namespace
See windmill-helm-charts for configuration options.
Cloud providers
Windmill works on AWS (EKS/ECS), GCP, Azure, Ubicloud, Fly.io, Render.com, Hetzner, Digital Ocean, and others. Rule of thumb: 1 worker per 1vCPU and 1-2 GB RAM.
OAuth, SSO & SMTP
Configure OAuth and SSO (Google Workspace, Microsoft/Azure, Okta) directly from the superadmin UI. See documentation.
License
- Using the Community Edition as is, internally or through its APIs, is free and needs no commercial license, within the limits and quotas set in the software.
- Selling, reselling or serving the Community Edition as a managed service, modifying or wrapping it, or re-exposing it to your users as a feature of your product (iframed public apps excepted) requires a commercial license: contact sales@windmill.dev.
- The binary built from this repository without the
enterprisefeature flag is open source under AGPLv3: the same uses are then allowed under the AGPLv3 terms, or with a commercial license. The API clients and the OpenAPI spec are Apache 2.0.
See LICENSE for the full terms and Pricing for plans.
Integrations
In Windmill, integrations are referred to as resources and resource types. Each Resource has a Resource Type that defines the schema that the resource needs to implement.
On self-hosted instances, you might want to import all the approved resource types from WindmillHub. A setup script will prompt you to have it being synced automatically everyday.
Environment Variables
The variables most deployments set:
| Environment Variable name | Default | Description | Api Server/Worker/All |
|---|---|---|---|
| DATABASE_URL | The Postgres database url. | All | |
| MODE | standalone | The mode of the binary: standalone, server, worker, agent (EE), indexer (EE image, full-text search), mcp | All |
| WORKER_GROUP | default | The worker group the worker belongs to and gets its configuration pulled from | Worker |
| BASE_URL | http://localhost:8000 | The base url that is exposed publicly to access your instance. Is overriden by the instance settings if any. | Server |
| LICENSE_KEY (EE only) | None | License key checked at startup for the Enterprise Edition of Windmill | Worker |
All other variables (database pool, queue, runtimes, private registries, certificates, zombie jobs and more) are documented in the environment variables reference.
Contributing
At this time, we are not seeking outside contribution. Bug reports and feature requests remain very welcome, and small, trivially-verified PRs that fix a problem are still accepted. See CONTRIBUTING.md for the full policy.
To run Windmill from source, see frontend/README_DEV.md.
Copyright
© 2023-2026 Windmill Labs, Inc.






