nw-connector-builder — scope¶
nw-connector-builder targets a specific, common shape of REST API (single connector-level
auth scheme, JSON-first bodies, no pagination) and soft-drops anything outside that shape
rather than trying to support every corner of OpenAPI/Swagger. This page is the scope
reference: what the generator handles today, what it deliberately does not, and what's
skipped-but-flagged per build. For usage, flags, and the codegen pipeline itself, see
nw-connector-builder.md.
In scope¶
Spec ingestion¶
- Swagger 2.0 and OpenAPI 3.x, YAML or JSON, UTF-8
- Local file path or
http(s)URL (remote fetch goes through Node Wire's SSRF guard,assert_safe_destination, no redirects followed) - In-house Swagger 2.0 → OpenAPI 3.0 normalization at the front door
- Local relative
$refs and in-document#/refs - Structural + semantic validation via
prance+openapi-spec-validator
Auth¶
- One connector-level scheme, chosen from the document's top-level
security(or the most common scheme across operations if none is declared) apiKeyinheaderorquery,httpbearer,httpbasic— mapped to Node Wire'sstatic_token/apikey_queryauth providers- Anonymous connectors (no scheme, or only unsupported schemes present) build as
auth: none
Codegen¶
- Actions discoverable via
@nw_actionon a generatedRestConnectorsubclass (regex-scrapable bynw-mcp-builder, matching the hand-written-connector convention) - A shared, hardened REST executor (
node-wire-runtime) owns base URL, path templating, parameter placement, auth injection, SSRF checks, and error mapping - Hybrid schema translation:
datamodel-code-generatorfor request/response schemas, hand-rolled per-operation input envelope with anaction: Literaldiscriminator - Non-JSON request bodies (form data, files, raw content) encoded by declared media type
- Typed output models from the lowest documented 2xx JSON response, falling back to a generic response envelope when no schema is documented
Testing & build gate¶
- Offline schema/contract tests only: parse the spec's
exampleinto the generated model when present, else synthesize one withpolyfactory - Generated tests ship with the connector (
packages/connectors/<id>/tests/) - Import smoke test +
pyteston staged output is a hard gate — promote only happens on green - Atomic two-phase promote into
src/node_wire_<id>/andpackages/connectors/<id>/; abort leaves the repo untouched
Wiring & hand-off¶
- Optional
--wire: upsertsconfig/connectors.yaml(comment-preserving viaruamel.yaml) and appends secret placeholders / allowlist entries tosample.env - Automatic hand-off to
nw-mcp-builderafter a clean promote (unless--no-mcp), producing an MCP host undernw-mcp-builder/out/
Out of scope¶
Auth schemes¶
- OAuth2 and OpenID Connect — operations secured only by these are soft-dropped, not supported with a workaround
- mutualTLS
- Cookie-based API keys
- AND-combined multi-scheme security (
security: [{a: [], b: []}]) - More than one auth provider per connector — a connector is single-scheme, even if the spec declares several; operations needing a divergent scheme are soft-dropped
- Per-operation auth overrides — auth is connector-level only
Spec features¶
- Remote
$refs (absolute URLs) — rejected outright; the input document must be self-contained aside from local relative/#/refs - Path- or operation-level
serversoverrides — ignored; only the connector-level base URL is used (noted in the build report when present) - Uncommon parameter serialization:
deepObjectquery style, non-simplepath/header styles, unsupportedcollectionFormatvalues (Swagger 2.0) — soft-dropped per operation in: cookieparameters — soft-dropped per operation
Behavior not generated¶
- Pagination — no auto-pagination in v1, even when the spec documents cursor/offset patterns; generated actions return one page as-is
- Rate-limit / observability metadata — not derived from the spec (e.g.
x-ratelimit-*extensions are ignored); deferred, not designed - Complex/ambiguous request bodies and non-object success responses fall back to permissive
typing (
Any/RestResponseOutput) rather than a fully modeled schema
Testing depth¶
- Mock-server tests and live/integration tests against the real API are explicitly out of scope — only offline schema/contract tests against generated models are produced
- No contract testing against the live upstream service as part of the generator's gate
Registration & deployment¶
--wirenever editsconnector_registry.pyor the rootpyproject.toml— entry-point registration for editable monorepo installs is a manual follow-up step- Publishing (PyPI wheel
setup.py/Cython glue,scripts/build-packages.shallowlist entries, CI allowlists, standalone MCP Docker image rows) is a manual Tier 2/3 checklist in packaging.md — the builder produces the runtime + package skeleton only - No deployment step: the builder stops at a promoted connector (+ optional MCP host); running
thv/ToolHive deploy or verify is manual, perscripts/deploy-openapi-mcp-toolhive.md— this was explicitly dropped from the companionnw-cliorchestrator's scope too, see nw-cli.md
Editing generated output¶
- Generated files are marked "do not hand-edit" — there is no supported workflow for
incrementally patching a generated connector; the only supported update path is regenerating
with
--force(full overwrite, not a diff/merge)
Soft-drop vs. hard failure¶
Everything above that's "soft-dropped" means: the operation is skipped and listed in
report.json, but the build continues. The only way an out-of-scope feature aborts the build
is if it leaves zero usable operations — that's a hard failure (DeriveError), since a
connector with no actions isn't useful. A coverage warning is also printed when fewer than 50%
of the document's operations survive derivation, even if the build otherwise succeeds.
This soft-fail-and-report design is deliberate: the generator is meant to get you most of the way there for typical REST APIs, with the report telling you exactly what to hand-write or follow up on for the rest — not to silently produce a broken or partial connector.