|
|
||
|---|---|---|
| .. | ||
| credentials | ||
| icons | ||
| nodes | ||
| test | ||
| README.md | ||
| eslint.config.mjs | ||
| package-lock.json | ||
| package.json | ||
| tsconfig.json | ||
README.md
n8n-nodes-ndc
Private NODE.DC node package for provider-neutral L2 workflows. It extends n8n through the supported private-node mechanism and does not patch Engine or n8n core.
Every custom node has an NDC display-name prefix. Runtime types are package
qualified:
n8n-nodes-ndc.ndcDataProductPublish— publishes canonical facts into an approved Data Product.n8n-nodes-ndc.ndcDataProductRead— reads the current snapshot or a bounded, cursor-paged history window of an approved Data Product.n8n-nodes-ndc.ndcFoundryBinding— creates or updates a declarative Foundry page-slot binding. This is a control-plane operation, not a runtime data transport.
Security and scope
Workflow parameters contain no service URL, provider, tenant, connection, raw secret, or credential selector. Product selection is loaded from the catalog visible to the selected opaque capability. Service locations are operator-owned runtime overrides (the package defaults to the canonical internal service names, so the first deployment needs no extra Engine environment):
NDC_DATA_PLANE_BASE_URLNDC_FOUNDRY_BASE_URL
The defaults are http://external-data-plane:18106 and
http://nodedc-module-foundry:3333. They are provider-neutral Platform service
addresses, not workflow configuration.
The three credential types contain only one password-protected opaque capability. Writer, reader, and Foundry capabilities are intentionally distinct. Provider identity, product version, ontology revision, persistence policy, and tenant scope are materialized by the receiving service from the grant. The node never accepts them from a workflow.
Fixed routes
GET /internal/data-plane/v1/writer/data-productsGET /internal/data-plane/v1/reader/data-productsPOST /internal/data-plane/v1/data-products/:dataProductId/publishGET /internal/data-plane/v1/data-products/:dataProductId/snapshotGET /internal/data-plane/v1/data-products/:dataProductId/historyGET /internal/foundry/v1/data-productsPOST /internal/foundry/v1/data-product-bindings
There is no fallback to a legacy intake route. NDC Foundry Binding uses the
dedicated internal control-plane endpoint implemented by Foundry and fails
closed when that route or its scoped workload grant is unavailable. Its
canonical Map entity-stream slot defaults to points.
The binding command uses the versioned
nodedc.foundry.binding-upsert/v1 schema. Its opaque ndc_fndbg_* workload
grant is separate from the short-lived Foundry MCP capability used by AI
Workspace and from the shared Platform service token. The receiving service
materializes actor, owner and exact application/page/binding/product scope from
that grant; none of those authorization claims are accepted from headers or
workflow data.
NDC Data Product Read supports the bounded
nodedc.data-product.snapshot/v1 contract. Its snapshot Page Size parameter is a
safety ceiling, not pagination: the complete scoped current projection must fit
within 5000 entity keys. A larger product returns
data_product_snapshot_limit_exceeded; the node must not assemble independent
pages or start a patch stream from an incomplete snapshot. Large products need
stable partition Data Products.
History mode uses nodedc.data-product.history/v1 and requires a closed
from/to interval. It supports provider-neutral sourceIds, a resolution
that is a multiple of the Data Product native sampling interval, a limit up to
5000 points and an opaque keyset continuation cursor. The response stays as one
envelope item so L2 logic can preserve query and nextCursor while iterating.
The workflow never selects a database, provider, tenant or connection.
Publish input
Each incoming item must be either a canonical fact or { "fact": <fact> }:
{
"sourceId": "fleet.unit.42",
"semanticType": "map.moving_object",
"observedAt": "2026-07-15T12:00:00.000Z",
"attributes": {},
"geometry": { "type": "Point", "coordinates": [37.61, 55.75] }
}
The node emits nodedc.data-product.publish/v1, enforces the 5000-fact and
64-KiB-per-attributes limits, rejects secret-like material in attributes, and
derives stable run/idempotency identifiers from workflow execution context.
Build and verification
npm install
npm test
npm run lint
The package must be installed as an n8n private community package under the runtime user's community-package root:
/home/node/.n8n/nodes/node_modules/n8n-nodes-ndc
The parent /home/node/.n8n/nodes/package.json owns the pinned package
registration. ~/.n8n/custom and N8N_CUSTOM_EXTENSIONS are deliberately not
used: n8n loads those through the CUSTOM namespace, which would destroy the
required n8n-nodes-ndc.* runtime types.
Deployment boundary
The Platform MCP catalog bridge preserves package-qualified custom runtime
types, but Engine can expose these schemas only after this private package is
installed through the community-package path and the bridge slice is deployed.
Production installation uses a verified offline tarball, an immutable
root-owned release, an atomic current/previous switch and a read-only mount; it
does not run npm install inside a live container. This package deliberately
does not patch Engine or n8n core.
The Platform-side release builder is:
node ../../infra/deploy-runner/build-n8n-private-extension-artifact.mjs \
n8n-nodes-ndc-release-YYYYMMDD-NNN
Its canonical deploy component only stages and seals a digest-bound release
under /volume1/docker/nodedc-platform/n8n-private-extensions; it does not
activate anything in Engine. Activation is intentionally blocked until an
Engine-owned deployment slice provides the exact read-only community-package
mount, atomic release selection, all-process restart and MCP schema acceptance.
The v2 rollback contract accepts a pre-activation, explicitly verified inactive
baseline for the first activation; subsequent upgrades prefer a previous
verified immutable release. The staged v1 0.1.0 release is never overwritten:
this contract is published as a separate 0.1.1 release.