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

@forestadmin/workflow-executor

v1.15.0

Published

Run Forest Admin workflow steps on your own infrastructure.

Readme

@forestadmin/workflow-executor

Run Forest Admin workflow steps on your own infrastructure.

The executor polls the Forest orchestrator for pending steps, runs them locally (with access to your data via the Forest agent), and reports results back. No client data ever leaves your infrastructure.

Prerequisites

Make sure you are on the latest version of your Forest Admin agent (Node.js/JS or Ruby), then point your agent at the executor with workflowExecutorUrl:

createAgent({
  // ...
  workflowExecutorUrl: process.env.WORKFLOW_EXECUTOR_URL, // e.g. http://localhost:3400
})

This is required for the executor to work: when workflowExecutorUrl is set, the agent mounts the route that forwards workflow requests to the executor (and relays the JWT for auth). If it is left unset, the agent returns 404 on those routes and the executor never receives any work.

Drive it from an environment variable (WORKFLOW_EXECUTOR_URL above) so each deployment can target its own executor. The URL is where the agent reaches the executor — its HTTP server (default port 3400). When the agent and executor run on separate hosts behind a private network (e.g. an internal load balancer), use the executor's internal address, and make sure the agent can reach the executor's HTTP port.


Docker (recommended)

Quick start

cp .env.example .env   # fill in your secrets
docker compose up

The docker-compose.yml at the root of this package starts a single executor instance. See .env.example for the full list of environment variables and their descriptions.

Run directly

docker run -d \
  -e FOREST_ENV_SECRET="your-env-secret" \
  -e FOREST_AUTH_SECRET="your-auth-secret" \
  -e AGENT_URL="http://host.docker.internal:3351" \
  -e DATABASE_URL="postgres://user:[email protected]:5432/mydb" \
  -p 3400:3400 \
  ghcr.io/forestadmin/workflow-executor:latest

Note: When the executor runs in Docker and your agent runs on the host machine, use host.docker.internal instead of localhost in AGENT_URL and DATABASE_URL.

Observability (OpenTelemetry)

The Docker image ships with OpenTelemetry APM built in, and works with any OTLP-compatible backend (Datadog, Grafana Tempo, Jaeger, Honeycomb, etc.). It is off by default and turns on automatically as soon as you point it at an OTLP receiver — no code changes or extra installs required. Tracing is set up before the app starts (auto-instrumentation for HTTP, Postgres, etc.) and buffered spans are flushed on graceful shutdown.

Configure it entirely through the standard OTel environment variables:

| Variable | Description | | --- | --- | | OTEL_EXPORTER_OTLP_ENDPOINT | OTLP receiver URL (e.g. http://collector:4318). Tracing stays disabled until this is set. | | OTEL_SERVICE_NAME | Service name reported in traces. Default: forestadmin-workflow-executor. | | OTEL_RESOURCE_ATTRIBUTES | Extra resource attributes, e.g. deployment.environment=production,version=1.7.0. | | OTEL_SDK_DISABLED | Set to true to force-disable tracing even when an endpoint is configured. |

docker run -d \
  -e FOREST_ENV_SECRET="your-env-secret" \
  -e FOREST_AUTH_SECRET="your-auth-secret" \
  -e AGENT_URL="http://host.docker.internal:3351" \
  -e DATABASE_URL="postgres://user:[email protected]:5432/mydb" \
  -e OTEL_EXPORTER_OTLP_ENDPOINT="http://collector:4318" \
  -p 3400:3400 \
  ghcr.io/forestadmin/workflow-executor:latest

Note: OpenTelemetry is bundled only in the Docker image. It is not shipped with the npm package (npx @forestadmin/workflow-executor).


Without Docker

With a database

Requires Node.js ≥ 22.12.0 and a Postgres database:

FOREST_ENV_SECRET="your-env-secret" \
FOREST_AUTH_SECRET="your-auth-secret" \
AGENT_URL="https://your-agent-url" \
DATABASE_URL="postgres://user:pass@localhost:5432/mydb" \
npx @forestadmin/workflow-executor

Where to find your credentials:

Both values are already in your agent's environment variables. FOREST_ENV_SECRET can also be found in app.forestadmin.comSettingsEnvironments → click your environment. FOREST_AUTH_SECRET is defined on your side only and is not available in the Forest Admin UI.

AGENT_URL is the URL where your Forest Admin agent is running (e.g. http://localhost:3351).

Database connection

The Postgres connection can be provided in two ways. If DATABASE_URL is set, it is used as-is. Otherwise the executor builds the connection string from individual parts — handy when your platform exposes credentials as separate variables:

| Variable | Required | Description | | --- | --- | --- | | DATABASE_HOST | yes | Database host | | DATABASE_NAME | yes | Database name | | DATABASE_USER | yes | Database user | | DATABASE_PASSWORD | no | Database password | | DATABASE_PORT | no | Database port (default: 5432) |

FOREST_ENV_SECRET="your-env-secret" \
FOREST_AUTH_SECRET="your-auth-secret" \
AGENT_URL="https://your-agent-url" \
DATABASE_HOST="localhost" \
DATABASE_NAME="mydb" \
DATABASE_USER="user" \
DATABASE_PASSWORD="pass" \
DATABASE_SSL="false" \
npx @forestadmin/workflow-executor

DATABASE_SSL defaults to true (managed Postgres requires TLS); set it to false for a local database without TLS.

DATABASE_URL takes precedence: when it is set, the individual parts are ignored.


OAuth-protected MCP connectors

When your workflows use OAuth-protected MCP connectors, the executor stores each user's OAuth credentials in its database, encrypted at rest. Provide the encryption key the same way as the other secrets (in .env, or with -e on docker run):

| Variable | Description | | --- | --- | | FOREST_EXECUTOR_ENCRYPTION_KEY | At-rest encryption key (AES-256-GCM) for the OAuth credentials the executor stores. Generate with openssl rand -hex 32. Use a separate secret from FOREST_AUTH_SECRET. The value isn't validated, so use a genuinely random secret. |

  • Required only for OAuth-protected MCP connectors, and read lazily — an executor that stores no such credentials boots and runs fine without it.
  • Use the same value on every instance that shares a database. Otherwise an instance cannot decrypt credentials stored by another.
  • Treat it as permanent: there is no managed rotation. Changing it forces every affected user to reconnect their OAuth-protected MCP connectors.

Testing only

The following modes skip the database requirement but are not suitable for production — state is lost on restart.

Docker

docker run --rm \
  -e FOREST_ENV_SECRET="your-env-secret" \
  -e FOREST_AUTH_SECRET="your-auth-secret" \
  -e AGENT_URL="http://host.docker.internal:3351" \
  -p 3400:3400 \
  ghcr.io/forestadmin/workflow-executor:latest \
  node packages/workflow-executor/dist/cli.js --in-memory --json

Without Docker

FOREST_ENV_SECRET="your-env-secret" \
FOREST_AUTH_SECRET="your-auth-secret" \
AGENT_URL="https://your-agent-url" \
npx @forestadmin/workflow-executor --in-memory

OAuth2-protected MCP

To exercise the executor's OAuth2-protected MCP path end-to-end, point it at mcp-oauth-test-server — a standalone OAuth2 + MCP server that can simulate refresh-token revocation/rotation, consent denial, and upstream 403s.