Agentless Windows workflow orchestration - a modern, open replacement for Microsoft System Center Orchestrator
See the codeAgentless Windows workflow orchestration — a modern, open replacement for Microsoft System Center Orchestrator.
Design, schedule, debug, and observe multi-step automation in your browser. Run PowerShell, file/registry/service operations, REST calls, SQL, and more across your Windows estate over WinRM — no agents on the targets.
See SCOrch import, the Workflow Designer, execution history, Live Ops, logs and AI chat in action. English captions, no audio.




NodePilot is a drop-in modern alternative for organizations stuck on legacy SCOrch — same agentless model, same target audience (sysadmins automating Windows estates), but built on a current stack with a UX that doesn't feel like a 2010 MMC snap-in.
Highlights
.ois_export XML, with activities, links, conditions, global variables and Published Data references translated into NodePilot's data bus. How it works.waitAll / waitAny / waitNofM), per-step DI scope, and skip propagation./ai-chat), sharing conversations, drafts and ongoing answers across navigation. Answers use admin-switchable knowledge sources: documentation, operational data scoped by folder permissions, source code, and read-only SQL against the database. Every source is opt-in; the chat never executes or publishes anything.np) — full-featured command-line client (login, run, watch, audit, lock/publish, import/export), published as a self-contained folder you put on PATH.nodepilot-mcp) exposes NodePilot to Claude Code, Claude Desktop and any other MCP client — 102 tools over 10 groups, HTTP-only against the same REST API, with destructive operations gated.NODEPILOT_GRAFANA_ADMIN_PASSWORD — Compose fails closed while the password is missing, rather than coming up on a default credential.423 Locked enforced by every mutating endpoint, force-unlock for admins with audit trail.audit-event alert source that pages on failed logins, lockouts, break-glass sign-ins and privilege changes without a SIEM.SCOrch is not going anywhere: System Center 2025 Orchestrator shipped in November 2024 with mainstream support to January 2030 and extended support to January 2035. If you run it today, you are not on a deadline — so this is not a migration pitch.
What has not moved is authoring. The web console added in 2022 runs and monitors runbooks; it cannot build them. Writing one still means the desktop Runbook Designer, on a machine with the client installed — and once it is written, there is no version history, no diff between two states, and no rollback. NodePilot is built for that gap: the same agentless model, the same job, the same people, with the editor, the debugger and the version history in a browser.
Your runbooks come with you. NodePilot reads SCOrch's native .ois_export XML directly
(exports from 2012, 2016 and 2019 all parse) and turns runbooks into workflows:
Trigger Policy) including the arguments passed to a child runbook.\`d.T.~Vb/{GUID}\`d.T.~Vb/ references are
rewritten into NodePilot's {{globals.Name}} and {{step.param.field}} syntax, resolving through
a readable name derived from each activity rather than a bare GUID. Where the two products name
the same value differently the field is translated too, and where SCOrch published something
NodePilot has no equivalent for, the reference is reported instead of quietly pointing at the
nearest-looking name. This is usually the part that makes a migration expensive.decision, and the links that read its
result are re-pointed at it — a comparison whose outcome nothing could read would leave every
branch behind it dead.TRIGGERS filter logic, and whether a link matched all or any of its filters.Import from the UI, from POST /api/workflows/import-scorch, or from the CLI:
np workflow import-scorch --file .\runbooks.ois_export
Treat the result as a reviewed draft, not a finished migration. Imported workflows arrive disabled,
credentials are never reconstructed (SCOrch encrypts them), and anything the report flags needs a
decision. After review, activate a workflow explicitly through
POST /api/workflows/{id}/enable or np workflow enable <id>. Both import APIs return the created
ids; the CLI exposes the same report as machine-readable stdout with -o json. The point is that you
start from your actual runbooks instead of a blank canvas.
| System Center Orchestrator | NodePilot | |
|---|---|---|
| Support lifecycle | System Center 2025: mainstream to 2030, extended to 2035 | rolling releases, no end-of-life date — and no vendor behind it either |
| Agents on targets | none (agentless) | none (agentless) — same WinRM model |
| Authoring | desktop Runbook Designer only — the 2022 web console runs and monitors, but cannot build a runbook | browser, live canvas, real-time step status over SignalR |
| Debugging | Runbook Tester in the designer — breakpoints, step, published data per activity | same in the real engine, plus conditional breakpoints, runtime variable overrides and time-scrubbing replay |
| Parallelism | parallel branches; junction waits for all or for any | event-driven fan-out/fan-in, three junction modes (waitAll / waitAny / waitNofM) |
| Authoring assistance | none | optional AI generation of scripts and whole workflows from natural language (local models supported) |
| Automation API | JSON web API since 2022 — starts and monitors jobs | full REST API covering every operation, an np CLI, and an MCP server for AI agents |
| Check-out / publish | per-user check-out | same model, kept deliberately — atomic lock/publish, 423 Locked on every mutating endpoint, admin force-unlock with audit |
| Versioning | none built in | every edit snapshotted, visual diff, one-click rollback |
| Observability | job history in the database, shown in the console; no metrics or tracing | opt-in OpenTelemetry + Prometheus, 10 pre-provisioned Grafana dashboards |
| Platform | Windows Server | Windows Server or a single desktop machine (offline installer) |
| Database | SQL Server | PostgreSQL or SQL Server |
| Licence | commercial, per-managed-host | Apache-2.0, no per-host cost |
| Support | vendor | community — this is a single-maintainer open-source project |
The last row is the honest one: NodePilot gives you the source, not a support contract. Judge it on that basis.
Need to make the case to someone else? A ready-made slide deck lives in
presentations/, self-contained HTML — download and open in a browser:
The deck is in German. It predates this README and is not maintained in step with it — treat it as a starting point for your own slides rather than as current reference material.
NodePilot runs in exactly three supported shapes. Pick the row that describes you; each one is a complete route to a working login, and nothing below mixes them.
| 1 · Desktop app | 2 · Windows service | 3 · From source | |
|---|---|---|---|
| For | one person, one machine | a team, a real server | contributors, evaluation |
| You need | Windows 11 x64, local admin | Windows Server 2022/2025, a TLS certificate, a prepared database | .NET 10 SDK, Node, a local PostgreSQL |
| You get | installer .exe — bundles a local PostgreSQL and the .NET runtime, installs both as services, opens a native window | setup .exe (or the signed .zip + PowerShell installer) — Windows service under a gMSA, Kestrel HTTPS | dotnet run + Vite dev server on your own machine |
| Database | bundled, loopback-only | you provide it | you provide it |
| Offline | yes, fully | yes | no (package restore) |
| Guide | below · details | below · step-by-step | below |
NodePilot is Windows-only by design — the engine drives PowerShell remoting over WinRM and protects credentials with DPAPI. There is no Linux, container or Kubernetes target.
Every path ends the same way: the first login creates the Admin account, and it needs a one-time setup token. Where to find that token differs per path and is called out below.
A local desktop application for Windows 11 x64: one .exe that bundles the app, a
self-contained .NET 10 runtime and a local PostgreSQL server, installs everything as background
Windows services, and opens a native Electron window on top — fully offline, no runtime
prerequisites, no external database.
Download NodePilot-Desktop-Setup-<version>.exe from the
latest release and run it. The installer
needs local admin: it provisions the database cluster, a loopback certificate and both services,
then launches the shell and hands the first-run setup token straight to the login screen — you
never have to find a file. If provisioning fails it says so and names its log, rather than
finishing green with an app that will not start. When something does go wrong,
docs/desktop-troubleshooting.md covers the log locations,
first-run recovery and a complete removal; the full inventory of every log file — server and
desktop, with paths, retention and which one to read when — is at
Logs & diagnostics.
The backend runs as an always-on service, so scheduled and webhook triggers keep firing when the
window is closed. It uses the Deployment:Mode=Desktop posture: Production-hardened, but with a
loopback-only Kestrel and a 127.0.0.1 Postgres. The Electron shell is a thin, hardened viewer that
pins the loopback certificate by SHA-256 and trusts no system root CA.
Needs .NET 10 SDK, Node, Inno Setup 6 (ISCC.exe)
and a PostgreSQL 16 binaries folder — the pgsql directory from the
EDB zip distribution. The build fails
fast if either of the last two is missing. Expect 10–15 minutes.
deploy\desktop\Build-DesktopInstaller.ps1 -PgBinariesPath 'C:\Packages\pgsql' -Version 1.2.0
# -> deploy\desktop\out\NodePilot-Desktop-Setup-1.2.0.exe
Build-DesktopInstaller.ps1 never signs — it has no signing parameter at all. To get a signed
installer, build it through the release build instead:
deploy\Build-Artifact.ps1 -SigningCertificateThumbprint <artifact-signer> `
-IncludeDesktopInstaller -PgBinariesPath 'C:\Packages\pgsql' `
-InstallerSigningCertificateThumbprint <authenticode-signer>
Sign during the build rather than afterwards: signing rewrites the .exe and would invalidate its
entry in NodePilot-<version>.SHA256SUMS.txt. Signing does not silence SmartScreen — a downloaded
installer warns on first launch either way, because the publisher certificate is self-signed and
carries no reputation (see
deployment-guide.md). Internals,
service identities and the first-run handoff: deploy/desktop/README.md.
The production rollout: a signed artifact plus a PowerShell installer that registers NodePilot as a Windows service under a gMSA, terminates HTTPS in Kestrel directly, and splits install and data directories so in-place upgrades can roll back.
Prerequisites (all enforced by the installer's pre-flight, which fails with a named error):
-UseLocalSystem works
without a domainwin-x64; a 32-bit runtime cannot host it
and the pre-flight says so rather than passing the rowEncrypt=Strict / TDS 8.0 connections NodePilot opens, and are rejected)Cert:\LocalMachine\My with its private keyThere are two ways to run it, and they install the same thing.
With the wizard. Download NodePilot-Server-Setup-<version>.exe from the
latest release and run it. It carries the
signed artifact and the ASP.NET Core runtime, checks every prerequisite above before changing
anything — showing each as green, amber or red with a copyable fix — and can install the runtime,
create the SQL login and database, or issue a lab certificate for you. One file instead of five,
and no manual thumbprint comparison. Unattended:
Setup.exe /VERYSILENT /SUPPRESSMSGBOXES /ANSWERFILE=answers.json. Details, answer-file schema and
switches: deploy/server/README.md.
With the scripts, which is what the wizard runs and what you want for automation. Download the
signed NodePilot-<version>.zip together with its .manifest.json and .manifest.json.p7s,
verify it against NodePilot-<version>.SHA256SUMS.txt, then:
.\deploy\Install-NodePilot.ps1 `
-ArtifactPath 'C:\Packages\NodePilot-1.2.0.zip' `
-TrustedArtifactSignerThumbprint '<publisher thumbprint from the release notes>' `
-CertThumbprint '<your TLS cert thumbprint>' `
-ServiceAccount 'CONTOSO\svc-nodepilot$' `
-PublicHostname 'nodepilot.corp.example.com'
The installer refuses unsigned or tampered artifacts — -TrustedArtifactSignerThumbprint is
mandatory, and the signature, the signer's identity, its code-signing eligibility and its validity
are all verified, not just the hash. It does not require the publisher to be trusted on the
target machine: pinning the thumbprint is the trust decision, so there is nothing to import before
installing. If you build the artifact yourself you also sign it yourself;
docs/deployment-guide.md walks through creating the self-signed code-signing certificate.
Full walkthrough — service identity, database, certificates, first login: Windows Server deployment. Verifying what you downloaded, and building it yourself — plus a troubleshooting table for what actually goes wrong: docs/deployment-guide.md. Operator reference — every parameter, update and uninstall: deploy/README.md.
For contributors and for evaluating on a workstation.
Prerequisites
global.jsonpackage.json engines field (react-router 8 sets it); npm warns if you are below itDatabase:Provider: sqlserver1. Create the database
Neither shipped connection string carries a password, so this step is not optional.
winget install PostgreSQL.PostgreSQL
$psql = "C:\Program Files\PostgreSQL\16\bin\psql.exe"
& $psql -U postgres -c "CREATE ROLE nodepilot WITH LOGIN PASSWORD 'ChangeMe!';"
& $psql -U postgres -c "CREATE DATABASE nodepilot OWNER nodepilot;"
2. Start the backend (port 5000)
Pass the password through the environment rather than editing a tracked file — that way it never becomes a commit:
$env:ConnectionStrings__Postgres = "Host=127.0.0.1;Port=5432;Database=nodepilot;Username=nodepilot;Password=ChangeMe!;SSL Mode=Disable"
cd src\NodePilot.Api
dotnet run
Start PostgreSQL before the API — without a reachable database the process exits during the migration bootstrap and tells you which server and database it could not reach.
On first start NodePilot writes a one-time setup token to admin-setup.token next to the
project (src\NodePilot.Api\admin-setup.token — it lands in the content root, not the directory
you started from). Sign in with the admin username and password you want; the login screen reveals
a Setup token field on the first attempt, and pasting the token creates the Admin account.
3. Start the frontend (port 5173)
cd src\nodepilot-ui
npm install
npm run dev
Open http://localhost:5173 — the Vite dev server proxies /api, /healthz and /hubs to
port 5000.
4. (optional) Bring up Grafana
cd grafana
Copy-Item .env.example .env # then set NODEPILOT_GRAFANA_ADMIN_PASSWORD - compose refuses to start without it
docker compose up -d
# Grafana -> http://localhost:3000 (user "admin", the password you just set)
# Prometheus -> http://localhost:9090
Enable the Prometheus exporter on the API — all three variables are required, the third is what
lets Prometheus scrape /metrics without credentials:
$env:OpenTelemetry__Enabled = "true"
$env:OpenTelemetry__Exporters__PrometheusScrape = "true"
$env:OpenTelemetry__Exporters__PrometheusScrapeAllowAnonymous = "true"
See grafana/README.md for the full walk-through.
The same walkthrough, with more detail per step, lives on the documentation site — in English and German.
Want to see the designer in action without building anything? Import the bundled showcase — a nightly fleet health-check that fans out three parallel probes, gathers them at a junction, and routes a decision to an alert or an all-green log:
scripts/readme-showcase-workflow.json
Import it via the Workflows page → Import (or POST /api/workflows/import). It exercises
every shape you'll meet in production — schedule trigger, runScript, log, junction
(waitAll), decision, emailNotification, returnData, plus three phase sticky-notes —
laid out to fill the canvas width and run top-to-bottom.
Everything below the surface lives on the documentation site — 43 pages in English and German, with search and deep links. This README deliberately stops at "installed and logged in".
| Start here | Introduction · Installation · Architecture |
| Building workflows | Workflows & activities · Data bus & variables · Edge conditions · Sub-workflows |
| The designer | Overview · Canvas, nodes & edges · Properties, modes & shortcuts |
| Reference | All 27 activities · Triggers · API endpoints · np CLI · MCP server |
| Running it | Windows Server · Desktop app · Antivirus exclusions · Logs & diagnostics · Configuration |
| Security | Security model · Hardening flags · Audit log |
| Enterprise | High availability · Secret providers · AD SSO Preview · Folder RBAC |
The API also documents itself: the OpenAPI spec is served at GET /openapi/v1.json, with Swagger
UI at GET /swagger (Development by default).
For a real server rollout, follow Windows Server deployment on the documentation site — a lab-validated walkthrough covering service identity, both database providers, certificates and the first admin account. The installer runs NodePilot as a Windows service under a gMSA with direct Kestrel HTTPS, splits install and data directories, and upgrades in place with automatic rollback.
Two companions to it: docs/deployment-guide.md covers what happens before you install — verifying the download against its checksums and publisher, and building the artifact yourself — and carries the troubleshooting table. deploy/README.md is the parameter reference, and states what the installer deliberately does not do.
Before you deploy anywhere with endpoint protection, hand docs/av-exclusions.md to whoever owns it — NodePilot runs PowerShell by design, and that trips heuristics.
src/
NodePilot.Core/ Domain models, interfaces, enums (zero dependencies)
NodePilot.Ai/ LLM stack — ILlmClient/OpenAI transport + SSRF guard, prompt catalog, script/workflow gen + chat assistant (Core-only; used by Api and Engine)
NodePilot.Data/ EF Core DbContext, CredentialStore (DPAPI), provider-agnostic migrations
NodePilot.Remote/ WinRM session factory + PowerShell SDK session
NodePilot.Engine/ WorkflowEngine, 27 activities, RetryPolicy, DebugCoordinator
NodePilot.Scheduler/ TriggerOrchestrator (Quartz.NET), 4 polling trigger sources + retention/cluster services
NodePilot.Telemetry/ OpenTelemetry setup, Prometheus client, metric constants
NodePilot.Api/ ASP.NET Core host, controllers, SignalR hub, security middleware
NodePilot.Cli/ `np` — operations CLI (Spectre.Console.Cli), shipped in both installers under tools\np
NodePilot.Mcp/ `nodepilot-mcp` — MCP server for AI agents (ModelContextProtocol), shipped under tools\mcp
NodePilot.Switcher/ WPF utility for exclusive local NodePilot/SCOrch service control
nodepilot-ui/ React 19 SPA (Vite 8 + Tailwind CSS 4 + React Flow 12)
nodepilot-docs-ui/ Documentation website (Vite + React SPA) — its OWN curated markdown corpus under content/{de,en}/, maintained alongside docs/ (not a 1:1 render)
nodepilot-desktop/ Electron shell for the desktop app — thin hardened viewer, no business logic
tests/
NodePilot.Engine.Tests/ xUnit — engine + every activity executor
NodePilot.Ai.Tests/ xUnit — LLM client factory, endpoint guard, prompt catalog, gen/chat services
NodePilot.Data.Tests/ xUnit — EF context + migrations
NodePilot.Api.Tests/ xUnit — controllers, auth, telemetry, validation
NodePilot.Cli.Tests/ xUnit + WireMock.Net — CLI ApiClient + DPAPI TokenStore
NodePilot.Mcp.Tests/ xUnit + WireMock.Net — MCP tools + stdio-process smoke test
NodePilot.LoadTests/ Standalone load harness (Console EXE, HdrHistogram)
NodePilot.Switcher.Tests/ xUnit — discovery, state machine, fail-closed switching
NodePilot.TestCommons/ Shared test infrastructure (TestDbFactory, FakeLlmClient, fixtures)
grafana/ Docker-compose stack: Prometheus + Grafana + 10 dashboards
deploy/ Production install / update / uninstall PowerShell scripts
docs/ Feature docs (AI, styleguide, perf, security, deployment)
samples/ Example workflows for the importer
Dependency graph:
Api → Ai, Engine, Scheduler, Data, Remote, Core, Telemetry
Engine → Ai, Data, Remote, Core, Telemetry
Ai → Core · Data → Core · Remote → Core · Telemetry → Core
Cli → Core · Mcp → Core (HTTP-only — no backend project references)
Six CI jobs gate every pull request and every push to main: backend build + tests with an
enforced 85 % line / 70 % branch coverage gate, frontend lint/build/vitest, docs-site
lint/tests/build, desktop-shell typecheck + tests, and hermetic Playwright E2E. A local nightly
task runs the same four suites against the checked-out tree.
Tests are mandatory — every behaviour change ships with tests in the same change. Which tests you run locally is scoped to what you touched; the full suite is CI's job, not yours. Commands, the scoping rules, and the guard-test mapping are in CONTRIBUTING.md and CLAUDE.md.
Two conventions worth knowing before you write one: the WinRM remote layer is always mocked, and backend database tests run on in-memory SQLite — a test backend only, never a supported production provider.
Contributions are welcome. CONTRIBUTING.md has the full setup: prerequisites, how to get a local PostgreSQL and a first admin account, the build and test commands, and the conventions that CI enforces.
The short version:
Found a security problem? Do not open a public issue — SECURITY.md has the private reporting path. Everyone taking part is expected to follow the Code of Conduct.
CLAUDE.md and .agents/ are working notes for AI coding agents, not contributor documentation.
They are checked in deliberately: NodePilot is built with agentic engineering, so the context an
agent needs to work on this codebase belongs in the repository rather than in someone's private
setup. What that does not change is the bar every change has to clear — behaviour changes ship
with tests, and CI enforces the coverage gate on every pull request.
CONTRIBUTING.md is the file written for people.
NodePilot is licensed under the Apache License 2.0. You are free to use, modify, and distribute it — including commercially — provided you retain the copyright and license notices. See LICENSE for the full text.
scheduleTrigger./docs, without a login and without internet access, at the version actually installed.#/en/…, #/de/…). Note: it ships its own curated markdown corpus under content/en/ and content/de/ — changes to docs/ must be mirrored there deliberately (it is not a 1:1 render), and both languages must be kept in step or the parity test fails. It has two deployments: GitHub Pages, and wwwroot/docs inside the server artifact and desktop package, which the API serves at /docs.C#
58.7%
TypeScript
30.2%
PowerShell
6.1%
Python
1.8%
CSS
1.5%
Agentless Windows workflow orchestration - a modern, open replacement for Microsoft System Center Orchestrator
See the codeAgentless Windows workflow orchestration — a modern, open replacement for Microsoft System Center Orchestrator.
Design, schedule, debug, and observe multi-step automation in your browser. Run PowerShell, file/registry/service operations, REST calls, SQL, and more across your Windows estate over WinRM — no agents on the targets.
See SCOrch import, the Workflow Designer, execution history, Live Ops, logs and AI chat in action. English captions, no audio.




NodePilot is a drop-in modern alternative for organizations stuck on legacy SCOrch — same agentless model, same target audience (sysadmins automating Windows estates), but built on a current stack with a UX that doesn't feel like a 2010 MMC snap-in.
Highlights
.ois_export XML, with activities, links, conditions, global variables and Published Data references translated into NodePilot's data bus. How it works.waitAll / waitAny / waitNofM), per-step DI scope, and skip propagation./ai-chat), sharing conversations, drafts and ongoing answers across navigation. Answers use admin-switchable knowledge sources: documentation, operational data scoped by folder permissions, source code, and read-only SQL against the database. Every source is opt-in; the chat never executes or publishes anything.np) — full-featured command-line client (login, run, watch, audit, lock/publish, import/export), published as a self-contained folder you put on PATH.nodepilot-mcp) exposes NodePilot to Claude Code, Claude Desktop and any other MCP client — 102 tools over 10 groups, HTTP-only against the same REST API, with destructive operations gated.NODEPILOT_GRAFANA_ADMIN_PASSWORD — Compose fails closed while the password is missing, rather than coming up on a default credential.423 Locked enforced by every mutating endpoint, force-unlock for admins with audit trail.audit-event alert source that pages on failed logins, lockouts, break-glass sign-ins and privilege changes without a SIEM.SCOrch is not going anywhere: System Center 2025 Orchestrator shipped in November 2024 with mainstream support to January 2030 and extended support to January 2035. If you run it today, you are not on a deadline — so this is not a migration pitch.
What has not moved is authoring. The web console added in 2022 runs and monitors runbooks; it cannot build them. Writing one still means the desktop Runbook Designer, on a machine with the client installed — and once it is written, there is no version history, no diff between two states, and no rollback. NodePilot is built for that gap: the same agentless model, the same job, the same people, with the editor, the debugger and the version history in a browser.
Your runbooks come with you. NodePilot reads SCOrch's native .ois_export XML directly
(exports from 2012, 2016 and 2019 all parse) and turns runbooks into workflows:
Trigger Policy) including the arguments passed to a child runbook.\`d.T.~Vb/{GUID}\`d.T.~Vb/ references are
rewritten into NodePilot's {{globals.Name}} and {{step.param.field}} syntax, resolving through
a readable name derived from each activity rather than a bare GUID. Where the two products name
the same value differently the field is translated too, and where SCOrch published something
NodePilot has no equivalent for, the reference is reported instead of quietly pointing at the
nearest-looking name. This is usually the part that makes a migration expensive.decision, and the links that read its
result are re-pointed at it — a comparison whose outcome nothing could read would leave every
branch behind it dead.TRIGGERS filter logic, and whether a link matched all or any of its filters.Import from the UI, from POST /api/workflows/import-scorch, or from the CLI:
np workflow import-scorch --file .\runbooks.ois_export
Treat the result as a reviewed draft, not a finished migration. Imported workflows arrive disabled,
credentials are never reconstructed (SCOrch encrypts them), and anything the report flags needs a
decision. After review, activate a workflow explicitly through
POST /api/workflows/{id}/enable or np workflow enable <id>. Both import APIs return the created
ids; the CLI exposes the same report as machine-readable stdout with -o json. The point is that you
start from your actual runbooks instead of a blank canvas.
| System Center Orchestrator | NodePilot | |
|---|---|---|
| Support lifecycle | System Center 2025: mainstream to 2030, extended to 2035 | rolling releases, no end-of-life date — and no vendor behind it either |
| Agents on targets | none (agentless) | none (agentless) — same WinRM model |
| Authoring | desktop Runbook Designer only — the 2022 web console runs and monitors, but cannot build a runbook | browser, live canvas, real-time step status over SignalR |
| Debugging | Runbook Tester in the designer — breakpoints, step, published data per activity | same in the real engine, plus conditional breakpoints, runtime variable overrides and time-scrubbing replay |
| Parallelism | parallel branches; junction waits for all or for any | event-driven fan-out/fan-in, three junction modes (waitAll / waitAny / waitNofM) |
| Authoring assistance | none | optional AI generation of scripts and whole workflows from natural language (local models supported) |
| Automation API | JSON web API since 2022 — starts and monitors jobs | full REST API covering every operation, an np CLI, and an MCP server for AI agents |
| Check-out / publish | per-user check-out | same model, kept deliberately — atomic lock/publish, 423 Locked on every mutating endpoint, admin force-unlock with audit |
| Versioning | none built in | every edit snapshotted, visual diff, one-click rollback |
| Observability | job history in the database, shown in the console; no metrics or tracing | opt-in OpenTelemetry + Prometheus, 10 pre-provisioned Grafana dashboards |
| Platform | Windows Server | Windows Server or a single desktop machine (offline installer) |
| Database | SQL Server | PostgreSQL or SQL Server |
| Licence | commercial, per-managed-host | Apache-2.0, no per-host cost |
| Support | vendor | community — this is a single-maintainer open-source project |
The last row is the honest one: NodePilot gives you the source, not a support contract. Judge it on that basis.
Need to make the case to someone else? A ready-made slide deck lives in
presentations/, self-contained HTML — download and open in a browser:
The deck is in German. It predates this README and is not maintained in step with it — treat it as a starting point for your own slides rather than as current reference material.
NodePilot runs in exactly three supported shapes. Pick the row that describes you; each one is a complete route to a working login, and nothing below mixes them.
| 1 · Desktop app | 2 · Windows service | 3 · From source | |
|---|---|---|---|
| For | one person, one machine | a team, a real server | contributors, evaluation |
| You need | Windows 11 x64, local admin | Windows Server 2022/2025, a TLS certificate, a prepared database | .NET 10 SDK, Node, a local PostgreSQL |
| You get | installer .exe — bundles a local PostgreSQL and the .NET runtime, installs both as services, opens a native window | setup .exe (or the signed .zip + PowerShell installer) — Windows service under a gMSA, Kestrel HTTPS | dotnet run + Vite dev server on your own machine |
| Database | bundled, loopback-only | you provide it | you provide it |
| Offline | yes, fully | yes | no (package restore) |
| Guide | below · details | below · step-by-step | below |
NodePilot is Windows-only by design — the engine drives PowerShell remoting over WinRM and protects credentials with DPAPI. There is no Linux, container or Kubernetes target.
Every path ends the same way: the first login creates the Admin account, and it needs a one-time setup token. Where to find that token differs per path and is called out below.
A local desktop application for Windows 11 x64: one .exe that bundles the app, a
self-contained .NET 10 runtime and a local PostgreSQL server, installs everything as background
Windows services, and opens a native Electron window on top — fully offline, no runtime
prerequisites, no external database.
Download NodePilot-Desktop-Setup-<version>.exe from the
latest release and run it. The installer
needs local admin: it provisions the database cluster, a loopback certificate and both services,
then launches the shell and hands the first-run setup token straight to the login screen — you
never have to find a file. If provisioning fails it says so and names its log, rather than
finishing green with an app that will not start. When something does go wrong,
docs/desktop-troubleshooting.md covers the log locations,
first-run recovery and a complete removal; the full inventory of every log file — server and
desktop, with paths, retention and which one to read when — is at
Logs & diagnostics.
The backend runs as an always-on service, so scheduled and webhook triggers keep firing when the
window is closed. It uses the Deployment:Mode=Desktop posture: Production-hardened, but with a
loopback-only Kestrel and a 127.0.0.1 Postgres. The Electron shell is a thin, hardened viewer that
pins the loopback certificate by SHA-256 and trusts no system root CA.
Needs .NET 10 SDK, Node, Inno Setup 6 (ISCC.exe)
and a PostgreSQL 16 binaries folder — the pgsql directory from the
EDB zip distribution. The build fails
fast if either of the last two is missing. Expect 10–15 minutes.
deploy\desktop\Build-DesktopInstaller.ps1 -PgBinariesPath 'C:\Packages\pgsql' -Version 1.2.0
# -> deploy\desktop\out\NodePilot-Desktop-Setup-1.2.0.exe
Build-DesktopInstaller.ps1 never signs — it has no signing parameter at all. To get a signed
installer, build it through the release build instead:
deploy\Build-Artifact.ps1 -SigningCertificateThumbprint <artifact-signer> `
-IncludeDesktopInstaller -PgBinariesPath 'C:\Packages\pgsql' `
-InstallerSigningCertificateThumbprint <authenticode-signer>
Sign during the build rather than afterwards: signing rewrites the .exe and would invalidate its
entry in NodePilot-<version>.SHA256SUMS.txt. Signing does not silence SmartScreen — a downloaded
installer warns on first launch either way, because the publisher certificate is self-signed and
carries no reputation (see
deployment-guide.md). Internals,
service identities and the first-run handoff: deploy/desktop/README.md.
The production rollout: a signed artifact plus a PowerShell installer that registers NodePilot as a Windows service under a gMSA, terminates HTTPS in Kestrel directly, and splits install and data directories so in-place upgrades can roll back.
Prerequisites (all enforced by the installer's pre-flight, which fails with a named error):
-UseLocalSystem works
without a domainwin-x64; a 32-bit runtime cannot host it
and the pre-flight says so rather than passing the rowEncrypt=Strict / TDS 8.0 connections NodePilot opens, and are rejected)Cert:\LocalMachine\My with its private keyThere are two ways to run it, and they install the same thing.
With the wizard. Download NodePilot-Server-Setup-<version>.exe from the
latest release and run it. It carries the
signed artifact and the ASP.NET Core runtime, checks every prerequisite above before changing
anything — showing each as green, amber or red with a copyable fix — and can install the runtime,
create the SQL login and database, or issue a lab certificate for you. One file instead of five,
and no manual thumbprint comparison. Unattended:
Setup.exe /VERYSILENT /SUPPRESSMSGBOXES /ANSWERFILE=answers.json. Details, answer-file schema and
switches: deploy/server/README.md.
With the scripts, which is what the wizard runs and what you want for automation. Download the
signed NodePilot-<version>.zip together with its .manifest.json and .manifest.json.p7s,
verify it against NodePilot-<version>.SHA256SUMS.txt, then:
.\deploy\Install-NodePilot.ps1 `
-ArtifactPath 'C:\Packages\NodePilot-1.2.0.zip' `
-TrustedArtifactSignerThumbprint '<publisher thumbprint from the release notes>' `
-CertThumbprint '<your TLS cert thumbprint>' `
-ServiceAccount 'CONTOSO\svc-nodepilot$' `
-PublicHostname 'nodepilot.corp.example.com'
The installer refuses unsigned or tampered artifacts — -TrustedArtifactSignerThumbprint is
mandatory, and the signature, the signer's identity, its code-signing eligibility and its validity
are all verified, not just the hash. It does not require the publisher to be trusted on the
target machine: pinning the thumbprint is the trust decision, so there is nothing to import before
installing. If you build the artifact yourself you also sign it yourself;
docs/deployment-guide.md walks through creating the self-signed code-signing certificate.
Full walkthrough — service identity, database, certificates, first login: Windows Server deployment. Verifying what you downloaded, and building it yourself — plus a troubleshooting table for what actually goes wrong: docs/deployment-guide.md. Operator reference — every parameter, update and uninstall: deploy/README.md.
For contributors and for evaluating on a workstation.
Prerequisites
global.jsonpackage.json engines field (react-router 8 sets it); npm warns if you are below itDatabase:Provider: sqlserver1. Create the database
Neither shipped connection string carries a password, so this step is not optional.
winget install PostgreSQL.PostgreSQL
$psql = "C:\Program Files\PostgreSQL\16\bin\psql.exe"
& $psql -U postgres -c "CREATE ROLE nodepilot WITH LOGIN PASSWORD 'ChangeMe!';"
& $psql -U postgres -c "CREATE DATABASE nodepilot OWNER nodepilot;"
2. Start the backend (port 5000)
Pass the password through the environment rather than editing a tracked file — that way it never becomes a commit:
$env:ConnectionStrings__Postgres = "Host=127.0.0.1;Port=5432;Database=nodepilot;Username=nodepilot;Password=ChangeMe!;SSL Mode=Disable"
cd src\NodePilot.Api
dotnet run
Start PostgreSQL before the API — without a reachable database the process exits during the migration bootstrap and tells you which server and database it could not reach.
On first start NodePilot writes a one-time setup token to admin-setup.token next to the
project (src\NodePilot.Api\admin-setup.token — it lands in the content root, not the directory
you started from). Sign in with the admin username and password you want; the login screen reveals
a Setup token field on the first attempt, and pasting the token creates the Admin account.
3. Start the frontend (port 5173)
cd src\nodepilot-ui
npm install
npm run dev
Open http://localhost:5173 — the Vite dev server proxies /api, /healthz and /hubs to
port 5000.
4. (optional) Bring up Grafana
cd grafana
Copy-Item .env.example .env # then set NODEPILOT_GRAFANA_ADMIN_PASSWORD - compose refuses to start without it
docker compose up -d
# Grafana -> http://localhost:3000 (user "admin", the password you just set)
# Prometheus -> http://localhost:9090
Enable the Prometheus exporter on the API — all three variables are required, the third is what
lets Prometheus scrape /metrics without credentials:
$env:OpenTelemetry__Enabled = "true"
$env:OpenTelemetry__Exporters__PrometheusScrape = "true"
$env:OpenTelemetry__Exporters__PrometheusScrapeAllowAnonymous = "true"
See grafana/README.md for the full walk-through.
The same walkthrough, with more detail per step, lives on the documentation site — in English and German.
Want to see the designer in action without building anything? Import the bundled showcase — a nightly fleet health-check that fans out three parallel probes, gathers them at a junction, and routes a decision to an alert or an all-green log:
scripts/readme-showcase-workflow.json
Import it via the Workflows page → Import (or POST /api/workflows/import). It exercises
every shape you'll meet in production — schedule trigger, runScript, log, junction
(waitAll), decision, emailNotification, returnData, plus three phase sticky-notes —
laid out to fill the canvas width and run top-to-bottom.
Everything below the surface lives on the documentation site — 43 pages in English and German, with search and deep links. This README deliberately stops at "installed and logged in".
| Start here | Introduction · Installation · Architecture |
| Building workflows | Workflows & activities · Data bus & variables · Edge conditions · Sub-workflows |
| The designer | Overview · Canvas, nodes & edges · Properties, modes & shortcuts |
| Reference | All 27 activities · Triggers · API endpoints · np CLI · MCP server |
| Running it | Windows Server · Desktop app · Antivirus exclusions · Logs & diagnostics · Configuration |
| Security | Security model · Hardening flags · Audit log |
| Enterprise | High availability · Secret providers · AD SSO Preview · Folder RBAC |
The API also documents itself: the OpenAPI spec is served at GET /openapi/v1.json, with Swagger
UI at GET /swagger (Development by default).
For a real server rollout, follow Windows Server deployment on the documentation site — a lab-validated walkthrough covering service identity, both database providers, certificates and the first admin account. The installer runs NodePilot as a Windows service under a gMSA with direct Kestrel HTTPS, splits install and data directories, and upgrades in place with automatic rollback.
Two companions to it: docs/deployment-guide.md covers what happens before you install — verifying the download against its checksums and publisher, and building the artifact yourself — and carries the troubleshooting table. deploy/README.md is the parameter reference, and states what the installer deliberately does not do.
Before you deploy anywhere with endpoint protection, hand docs/av-exclusions.md to whoever owns it — NodePilot runs PowerShell by design, and that trips heuristics.
src/
NodePilot.Core/ Domain models, interfaces, enums (zero dependencies)
NodePilot.Ai/ LLM stack — ILlmClient/OpenAI transport + SSRF guard, prompt catalog, script/workflow gen + chat assistant (Core-only; used by Api and Engine)
NodePilot.Data/ EF Core DbContext, CredentialStore (DPAPI), provider-agnostic migrations
NodePilot.Remote/ WinRM session factory + PowerShell SDK session
NodePilot.Engine/ WorkflowEngine, 27 activities, RetryPolicy, DebugCoordinator
NodePilot.Scheduler/ TriggerOrchestrator (Quartz.NET), 4 polling trigger sources + retention/cluster services
NodePilot.Telemetry/ OpenTelemetry setup, Prometheus client, metric constants
NodePilot.Api/ ASP.NET Core host, controllers, SignalR hub, security middleware
NodePilot.Cli/ `np` — operations CLI (Spectre.Console.Cli), shipped in both installers under tools\np
NodePilot.Mcp/ `nodepilot-mcp` — MCP server for AI agents (ModelContextProtocol), shipped under tools\mcp
NodePilot.Switcher/ WPF utility for exclusive local NodePilot/SCOrch service control
nodepilot-ui/ React 19 SPA (Vite 8 + Tailwind CSS 4 + React Flow 12)
nodepilot-docs-ui/ Documentation website (Vite + React SPA) — its OWN curated markdown corpus under content/{de,en}/, maintained alongside docs/ (not a 1:1 render)
nodepilot-desktop/ Electron shell for the desktop app — thin hardened viewer, no business logic
tests/
NodePilot.Engine.Tests/ xUnit — engine + every activity executor
NodePilot.Ai.Tests/ xUnit — LLM client factory, endpoint guard, prompt catalog, gen/chat services
NodePilot.Data.Tests/ xUnit — EF context + migrations
NodePilot.Api.Tests/ xUnit — controllers, auth, telemetry, validation
NodePilot.Cli.Tests/ xUnit + WireMock.Net — CLI ApiClient + DPAPI TokenStore
NodePilot.Mcp.Tests/ xUnit + WireMock.Net — MCP tools + stdio-process smoke test
NodePilot.LoadTests/ Standalone load harness (Console EXE, HdrHistogram)
NodePilot.Switcher.Tests/ xUnit — discovery, state machine, fail-closed switching
NodePilot.TestCommons/ Shared test infrastructure (TestDbFactory, FakeLlmClient, fixtures)
grafana/ Docker-compose stack: Prometheus + Grafana + 10 dashboards
deploy/ Production install / update / uninstall PowerShell scripts
docs/ Feature docs (AI, styleguide, perf, security, deployment)
samples/ Example workflows for the importer
Dependency graph:
Api → Ai, Engine, Scheduler, Data, Remote, Core, Telemetry
Engine → Ai, Data, Remote, Core, Telemetry
Ai → Core · Data → Core · Remote → Core · Telemetry → Core
Cli → Core · Mcp → Core (HTTP-only — no backend project references)
Six CI jobs gate every pull request and every push to main: backend build + tests with an
enforced 85 % line / 70 % branch coverage gate, frontend lint/build/vitest, docs-site
lint/tests/build, desktop-shell typecheck + tests, and hermetic Playwright E2E. A local nightly
task runs the same four suites against the checked-out tree.
Tests are mandatory — every behaviour change ships with tests in the same change. Which tests you run locally is scoped to what you touched; the full suite is CI's job, not yours. Commands, the scoping rules, and the guard-test mapping are in CONTRIBUTING.md and CLAUDE.md.
Two conventions worth knowing before you write one: the WinRM remote layer is always mocked, and backend database tests run on in-memory SQLite — a test backend only, never a supported production provider.
Contributions are welcome. CONTRIBUTING.md has the full setup: prerequisites, how to get a local PostgreSQL and a first admin account, the build and test commands, and the conventions that CI enforces.
The short version:
Found a security problem? Do not open a public issue — SECURITY.md has the private reporting path. Everyone taking part is expected to follow the Code of Conduct.
CLAUDE.md and .agents/ are working notes for AI coding agents, not contributor documentation.
They are checked in deliberately: NodePilot is built with agentic engineering, so the context an
agent needs to work on this codebase belongs in the repository rather than in someone's private
setup. What that does not change is the bar every change has to clear — behaviour changes ship
with tests, and CI enforces the coverage gate on every pull request.
CONTRIBUTING.md is the file written for people.
NodePilot is licensed under the Apache License 2.0. You are free to use, modify, and distribute it — including commercially — provided you retain the copyright and license notices. See LICENSE for the full text.
scheduleTrigger./docs, without a login and without internet access, at the version actually installed.#/en/…, #/de/…). Note: it ships its own curated markdown corpus under content/en/ and content/de/ — changes to docs/ must be mirrored there deliberately (it is not a 1:1 render), and both languages must be kept in step or the parity test fails. It has two deployments: GitHub Pages, and wwwroot/docs inside the server artifact and desktop package, which the API serves at /docs.C#
58.7%
TypeScript
30.2%
PowerShell
6.1%
Python
1.8%
CSS
1.5%