Skip to content

chore(release): 0.8.0 - #34

Open
imbenrabi wants to merge 10 commits into
mainfrom
claude/project-thread-4ocdp6
Open

imbenrabi wants to merge 10 commits into
mainfrom
claude/project-thread-4ocdp6

Conversation

@imbenrabi

@imbenrabi imbenrabi commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Ben · project thread

Before: main is at 0.7.0, and the finished changes for 0.8.0 (#29 to #33) have no release entry.

After: version 0.8.0 with one changelog entry covering all five, plus one small addition: PermissionAwareFastifyTransport now rejects a client whose startup toolsets failed to load, the follow-up #33 and #30 asked for. Docs match the new behaviour. Nothing is tagged or published.

Merge order (read first)

Base is main. #29, #30, #32 and #33 have merged. #31 is still open, so this draft branch contains it merged in. Merge #31 first; this PR's diff then shrinks to the release commits and merges cleanly on top. Do not rebase or force-push the PR branches.

PR Change State
#29 enable_toolset/disable_toolset advertise destructiveHint: false merged
#30 permission-aware transport waits for the orchestrator before connect() merged
#31 disable_toolset removes the toolset's tools open
#32 opt-in http.allowedOrigins Origin check on /mcp merged
#33 failed startup toolset registration fails initialize and STATIC startup (Breaking) merged

This release ships #33 as written (Strict semantics).

What the release adds beyond the five PRs

  • package.json / package-lock.json 0.7.0 to 0.8.0, and CHANGELOG.md [0.8.0] replacing [Unreleased], with Breaking, Added, Changed and Fixed sections and migration notes covering fix: mark enable_toolset and disable_toolset as non-destructive #29 to fix: reject STATIC clients whose startup toolsets failed to load #33.
  • PermissionAwareFastifyTransport: isReady() false gives 500 / JSON-RPC -32603 and drops the cached bundle, as FastifyTransport does. This is internal hardening: the class is not public API, and createPermissionBasedMcpServer (which enables toolsets itself, starts its orchestrators with no toolsets and continues on partial failure) is unchanged. Two transport-level e2e tests fail without it, and two tests through the public factory pin the real behaviour.
  • Docs: README (startup failure behaviour), root AGENTS.md invariant 4 (loader errors stay silent, registration failures no longer do) and src/permissions/AGENTS.md. allowedOrigins, destructive hints and disable-removes-tools were already documented by their PRs.

Verification

  • npm run typecheck, npm run test:run (395 tests) and npm run build pass.
  • npm publish --dry-run: toolception@0.8.0, 64 files, 107 kB; only dist/, package.json, README.md, CHANGELOG.md and LICENSE; no src/, tests or env files.
  • npm run verify:toolception in the FMP server (main, 2.7.0) against the packed tarball: 19/21. Both failures are expected and are server work that must merge first:
    1. ALL_TOOLS does not start: the calendar and earnings toolsets both list the earnings-transcript module, so getLatestEarningsTranscripts collides (src/constants/toolSets.ts). The server needs a catalog fix, being done in a separate project thread.
    2. The dynamic smoke test should disable toolset (state only, tools remain) asserts the old disable behaviour. Fixed by server #113. (The same overlap breaks the legacy/all-tools smoke tests and the installation checks.)
  • TS reviewer (pipeline-ts-reviewer): APPROVE in round 3; findings and fix mappings are in the comments below.

Server prerequisites before the FMP server takes 0.8.0

  1. Merge server #113.
  2. Merge the catalog fix that removes the duplicate earnings-transcript module from one of calendar / earnings.
  3. After 0.8.0 is on npm: npm run verify:toolception -- --source 0.8.0 must be green, then the dependency bump PR, with the docs that say disable is "state tracking only" (docs/USAGE.md, src/endpoints/server-card.ts) changed together with it.

Release steps (Ben)

After #31 and this PR are merged: tag v0.8.0 on main HEAD (release.yml publishes to npm and creates the GitHub Release). The command is in the project thread.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jke6dnq5CNkrDFWbJSHJWr

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jke6dnq5CNkrDFWbJSHJWr
…ets failed to load

Mirrors FastifyTransport: a not-ready bundle gets a 500 / -32603 on
initialize and is dropped from the cache. Docs updated for 0.8.0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jke6dnq5CNkrDFWbJSHJWr
@imbenrabi imbenrabi self-assigned this Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

TS review: pipeline-ts-reviewer (feature-pipeline) — round 1

Verdict: REQUEST_CHANGES. The permission-aware isReady() guard is correct as code and mirrors FastifyTransport, and the version bump is consistent. But the 0.8.0 changelog and docs claim a behaviour change for createPermissionBasedMcpServer that the code cannot deliver.

Reviewed: the full diff against main (head a2857cf) plus ServerOrchestrator.ts, DynamicToolManager.ts, createPermissionBasedMcpServer.ts, permissions.utils.ts, PermissionAwareFastifyTransport.ts, createMcpServer.ts, the src/index.ts exports, ModuleResolver, ClientResourceCache, package.json and package-lock.json. Static analysis only.

# Sev Location Finding
1 HIGH CHANGELOG.md [0.8.0] Breaking, first bullet Says createPermissionBasedMcpServer clients with failing startup toolsets now get -32603 / HTTP 500. False: the permission orchestrator is built with toolsets: [], createPermissionAwareBundle enables toolsets itself, partial failure still connects (failedToolsets), total failure is 403, so isReady() never goes false there.
2 MEDIUM CHANGELOG.md [0.8.0] Fixed (#30) Describes PermissionAwareFastifyTransport, which is not exported from src/index.ts, racing on background preload. Unreachable via the public factory, which awaits enableToolsets before returning.
3 MEDIUM src/permissions/AGENTS.md flow; root AGENTS.md invariant 4 Imply the isReady / 500 path covers permission clients, and contradict "partial success continues with warning".
4 MEDIUM tests/e2e/permissionBased.e2e.test.ts (new describes) Build the transport directly with hand-made bundles, so they pass while the public path is unchanged and hide finding 1. Label as transport-level, and pin the real behaviour through createPermissionBasedMcpServer.
5 LOW README.md startup note "activates with no tools" overstates it; other modules in the toolset still register ("fewer tools").
{
  "recommendation": "REQUEST_CHANGES",
  "summary": "Version bump and most changelog/doc claims match the code, but the Breaking entry (and related docs/tests) claim createPermissionBasedMcpServer clients now get a 500/-32603 on failed startup toolsets, which cannot happen because that factory enables toolsets itself, tolerates partial failure, and leaves orchestrator.isReady() always true.",
  "findings": [
    { "severity": "HIGH", "file": "CHANGELOG.md", "line": null, "issue": "Breaking entry claims permission-based clients get -32603/500 on failed startup toolsets; false for the public factory." },
    { "severity": "MEDIUM", "file": "CHANGELOG.md", "line": null, "issue": "Fixed entry for #30 describes an unexported class racing on preload; unreachable via createPermissionBasedMcpServer." },
    { "severity": "MEDIUM", "file": "src/permissions/AGENTS.md", "line": null, "issue": "Permission Flow and root invariant 4 imply the isReady/500 path covers permission clients and contradict partial-success behaviour." },
    { "severity": "MEDIUM", "file": "tests/e2e/permissionBased.e2e.test.ts", "line": null, "issue": "New e2e tests bypass the public factory and mask the changelog inaccuracy." },
    { "severity": "LOW", "file": "README.md", "line": null, "issue": "'activates with no tools' vs 'fewer tools' elsewhere." }
  ]
}

Generated by Claude Code

createPermissionBasedMcpServer enables toolsets in its bundle factory and
continues on partial failure, so the isReady() rejection does not apply.
Pin that with a public-factory test and label the transport-level tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jke6dnq5CNkrDFWbJSHJWr

Copy link
Copy Markdown
Contributor Author

Fixes for the round 1 TS review

All five findings were correct (I confirmed the permission flow in permissions.utils.ts: toolsets are enabled in the bundle factory, partial failure continues, all-failed throws and becomes a 403). Fixed in 0349957.

# Finding Fix
1 (HIGH) Breaking entry claimed permission-based clients get 500 / -32603 Entry now covers STATIC createMcpServer only, and says createPermissionBasedMcpServer is unaffected (partial failure still connects with failedToolsets, all failed is still 403).
2 (MEDIUM) #30 Fixed entry described an unreachable race Reworded as hardening of the transport for hand-built createPermissionAwareBundle bundles; says the public factory's behaviour is unchanged.
3 (MEDIUM) src/permissions/AGENTS.md flow and root invariant 4 implied the guard covers permission clients Both now say only a hand-built bundle can be not ready, and that createPermissionBasedMcpServer continues on partial failure. Root invariant 4 names it as the exception.
4 (MEDIUM) e2e tests bypassed the public factory The two transport tests are labelled "transport level". New e2e case through createPermissionBasedMcpServer pins the real behaviour: partial failure connects with the good toolset's tools, all failed is refused. 395 tests pass.
5 (LOW) README said "no tools" Now "fewer tools", matching the other docs.

The guard itself stays: it is a small mirror of FastifyTransport for the exported-in-spirit custom-bundle path, and the review found the code correct.


Generated by Claude Code

…ening

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jke6dnq5CNkrDFWbJSHJWr

Copy link
Copy Markdown
Contributor Author

TS review: pipeline-ts-reviewer — round 2 (head 0349957)

Verdict: COMMENT (no CRITICAL/HIGH). All five round-1 findings were fixed correctly and truthfully, every [0.8.0] changelog and doc claim checked matches the code, and the fix commit introduced nothing new. Three LOW notes:

# Sev Location Finding Fix (1c58bb8)
1 LOW CHANGELOG.md Fixed (#30) "hand-built createPermissionAwareBundle callback" implies a path consumers have; the class and helper are not exported. Reworded as internal hardening: the class is not public API and createPermissionBasedMcpServer is unchanged.
2 LOW permissionBased.e2e.test.ts "all failed" Bare rejects.toThrow() passes on any error. Now asserts /Access denied/ (the 403 body).
3 LOW permissionBased.e2e.test.ts partial failure Did not assert the failed toolset's tool is absent. Now asserts dup.ping is not listed, which also pins the #31 rollback on the public path.
{"recommendation":"COMMENT","summary":"All five round-1 findings fixed correctly and truthfully; only LOW polish remains.","findings":[{"severity":"LOW","file":"CHANGELOG.md","line":null,"issue":"#30 entry implies a user-reachable path; reword as internal hardening."},{"severity":"LOW","file":"tests/e2e/permissionBased.e2e.test.ts","line":null,"issue":"bare rejects.toThrow() in the all-failed test."},{"severity":"LOW","file":"tests/e2e/permissionBased.e2e.test.ts","line":null,"issue":"partial-failure test does not assert the failed toolset's tool is absent."}]}

All three are addressed in 1c58bb8 (typecheck clean, 395 tests pass). Round 3 follows to confirm APPROVE.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

TS review: pipeline-ts-reviewer — round 3 (head 1c58bb8)

Verdict: APPROVE. All three round-2 LOW notes are fixed, the [0.8.0] changelog and touched docs match the code, and nothing new was found at any severity. CI is green on this head.

{"recommendation":"APPROVE","summary":"All three round-2 notes are fixed (CHANGELOG #30 reads as internal hardening, the all-failed test asserts /Access denied/, the partial-failure test asserts dup.ping is absent), the 0.8.0 CHANGELOG and touched docs match the code, and nothing new was introduced.","findings":[]}

Still a draft on purpose: #29-#33 are unmerged and are included in this branch. Merge them first, then mark this ready.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

TS review: pipeline-ts-reviewer — round 4, final (head 21dd24b)

Verdict: APPROVE, zero findings. Re-run on the minimal release diff now that #29 to #33 are all on main (8 files, +169/-11). Every claim in the [0.8.0] changelog was checked against the code, and nothing in 2381fd7..HEAD is missing from it. The PermissionAwareFastifyTransport guard mirrors FastifyTransport, with matching tests and docs. CI is green on this head.

{"recommendation":"APPROVE","summary":"Final release diff is minimal and correct: every CHANGELOG [0.8.0] claim (#29-#33) is verified against the code on the branch, nothing in 2381fd7..HEAD is missing, and the PermissionAwareFastifyTransport isReady() guard mirrors FastifyTransport with matching tests and docs.","findings":[]}

Marking ready for review.


Generated by Claude Code

@imbenrabi
imbenrabi marked this pull request as ready for review October 12, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants