release: prepare v0.4.0 HTTP transport release#29
Conversation
v0.4.0 implementation PR 3 — release polish + lockstep version bump + HTTP smoke + CLI surface. Brings the v0.4.0 release line into a publishable state. **Nothing is published; no git tag, no GitHub release.** Publishing happens through the existing Trusted Publishing workflow only after maintainer approval. Refs #22. What lands ---------- Versions (lockstep 0.3.0 → 0.4.0): - root package.json - packages/{core,sdk,scanner,openapi,cli}/package.json - apps/{mcp-server,demo-app,studio}/package.json - workspace dependency ranges ^0.3.0 → ^0.4.0 - apps/mcp-server/src/server.ts: SERVER_VERSION → "0.4.0" - package-lock.json refreshed via `npm install --package-lock-only` - packages/openapi/README.md: "method-based in v0.3.0" → "v0.4.0" Release artifacts: - docs/releases/v0.4.0.md — full release notes (summary, transport, security posture, env vars, stdio compat, Codex / Claude / generic notes, OpenAPI fixtures, adopter docs, migration, verification, publishing checklist, non-goals, PR links #23 / #24 / #25 / #26 / #27 / this, safety invariants explicitly preserved). - examples/http-client-config/README.md — local-dev recipe, curl smoke (missing/wrong/query-token/bad-origin/valid), generic hosted-MCP-client JSON shape, Codex / Claude note, public-bind caution. Placeholder token only; no secrets. - examples/README.md — adds http-client-config row without overwriting the PR #25/#26 rows. Smoke / CI: - scripts/http-mcp-smoke.mjs — spawns the dist binary in HTTP mode on an ephemeral port and verifies: server starts cleanly + stdout empty, missing Authorization → 401, wrong bearer → 401, token in URL query string → 400 (no token in body), unknown Origin → 403, valid bearer + initialize → 200 with serverInfo {agentbridge, 0.4.0}, tools/list never leaks the token, shutdown clean, stderr never contains the token, http mode without auth token fails closed at startup, public bind without origin allowlist fails closed at startup. Exit code = number of failures. - package.json: new `npm run smoke:http` script. - scripts/external-adopter-smoke.mjs runs the HTTP smoke as a final step against the freshly built dist inside the temp snapshot, so `npm run smoke:external` exercises both transports end-to-end. CLI: - packages/cli/src/commands/mcp-config.ts prints an "HTTP transport (experimental, v0.4.0 — opt-in)" block with: env-var recipe (placeholder token only), generic hosted-client JSON config (transport: "streamable-http", url + Authorization header with ${AGENTBRIDGE_HTTP_AUTH_TOKEN} placeholder), safety reminder updated for outbound vs inbound allowlists, query-token rejection, public-bind fail- closed. - packages/cli/src/tests/cli.test.ts asserts every new line plus a regex assertion that no real-looking bearer token leaks to stdout. Docs: - README.md: status block to "v0.4.0 release-prepared on `release/v0.4.0-http-polish`; not yet on npm"; HTTP roadmap bullet updated; release-notes pointer. - AGENTS.md: current-state block updated with PRs #23–#27 + this PR; HTTP opt-in note. - CLAUDE.md: production/v1.0 references list adds the v0.4.0 release-notes file. - docs/roadmap.md: v0.4.0 line marked release-prepared with file-path commitments; remaining gaps spelled out. - docs/v1-readiness.md: criteria #8 and #9 from "design complete" → "implemented opt-in in v0.4.0"; status block + transport surface row updated. - docs/threat-model.md: T14 rewritten with concrete v0.4.0 mitigations (bearer auth, no query tokens, exact Origin match, loopback bind, public-bind fail-closed, stdout hygiene preserved) and explicit remaining gaps (OAuth resource server, token rotation, scopes, caller-identity propagation, deployment guides). - docs/security-configuration.md (already v0.4.0-tone in PR #27); no further changes required here. - docs/mcp-client-setup.md (already covers experimental HTTP transport in PR #27); no further changes required here. - apps/mcp-server/README.md: opening sentence + status block refreshed to mention default stdio + opt-in HTTP. - apps/mcp-server/src/transports/README.md: PR 3 marked landed with file-path commitments. - CHANGELOG.md: Unreleased content moved into a v0.4.0 entry with full Added/Changed/Compatibility breakdown; previous Unreleased docs lines folded into v0.4.0 since they ship in the same release line. Verification (locally on the working tree) ------------------------------------------ npm run typecheck:clean → green npm test → 185/185 green (174 prior + 11 openapi-fixtures from PR #26) npm run build → six packages OK; mcp-server bundle 40.3 KB ESM npm run pack:dry-run → six tarballs OK at 0.4.0 npm run smoke:http → 13/13 ok against the built dist (token never logged) node apps/mcp-server/dist/index.js < /dev/null → exit 0; serverInfo {agentbridge, 0.4.0}; stderr empty. node packages/cli/dist/bin.js version → 0.4.0 node packages/cli/dist/bin.js mcp-config → prints stdio + HTTP blocks; no real token. node packages/cli/dist/bin.js validate examples/adopter-quickstart/manifest.basic.json → ✓ valid node packages/cli/dist/bin.js validate examples/adopter-quickstart/manifest.production-shaped.json → ✓ valid node packages/cli/dist/bin.js generate openapi examples/openapi-regression/catalog-regression.openapi.json --out /tmp/agentbridge.openapi-regression.generated.json && validate /tmp/agentbridge.openapi-regression.generated.json → 8 actions; ✓ valid npm run smoke:external → green (run after this commit since the script snapshots HEAD; results inline in the PR description). Confirmations ------------- - ✅ stdio remains the default. No HTTP listener opens unless AGENTBRIDGE_TRANSPORT=http. - ✅ HTTP requires AGENTBRIDGE_HTTP_AUTH_TOKEN; missing/short token fails closed at startup. - ✅ Tokens in URL query strings rejected with 400. - ✅ Origin allowlist exact-match; CORS never wildcard with credentials. - ✅ Public bind requires both auth and Origin allowlist or fails closed at startup. - ✅ Confirmation gate, origin pinning, target-origin allowlist, idempotency, audit redaction, simulated destructive demo actions — all unchanged. - ✅ Stdout hygiene preserved (stdio-hygiene 3/3 + http-mcp-smoke asserts stdout empty across the run). - ✅ Bearer token never in stdout, stderr, audit, or HTTP error bodies. - ✅ No npm publish, no git tag, no GitHub release. - ✅ Dependabot PRs untouched. - ✅ Codex PR #25 (already on main) and PR #26 (merged before this PR opened) untouched; no edits to CHANGELOG.md beyond moving the Unreleased section into the v0.4.0 entry, no edits to examples/README.md beyond appending the http-client-config row. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b69452424c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| out.write(`${c.dim("Generic hosted-MCP-client config (adapt to your client):")}\n`); | ||
| out.write(indentBlock(JSON.stringify(httpClientConfig, null, 2)) + "\n"); | ||
| out.write(` ${c.dim("# Resolve ${AGENTBRIDGE_HTTP_AUTH_TOKEN} via your client's secrets manager — never commit the literal token.")}\n\n`); |
There was a problem hiding this comment.
Escape env-var placeholder in mcp-config output
The string passed to out.write interpolates ${AGENTBRIDGE_HTTP_AUTH_TOKEN} as a JavaScript identifier, but that variable is not defined in this module. As a result, running agentbridge mcp-config throws a ReferenceError at runtime before the command finishes, so users cannot get the config snippet. Print the placeholder literally (for example, by escaping $) instead of interpolating it.
Useful? React with 👍 / 👎.
v0.4.0 implementation PR 3 — release polish + lockstep version bump
publishable state. Nothing is published; no git tag, no GitHub
release. Publishing happens through the existing Trusted
Publishing workflow only after maintainer approval.
Refs #22.
Predecessor PRs
createMcpServer()factory)Version bump
Lockstep
0.3.0→0.4.0across:package.jsonpackages/{core,sdk,scanner,openapi,cli}/package.jsonapps/{mcp-server,demo-app,studio}/package.json^0.3.0→^0.4.0apps/mcp-server/src/server.tsSERVER_VERSION→"0.4.0"package-lock.jsonrefreshed vianpm install --package-lock-onlypackages/openapi/README.md"method-based in v0.3.0" → "v0.4.0"Release artifacts added
docs/releases/v0.4.0.md— fullrelease notes (summary, transport, security posture, env vars,
stdio compat, Codex / Claude / generic notes, OpenAPI fixtures,
adopter docs, migration, verification, publishing checklist,
non-goals, PR links, safety invariants explicitly preserved).
examples/http-client-config/— local-dev recipe, curl smoke (missing/wrong/query-token/
bad-origin/valid), generic hosted-MCP-client JSON, public-bind
caution. Placeholder token only; no secrets.
examples/README.md— addshttp-client-configrow without overwriting PR docs: add adopter quickstart and manifest patterns #25/test(openapi): add converter regression fixtures #26 rows.HTTP smoke wiring
scripts/http-mcp-smoke.mjs—spawns the dist binary in HTTP mode on an ephemeral port and
verifies:
Authorization→401,401,400(no token in body),Origin→403,initialize→200withserverInfo {agentbridge, 0.4.0},startup.
package.jsonexposesnpm run smoke:http.scripts/external-adopter-smoke.mjsruns the HTTP smoke as a final step against the freshly-built
dist inside the temp snapshot, so
npm run smoke:externalexercises both transports end-to-end.
CLI mcp-config
agentbridge mcp-confignow prints an"HTTP transport (experimental, v0.4.0 — opt-in)" block:
transport: "streamable-http",url,Authorization: Bearer ${AGENTBRIDGE_HTTP_AUTH_TOKEN}placeholder),
query-token rejection, public-bind fail-closed.
packages/cli/src/tests/cli.test.tsasserts every new line plus a regex assertion that no
real-looking bearer token leaks to stdout.
Docs updated
README.md— status block now says v0.4.0release-prepared on this branch; not yet on npm.
AGENTS.md— current-state block lists PRsdocs: design v0.4.0 HTTP MCP transport and auth #23–feat(mcp-server): add opt-in HTTP transport with bearer auth #27 + this PR; HTTP opt-in note.
CLAUDE.md— references list addsdocs/releases/v0.4.0.md.docs/roadmap.md— v0.4.0 line markedrelease-prepared with file-path commitments and explicit
remaining gaps.
docs/v1-readiness.md— criteria build(deps): bump zod from 3.25.76 to 4.3.6 #8and build(deps): bump marked from 14.1.4 to 18.0.2 #9 from "design complete" → "implemented opt-in in
v0.4.0"; status block + transport surface row updated.
docs/threat-model.md— T14 rewrittenwith concrete v0.4.0 mitigations (bearer auth, no query
tokens, exact Origin match, loopback bind, public-bind
fail-closed, stdout hygiene preserved) and explicit remaining
gaps (OAuth resource server, token rotation, scopes,
caller-identity propagation, deployment guides).
apps/mcp-server/README.mdandapps/mcp-server/src/transports/README.md— opening sentence + status / migration plan refreshed.
CHANGELOG.md—Unreleasedcontent movedinto a
0.4.0 — release-preparedentry with fullAdded/Changed/Compatibility breakdown.
Verification
Confirmations
AGENTBRIDGE_TRANSPORT=http.AGENTBRIDGE_HTTP_AUTH_TOKEN. Missing/short token fails closed at startup.400. Verified by HTTP smoke.stdio-hygiene.test.ts3/3 + http-mcp-smoke asserts stdout is empty across the HTTP run.CHANGELOG.mdandexamples/README.mdoutlined above.Test plan
npm run typecheck:cleangreen locally.npm test— 185/185 green locally.npm run build— six packages OK at 0.4.0.npm run pack:dry-run— six tarballs OK at 0.4.0.npm run smoke:http— 13/13 ok against the built dist.npm run smoke:external— PASS against the just-committed branch.version/mcp-config/validate/generate openapiall green.Recommended next step
If all CI tracks are green, ask the maintainer for explicit
approval to publish
@marmarlabs/agentbridge-*@0.4.0via theexisting Trusted Publishing workflow. Do not publish without
explicit approval.
🤖 Generated with Claude Code