Noodle Seed
Guides

Self-host the engine

Run the Noodle Seed engine yourself — local development with no account, the standalone service, and the portability guarantee.

Noodle is built so the engine is yours to run. The compiler, runtime, protocol/transport, compute sandbox, authoring SDK, and CLI are the open-source core (see the open-core table in the the open-core boundary). You can develop, run, and operate Noodle MCP servers without a Noodle Seed account.

There are two self-host levels, smallest first:

  1. Local dev (zero account, zero config)noodle dev, already covered below.
  2. Standalone service — the multi-tenant deploy service on your own host.

1. Local dev — zero account, zero login

With Node 24+, the magic moment needs no account, no service, and no global install:

npx @noodleseed/one@latest init my-app   # or: npm i -g @noodleseed/one && noodle init my-app
cd my-app
noodle dev
: # → MCP endpoint: http://127.0.0.1:<port>/o/local/my-app/dev/mcp

noodle init is safe to re-run — it only adds missing scaffold files and preserves your edits (pass --force to overwrite, --dry-run --json to preview).

noodle dev boots the full runtime in-process, in-memory, on loopback — no Postgres, no master key, no OAuth. It hot-reloads server.ts on save. noodle validate (compile only) and noodle test (compile + MCP smoke) are the one-shot variants. None of these require noodle login or noodle link. See hosted-quickstart.md for the full local author loop.

2. Run the standalone service

The deploy service is a single stateless process that accepts tenant-scoped deploys and serves each app at /o/{org}/{app}/mcp (or /o/{org}/{app}/{env}/mcp). Build the workspace, then run the service binary:

git clone https://github.com/NoodleSeed-com/noodle-core
cd noodle-core
pnpm install
pnpm build
node packages/service/dist/main.js
: # → Noodle deploy service listening at http://127.0.0.1:8787

In its default form it runs in-memory on loopback with the control plane OPEN — a throwaway local multi-tenant instance. It boots, recovers, and serves tenant MCP routes with no external dependencies.

Deploys need a deployer identity. A deploy defaults to the owner-only access mode, and identity access modes require an authenticated deployer — so the bare open service serves apps but will reject an unauthenticated noodle deploy. To exercise the full deploy → call loop on the real binary, configure a deployer identity (the control-plane + owner auth knobs under Configuration below) — or just run the end-to-end harness, which boots the real binary with a local issuer and runs a deploy → call sweep:

pnpm e2e                 # or: node scripts/e2e-localhost.mjs

For the single-app inner loop with zero auth or config, prefer noodle dev (Section 1): it runs the same runtime in-process and is the fastest way to see the engine serve MCP locally.

Loopback-only by default, fail-closed otherwise. The open mode is safe only because it binds loopback. The service refuses to expose a non-loopback bind without deploy authentication — set a control-auth mode (below) before binding a public interface.

Configuration

The service is configured entirely through environment variables. Pick persistence and auth independently.

Network

VariableDefaultPurpose
PORT8787Listen port.
HOST127.0.0.1Bind address. Use 0.0.0.0 only with auth + a TLS proxy.
PUBLIC_BASE_URLExternal URL used when building endpoint URLs in responses.
NOODLE_TRUST_PROXYoff1/true behind a TLS-terminating proxy (enforces HTTPS + HSTS, trusts X-Forwarded-Proto).
NOODLE_LOG_LEVELinfodebug | info | warn | error.
NOODLE_WARM_ALLoffEager recompile-all-on-boot for pinned single-instance/on-prem; default is lazy recompile-on-first-request.

Persistence (omit both for in-memory; deploys are then lost on restart)

VariablePurpose
NOODLE_DATA_DIRFile-backed JSON artifact store in a local directory.
DATABASE_URLPostgres connection string (postgres://…).

When any persistence backend is set, secret encryption is required (fail-closed):

VariablePurpose
NOODLE_SECRET_MASTER_KEYBase64 32-byte key (e.g. openssl rand -base64 32); AES-256-GCM, key stays in process memory.

Control-plane + owner auth (required before exposing off loopback)

  • Control-plane deploys: set NOODLE_GOOGLE_CLIENT_ID to require a Google ID token for deploys (org membership gates them). NOODLE_CONTROL_PLANE_ADMINS is a comma-separated list of immutable canonical principal subjects (plus exact Google workload subjects when those workloads need admin operations). Direct-Google-only deployments temporarily accept admin emails for compatibility, but must replace them with subjects before configuring WorkOS. NOODLE_CONTROL_PLANE_ALLOWED_EMAIL_DOMAIN remains signup policy, not authorization.
  • Owner-only end-user auth, self-hosted authorization server: set NOODLE_OAUTH_ISSUER plus the Google client creds NOODLE_OAUTH_GOOGLE_CLIENT_ID / NOODLE_OAUTH_GOOGLE_CLIENT_SECRET / NOODLE_OAUTH_GOOGLE_REDIRECT_URI (optional NOODLE_OAUTH_SIGNING_KEY, NOODLE_OAUTH_ALLOWED_EMAIL_DOMAIN). The service then runs the authorization server (DCR + PKCE, federating human login through the configured upstream) so standard clients can sign in. Direct Google is the compatibility/default upstream. To make WorkOS available behind the same Noodle issuer, configure the complete WorkOS unit below; configuration alone does not change the Google/0% rollout. See ADR 0042.
  • Owner-only with an external issuer: set NOODLE_OAUTH_ISSUER + NOODLE_OAUTH_JWKS_URI; the runtime is only the resource server. See ADR 0041.

Optional WorkOS upstream-human unit (all three values or none)

VariablePurpose
NOODLE_OAUTH_WORKOS_CLIENT_IDAuthKit client for this environment.
NOODLE_OAUTH_WORKOS_REALMStable, environment-specific realm stored in immutable identity links.
NOODLE_OAUTH_WORKOS_API_KEYServer API key; inject from a version-pinned secret, never plain config.
NOODLE_OAUTH_WORKOS_AUTHENTICATION_METHODSOptional comma-separated allowlist. Defaults to GoogleOAuth,MagicAuth; GitHubOAuth, Password, and SSO require an explicit compatibility release.
NOODLE_OAUTH_CONSOLE_CLIENT_ID + NOODLE_CONSOLE_URLOptional stable first-party Console public client and exact Console origin; configure both together.

Register the exact derived callback <NOODLE_OAUTH_ISSUER>/oauth/workos/callback. A partial unit fails startup. Keep environments isolated and never log or render these values. Rollout state, identity import, and rollback are PostgreSQL-backed operator concerns described in the WorkOS migration runbook; they are not environment variables.

Direct Google control-plane compatibility and workload identity are separate. During migration, NOODLE_GOOGLE_HUMAN_AUTH_ENABLED=true retains the former; NOODLE_GOOGLE_WORKLOAD_SUBJECTS lists exact immutable CI/build subjects for the latter. Finalization may set human compatibility to false, but it must retain the workload list and NOODLE_GOOGLE_CLIENT_ID audience.

Optional billing observation and validation

VariablePurpose
NOODLE_BILLING_USAGE_HMAC_KEYStable base64-encoded 32-byte key that enables fail-open shadow observation of admitted connector-backed tools/call dispatches. Omit it to keep metering not_started.
NOODLE_BILLING_METER_VALIDATION_ENABLEDExplicitly enables the PostgreSQL-only fail-open version 2 validation mirror, durable writer health, and bounded maintenance/reconciliation scheduler. It does not prepare an epoch or activate enforcement.
NOODLE_BILLING_METER_CPU_ALWAYS_ALLOCATEDRequired true assertion whenever validation is enabled. The operator must separately ensure the host really supplies continuous CPU and keeps at least one instance/process running.

Use a distinct key per environment, and give every service replica in one environment the same value. Generate one with openssl rand -base64 32. Durable multi-replica reporting requires the shared PostgreSQL backend; an in-memory observer is process-local and resets on restart. Shadow observations are diagnostics only: this setting does not enable quota denial, overage, invoice evidence, or production-app enforcement. Changing the key breaks retry identity continuity, so rotate it only through a coordinated rollout that avoids serving traffic from old-key and new-key replicas at the same time.

Validation additionally requires the shared PostgreSQL backend and a full lowercase 40-character NOODLE_BUILD_SHA. Set both validation variables to true only after the process has continuous CPU outside request handling; an incomplete combination fails service startup. Every replica may run the validation runtime because PostgreSQL elects one scheduler leader, but at least one replica must remain warm for health evidence to stay fresh. Prepare and retire the release-bound validation epoch only through the audited CLI/API procedure in the authoritative-meter readiness runbook. Customer reads remain shadow/partial, and validation failure never changes request admission.

A persistent, encrypted, identity-protected self-host therefore looks like:

DATABASE_URL=postgres://user:pw@db.internal:5432/noodle \
NOODLE_SECRET_MASTER_KEY="$(openssl rand -base64 32)" \
NOODLE_OAUTH_ISSUER=https://noodle.example.com \
NOODLE_OAUTH_GOOGLE_CLIENT_ID=… NOODLE_OAUTH_GOOGLE_CLIENT_SECRET=… \
NOODLE_OAUTH_GOOGLE_REDIRECT_URI=https://noodle.example.com/oauth/google/callback \
PUBLIC_BASE_URL=https://noodle.example.com HOST=0.0.0.0 NOODLE_TRUST_PROXY=1 \
node packages/service/dist/main.js

The Postgres schema is created on first boot. Managed-cloud connector and key-custody adapters are composed outside the public self-host entrypoint; the in-memory path pulls none of them.

3. Anti-rug-pull guarantee — you own your app

Noodle Seed's business is distribution and generation, not lock-in. Concretely:

  • Your server.ts is yours — and it is the source of truth. It is plain TypeScript using the open-source authoring SDK (bundled in the Apache-2.0 @noodleseed/one package). It is declarative data in TypeScript syntax, not imperative code: fulfil bodies are symbolically recorded, not executed, and the SDK compiles it to the internal manifest. Keep server.ts in your own git repository — it is the user-owned, diffable, reviewable, portable artifact, not the hosted deployment.

  • The engine is open and free to self-host. The compiler, runtime, protocol/transport, compute sandbox, authoring SDK, and CLI run on your own infrastructure forever (Section 2). The same server.ts runs unchanged on a self-hosted engine — noodle dev and a self-hosted deploy service use the same runtime.

  • The eject path is simply: keep server.ts in version control, run the open-source engine yourself, and point your MCP clients at your own endpoint. No data is trapped behind the managed service.

  • Manifest export (quiet fallback). noodle export manifest compiles server.ts locally — no service, no login — and writes a vendor-neutral manifest JSON:

    noodle export manifest --output manifest.json

    This is retained as a quiet fallback for users who want the compiled data shape. The foregrounded user-owned artifact is server.ts; the manifest/runtime-artifact is otherwise an internal intermediate representation that lets one runtime serve many MCP servers and is not a public authoring surface.

Honest limits (today): the manifest schema does not yet carry a formal cross-version compatibility SLA, and commercial governance modules (advanced policy/audit/auth) are separate from the open core. Self-hosting gives you the full open-core engine; it does not bundle those commercial modules. See the open-core module roadmap.

On this page