@cyanheads/mcp-ts-core 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/changelog/0.8.x/0.8.0.md +17 -15
  4. package/changelog/0.8.x/0.8.1.md +17 -0
  5. package/changelog/0.8.x/0.8.2.md +18 -0
  6. package/changelog/template.md +13 -0
  7. package/dist/logs/combined.log +4 -4
  8. package/dist/logs/error.log +4 -4
  9. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.d.ts +13 -4
  10. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.d.ts.map +1 -1
  11. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.js +99 -25
  12. package/dist/mcp-server/transports/http/landing-page/assets/copy-script.js.map +1 -1
  13. package/dist/mcp-server/transports/http/landing-page/assets/styles.d.ts.map +1 -1
  14. package/dist/mcp-server/transports/http/landing-page/assets/styles.js +318 -8
  15. package/dist/mcp-server/transports/http/landing-page/assets/styles.js.map +1 -1
  16. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.d.ts.map +1 -1
  17. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.js +20 -1
  18. package/dist/mcp-server/transports/http/landing-page/sections/status-strip.js.map +1 -1
  19. package/dist/mcp-server/transports/http/landing-page/sections/tools.d.ts +6 -5
  20. package/dist/mcp-server/transports/http/landing-page/sections/tools.d.ts.map +1 -1
  21. package/dist/mcp-server/transports/http/landing-page/sections/tools.js +114 -69
  22. package/dist/mcp-server/transports/http/landing-page/sections/tools.js.map +1 -1
  23. package/package.json +1 -1
  24. package/skills/add-app-tool/SKILL.md +24 -8
  25. package/skills/add-service/SKILL.md +7 -1
  26. package/skills/add-tool/SKILL.md +3 -1
  27. package/skills/api-errors/SKILL.md +21 -1
  28. package/skills/field-test/SKILL.md +73 -13
  29. package/skills/maintenance/SKILL.md +22 -7
  30. package/templates/changelog/template.md +18 -5
package/CLAUDE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent Protocol
2
2
 
3
- **Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.0
3
+ **Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.2
4
4
  **npm:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) · **Docker:** [ghcr.io/cyanheads/mcp-ts-core](https://ghcr.io/cyanheads/mcp-ts-core)
5
5
 
6
6
  > **Developer note:** Never assume. Read related files and docs before making changes. Read full file content for context. Never edit a file before reading it.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  <div align="center">
7
7
 
8
- [![Version](https://img.shields.io/badge/Version-0.8.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--11--25-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE)
8
+ [![Version](https://img.shields.io/badge/Version-0.8.2-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--11--25-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE)
9
9
 
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.2-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
@@ -5,27 +5,29 @@ breaking: false
5
5
 
6
6
  # 0.8.0 — 2026-04-28
7
7
 
8
- Minor release introducing **typed error contracts** for tools and resources. Definitions can now declare `errors: [{ reason, code, when, retryable? }]` to advertise their failure surface in `tools/list` (under `_meta['mcp-ts-core/errors']`) and receive a typed `ctx.fail(reason, …)` keyed against the declared reason union TypeScript catches `ctx.fail('typo')` at compile time, the runtime auto-populates `data.reason` for observability, and a startup linter cross-checks the handler body against the contract. Fully backwards compatible: definitions without `errors[]` keep their existing `ctx: Context` signature and direct-throw behavior. Ships alongside two new utility modules (`httpErrorFromResponse`, `partialResult`) and three more error factories.
8
+ Typed error contracts for tools and resources. Backwards compatible — definitions without `errors[]` keep the existing `Context` signature.
9
9
 
10
10
  ## Added
11
11
 
12
- - **Typed error contracts on `tool()` / `resource()` / `appTool()` / `appResource()`** — new optional `errors: [{ code, reason, when, retryable? }]` field declares the public failure surface. The const-tuple shape preserves literal reasons through to the handler signature: `ctx.fail` is typed as `TypedFail<R>` where `R` is the union of declared `reason` strings, and `HandlerContext<ReasonOf<TErrors>>` collapses to plain `Context` when no contract is declared. Runtime `ctx.fail` constructs an `McpError` with the contract's code, the caller's message (or the `when` text as a fallback), and `data.reason` auto-populated from the contract — caller-supplied `data.reason` cannot override it, preserving `data.reason` as a stable observability identifier. New exports: `TypedFail`, `ReasonOf`, `HandlerContext`, `createFail`, `attachTypedFail` (internal) on `@cyanheads/mcp-ts-core`; `ErrorContract`, `ERROR_CONTRACT_META_KEY`, `buildMetaWithErrorContract` (internal) on `/errors`. Contracts surface in `tools/list` and `resources/list` under `_meta['mcp-ts-core/errors']`. The `appTool` / `appResource` builders forward the third type parameter so MCP App tools get the same compile-time guarantees as standard tools. The auto-task path in `tool-registration.ts` mirrors the standard handler factory's ctx construction so auto-task handlers calling `ctx.fail(...)` work — without `attachTypedFail` they would crash with `ctx.fail is not a function` when the contract is declared.
13
- - **`httpErrorFromResponse(response, opts?)` and `httpStatusToErrorCode(status)` in `/utils`** — replaces hand-rolled status→code ladders that consumer servers tend to write (and get wrong, especially for 401/403/408/422). Maps the full 4xx/5xx range with specific handling for auth failures, conflicts, validation, rate limits, and timeouts — see the table in the file's JSDoc. Captures the response body (truncated to 500 bytes by default) and `Retry-After` header into `error.data`, supports `cause` chaining, accepts a `service` name for the message subject and a `codeOverride` for upstream-specific quirks. New exports: `httpErrorFromResponse`, `httpStatusToErrorCode`, `HttpErrorFromResponseOptions`.
14
- - **`partialResult` / `partialResultSchema` / `failureEntrySchema` in `/utils`** — first-class helpers for the "partial success" tool-output pattern (a tool that processes N items and returns the ones that succeeded plus a structured list of the ones that failed, each with a stable `reason` enum). `failureEntrySchema` builds a `{ [idKey]: string; reason: TReason; detail?: string }` Zod object; `partialResultSchema` composes that with a typed succeeded array and totals; `partialResult` constructs the runtime object with the failed array conditionally omitted when empty so `structuredContent` stays clean. Generic over the success/failure key names so the surface mirrors the existing public API of any tool (no forced rename to `succeeded` / `failed`). New exports: `partialResult`, `partialResultSchema`, `failureEntrySchema`, `PartialResultObject`.
15
- - **Three more error factories: `internalError`, `serializationError`, `databaseError`** — fills the gaps in the factory set so handlers don't fall back to `new McpError(JsonRpcErrorCode.X, …)` for these common codes. All accept the standard `(message, data?, options?)` signature with `cause` chaining support.
16
- - **Handler-body lint rules** (`src/linter/rules/handler-body-rules.ts`) heuristic source-text scan that flags four common error-handling anti-patterns in tool and resource handlers: `prefer-mcp-error-in-handler` (plain `throw new Error(...)` should use `McpError` or a factory), `prefer-error-factory` (`new McpError(JsonRpcErrorCode.NotFound, …)` should use `notFound(…)`), `preserve-cause-on-rethrow` (`catch (e) { throw notFound(...) }` without `{ cause: e }` loses the chain), `no-stringify-upstream-error` (throwing a message containing `JSON.stringify(...)` risks leaking raw upstream traces — sanitize first or attach to `data`). All warnings, all surfaced via `bun run devcheck`, all hit at most once per definition to avoid noisy reports.
17
- - **Error-contract conformance lints** (`src/linter/rules/error-contract-rules.ts`) — when a definition declares `errors[]`, the linter validates structural invariants (`errors` is an array, each entry has `{ code, reason, when }`, `code` is a real `JsonRpcErrorCode`, `reason` is snake_case and unique) plus two cross-checks against the handler body: `error-contract-conformance` flags codes thrown from the handler that aren't declared (suggests adding them), `error-contract-prefer-fail` flags codes that ARE declared but get thrown via factory or `new McpError` instead of `ctx.fail(reason, …)`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble from anywhere and are auto-allowed by conformance, modeled after how OpenAPI-driven frameworks treat 5xx — implicit, not required to enumerate per-endpoint. Source-text scan only; codes thrown from called services are invisible (still classify correctly at runtime via the auto-classifier, just without lint enforcement).
18
- - **`createMockContext({ errors })` test option** pass the definition's own `errors` array (`createMockContext({ errors: myTool.errors })`) to attach a typed `ctx.fail` against the contract's reasons. Tests can then assert on `data.reason` without manually composing `createFail`. Mirrors the production handler factory's `attachTypedFail` wiring.
19
- - **Tests** `tests/unit/core/typed-fail.test.ts`, `tests/unit/linter/error-contract-rules.test.ts`, `tests/unit/linter/handler-body-rules.test.ts`, `tests/unit/mcp-server/tools/typed-error-contract.test.ts`, `tests/unit/utils/network/httpError.test.ts`, `tests/unit/utils/formatting/partialResult.test.ts`, plus expansion of `tests/unit/mcp-server/tools/tool-registration.lifecycle.test.ts` and `tests/unit/mcp-server/apps/appBuilders.test.ts` for typed-fail propagation through the auto-task and app-tool paths.
12
+ - **`errors: [{ reason, code, when, retryable? }]`** on `tool()` / `resource()` / `appTool()` / `appResource()`. Surfaces in `tools/list` and `resources/list` under `_meta['mcp-ts-core/errors']`. Const-tuple inference flows the reason union into the handler's `ctx.fail`.
13
+ - **`ctx.fail(reason, msg?, data?, opts?)`** — typed `TypedFail<R>` keyed against the contract's reasons. `ctx.fail('typo')` is a TS error. Constructs an `McpError` with the contract's code, message (defaults to `when`), and `data.reason` auto-populated from the contract caller-supplied `data.reason` cannot override it.
14
+ - **New core exports:** `TypedFail`, `ReasonOf`, `HandlerContext`, `createFail`. **New `/errors` exports:** `ErrorContract`, `ERROR_CONTRACT_META_KEY`, `buildMetaWithErrorContract`.
15
+ - **`httpErrorFromResponse(response, opts?)` and `httpStatusToErrorCode(status)` in `/utils`** — full 4xx/5xx `JsonRpcErrorCode` table (401/403/408/422/429/5xx). Captures truncated body and `Retry-After` into `error.data`. Supports `service`, `cause`, `codeOverride`. Exports `HttpErrorFromResponseOptions`.
16
+ - **`partialResult` / `partialResultSchema` / `failureEntrySchema` in `/utils`** typed succeeded/failed pattern with stable reason enums. Generic over key names. `failed[]` is omitted when empty. Exports `PartialResultObject`.
17
+ - **Three more factories on `/errors`:** `internalError`, `serializationError`, `databaseError`. Same `(message, data?, options?)` signature as the rest.
18
+ - **Handler-body lints** (warnings, surfaced in devcheck): `prefer-mcp-error-in-handler`, `prefer-error-factory`, `preserve-cause-on-rethrow`, `no-stringify-upstream-error`.
19
+ - **Contract lints** (warnings): structural validation (`error-contract-{type,empty,entry-type,code-type,code-unknown,reason-required,reason-format,reason-unique,when-required,retryable-type}`); conformance — `error-contract-conformance` flags undeclared codes thrown from the handler, `error-contract-prefer-fail` flags declared codes thrown directly instead of via `ctx.fail`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) auto-allowed.
20
+ - **`createMockContext({ errors })`** — attaches `ctx.fail` against a contract for tests.
21
+ - **Tests** for typed-fail propagation, the two new lint families, `httpErrorFromResponse`, `partialResult`, and the auto-task / app-tool integration paths.
20
22
 
21
23
  ## Changed
22
24
 
23
- - **`AGENTS.md` / `CLAUDE.md` / `templates/AGENTS.md` / `templates/CLAUDE.md` Error Handling sections rewritten** — leads with the typed error contract as the recommended path (with concrete `errors[]` + `ctx.fail` example), demotes plain-throw + factory usage to the fallback for ad-hoc cases, documents baseline-code auto-allow, references the new conformance and handler-body lint diagnostics, and links to `httpErrorFromResponse` for upstream API mapping. Exports table updated to include `createFail`, `TypedFail`, `ReasonOf`, `HandlerContext`. Available factory list expanded to include `internalError`, `serializationError`, `databaseError`.
24
- - **`README.md` "Structured errors" feature bullet rewritten** to lead with typed contracts (the headline 0.8.0 feature) and demote factories + auto-classification to the fallback path. Mirrors the framing in `AGENTS.md` / `CLAUDE.md`.
25
- - **Skills sync** `add-tool`, `add-resource`, `add-service`, `add-test`, `add-app-tool`, `api-context`, `api-errors`, `api-linter`, `api-testing`, `api-utils`, `design-mcp-server`, `field-test` updated to cover the typed-contract API surface, the new utilities, the new lint rules, and the expanded factory set. `maintenance` v1.7 → v1.8 (Step 4 adoption-check row broadened from "new error factories" to "new `/errors` surface — factories, typed contracts, `httpErrorFromResponse`"). `security-pass` v1.1 → v1.2 (Axis 7 leakage check now greps `ctx.fail(` and `httpErrorFromResponse(` alongside `new McpError`, since all three flow through the same `data` payload). `report-issue-framework` v1.3 → v1.4 (`errors` scope row expanded to mention typed contracts, conformance lint, and `httpErrorFromResponse`).
26
- - **`ToolDefinition` / `ResourceDefinition` gain a third type parameter** `TErrors extends readonly ErrorContract[] | undefined = undefined` — defaults to `undefined`, so existing `ToolDefinition<X, Y>` and `ResourceDefinition<X, Y, Z>` annotations continue to work and the handler signature collapses to plain `Context`. `AnyToolDefinition` and `AnyResourceDefinition` are widened to `readonly ErrorContract[] | undefined` for the new parameter so type-erased arrays passed to `createApp()` still accept mixed contracts.
27
- - **`docs/tree.md`** regenerated to reflect new files (`error-contract-rules.ts`, `handler-body-rules.ts`, `source-text.ts`, `partialResult.ts`, `httpError.ts`, `check-framework-antipatterns.ts`) and corresponding test files.
25
+ - **`ToolDefinition` / `ResourceDefinition`** gain a third type parameter `TErrors extends readonly ErrorContract[] | undefined = undefined`. Existing `ToolDefinition<X, Y>` annotations keep working; handler signature collapses to plain `Context` when no contract is declared. `AnyToolDefinition` / `AnyResourceDefinition` widened accordingly.
26
+ - **`AGENTS.md` / `CLAUDE.md` / `templates/AGENTS.md` / `templates/CLAUDE.md`** — Error Handling sections rewritten to lead with the contract path, factories demoted to fallback. Exports table and factory list updated.
27
+ - **`README.md`**"Structured errors" feature bullet rewritten as "Typed error contracts".
28
+ - **Skills sync** `add-tool`, `add-resource`, `add-service`, `add-test`, `add-app-tool`, `api-context`, `api-errors`, `api-linter`, `api-testing`, `api-utils`, `design-mcp-server`, `field-test` updated for the new surface. `maintenance` v1.7 v1.8, `security-pass` v1.1 v1.2, `report-issue-framework` v1.3 v1.4.
29
+ - **`docs/tree.md`** regenerated.
28
30
 
29
31
  ## Fixed
30
32
 
31
- - **Stale `@see docs/service-resilience.md` reference removed** from `src/utils/network/retry.ts` — the linked doc no longer exists in the repo, the JSDoc above already explains the retry boundary semantics.
33
+ - Stale `@see docs/service-resilience.md` reference removed from `src/utils/network/retry.ts`.
@@ -0,0 +1,17 @@
1
+ ---
2
+ summary: "Skills sync — service-thrown contract reasons (pass `data: { reason }` from factories), field-test helper hardening, maintenance skill-version paradox check, factory-choice semantic audit"
3
+ breaking: false
4
+ ---
5
+
6
+ # 0.8.1 — 2026-04-28
7
+
8
+ Skill-only follow-up to 0.8.0. Documents the missing pattern for carrying contract `reason` from service-layer throws (services don't have `ctx.fail`), hardens the field-test helper, and teaches `maintenance` to self-detect a skill-version paradox.
9
+
10
+ ## Changed
11
+
12
+ - **`api-errors` v1.0 → v1.1** — adds "Carrying contract `reason` from services" section. Services pass `data: { reason: 'X' }` to error factories; the auto-classifier preserves `data` on the wire so clients see the same `error.data.reason` they'd see from `ctx.fail`. Trade-off noted: lint-time conformance enforcement is lost; compensate with one wire-shape test per reason.
13
+ - **`add-service` v1.3 → v1.4** — same pattern surfaced as a "Carry contract `reason` via `data: { reason }`" bullet under the "Services don't declare contracts" rule.
14
+ - **`add-tool` v1.8 → v1.9** — cross-references the service-thrown reason path in the `ctx.fail` section, so handler authors see it where they're already reading.
15
+ - **`field-test` v2.0 → v2.1** — `/tmp/mcp-field-test.sh` helper hardened: build/start failures auto-tail their logs; `mcp_init` captures HTTP status + body on failure; `mcp_call` surfaces 4xx/5xx with body + falls through to raw body when SSE framing is absent (so plain-JSON errors aren't swallowed); new `mcp_log [N]` tails server log for surprising responses; `mcp_stop` waits for SIGTERM, escalates to SIGKILL, reports residual processes.
16
+ - **`maintenance` v1.8 → v1.9** — adds skill-version paradox check: if `node_modules/@cyanheads/mcp-ts-core/skills/maintenance/SKILL.md` version exceeds the running one, run Phase A first and re-invoke. Also adds factory-choice semantic audit row: `invalidParams` is for malformed JSON-RPC params (rare post-Zod); semantic post-shape validation should use `validationError`. Wrong codes degrade `mcp_error_classified_code` observability and break client retry logic.
17
+ - **`templates/changelog/template.md`** — example issue/PR numbers updated from placeholder `#12`/`#17` to concrete `#38`/`#42` against `cyanheads/mcp-ts-core` so the linking guidance reads correctly when copied.
@@ -0,0 +1,18 @@
1
+ ---
2
+ summary: "Landing page tools section grouped by mutability with chip + search filter; status strip gains repo link; add-app-tool host-theming guidance; maintenance v2.0 hard-rule on framework adoption"
3
+ breaking: false
4
+ ---
5
+
6
+ # 0.8.2 — 2026-04-28
7
+
8
+ Landing-page UX pass plus skill tightening. No runtime API changes.
9
+
10
+ ## Changed
11
+
12
+ - **Tools section** (`src/mcp-server/transports/http/landing-page/sections/tools.ts`) — replaces prefix-based grouping with mutability buckets (`read` / `write` / `destructive`) using `tool.annotations.{readOnlyHint, destructiveHint}`. Annotation-less tools bucket as `write` (matches the existing `pill-destructive === true` rule). Cards now carry `data-tool-card`, `data-mutability`, `data-name`, `data-search` for the filter script. Auth display reduced to the trailing access-level chip (`tool:foo:read` → `read`); full scope list still in the `title` tooltip.
13
+ - **Tool filter bar** — new chip row (`all` + populated buckets) with `aria-pressed` toggling, plus a `<input type="search">` indexed against `data-search` (lowercased `name + description`). Empty state renders `No tools match the current filter.` Filter logic lives in the inlined script — no framework, no transitions, ships under 2 KB.
14
+ - **Status strip** (`sections/status-strip.ts`) — adds a dim `github` repo link when `manifest.landing.repoRoot` is set. Same visual weight as the count + protocol items; the prominent "Source" footer entry stays for scrollers.
15
+ - **Inlined client script** (`assets/copy-script.ts`) — wraps copy-to-clipboard + tool filtering in a single IIFE. Filter handler bails early when `[data-tools-section]` or `[data-tool-card]` is absent, so the empty server still ships clean.
16
+ - **Styles** (`assets/styles.ts`) — adds CSS for the filter bar, mutability-tinted chips, group-count pills, and the `tools-empty` placeholder. Mobile breakpoint preserved.
17
+ - **`add-app-tool` skill** — sharper "ship self-contained HTML" guidance (CSP / supply-chain / offline footguns enumerated). New "Adopt the host's visual identity" section documenting `applyDocumentTheme` / `applyHostStyleVariables` / `applyHostFonts` and the pre-connect `prefers-color-scheme` baseline pattern that prevents first-paint flashes.
18
+ - **`maintenance` skill v1.9 → v2.0** — framework-adoption default hardened from "default adopt" to "auto-adopt every applicable site, in this pass." Adds an explicit valid/invalid deferrals table and forbids scope/effort/marginal-benefit deferrals in the "Open decisions" section. Cost/benefit reasoning now applies to third-party adoptions only.
@@ -27,6 +27,19 @@ breaking: false
27
27
 
28
28
  Optional narrative intro — 1-3 sentences framing the release theme. Delete if not needed.
29
29
 
30
+ TONE: terse and fact-dense. 1-2 sentence(s) per bullet where possible —
31
+ name the symbol, state what changed, stop. Drop "explains how it works" prose;
32
+ that belongs in JSDoc, AGENTS.md, or the relevant skill. Drop ceremonial
33
+ framings ("This release introduces…", "fully backwards compatible:" with a
34
+ paragraph of justification). Prefer code/symbol names over English
35
+ re-explanations. If a bullet runs more than ~2 lines, split it or cut it.
36
+
37
+ WHAT TO INCLUDE: every distinct fact a reader needs to adopt or audit the
38
+ release — new exports, signatures, lint rule IDs, env vars, breaking
39
+ changes, version bumps on shipped skills. WHAT TO CUT: mechanism walkthroughs,
40
+ duplicate prose between Added and Changed, file-by-file test enumerations,
41
+ internal implementation notes. Trust the reader to read the code or the docs.
42
+
30
43
  Linking issues/PRs: use full URLs so the link works everywhere (GitHub web UI,
31
44
  npm/node_modules reads, local editors). GitHub's bare `#NN` auto-link only
32
45
  resolves inside its own UI.
@@ -1,4 +1,4 @@
1
- {"level":50,"time":1777411375566,"env":"testing","version":"0.0.0-test","pid":21464,"requestId":"AWQQL-93X1J","timestamp":"2026-04-28T21:22:55.565Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"d9659eae41503420a9fbe1a137386f211e1880fefe827828f600907f56f92f0e","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"d9659eae41503420a9fbe1a137386f211e1880fefe827828f600907f56f92f0e","toolName":"scoped_echo","requestId":"AWQQL-93X1J","timestamp":"2026-04-28T21:22:55.565Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:72:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:107:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
2
- {"level":50,"time":1777411376971,"env":"testing","version":"0.8.0","pid":21504,"requestId":"T5AF5-CUWA1","timestamp":"2026-04-28T21:22:56.971Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"T5AF5-CUWA1","timestamp":"2026-04-28T21:22:56.971Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
3
- {"level":50,"time":1777411376988,"env":"testing","version":"0.8.0","pid":21504,"requestId":"AYH25-LS56D","timestamp":"2026-04-28T21:22:56.988Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"AYH25-LS56D","timestamp":"2026-04-28T21:22:56.988Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
4
- {"level":50,"time":1777411376991,"env":"testing","version":"0.8.0","pid":21504,"requestId":"0BLY1-FMRXN","timestamp":"2026-04-28T21:22:56.991Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"0BLY1-FMRXN","timestamp":"2026-04-28T21:22:56.991Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
1
+ {"level":50,"time":1777420386266,"env":"testing","version":"0.0.0-test","pid":93036,"requestId":"9SR3Y-96Q5Q","timestamp":"2026-04-28T23:53:06.265Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"b6d7f21343ef3d0098ee5154572d21e4f3453c49f591d9a06424ae7d25e95865","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"b6d7f21343ef3d0098ee5154572d21e4f3453c49f591d9a06424ae7d25e95865","toolName":"scoped_echo","requestId":"9SR3Y-96Q5Q","timestamp":"2026-04-28T23:53:06.265Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:72:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:107:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
2
+ {"level":50,"time":1777420387550,"env":"testing","version":"0.8.2","pid":93075,"requestId":"EOXXJ-UGLBI","timestamp":"2026-04-28T23:53:07.549Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"EOXXJ-UGLBI","timestamp":"2026-04-28T23:53:07.549Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
3
+ {"level":50,"time":1777420387567,"env":"testing","version":"0.8.2","pid":93075,"requestId":"H0RA2-3FZ2J","timestamp":"2026-04-28T23:53:07.567Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"H0RA2-3FZ2J","timestamp":"2026-04-28T23:53:07.567Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
4
+ {"level":50,"time":1777420387570,"env":"testing","version":"0.8.2","pid":93075,"requestId":"GUJJZ-AY2OQ","timestamp":"2026-04-28T23:53:07.570Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"GUJJZ-AY2OQ","timestamp":"2026-04-28T23:53:07.570Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
@@ -1,4 +1,4 @@
1
- {"level":50,"time":1777411375566,"env":"testing","version":"0.0.0-test","pid":21464,"requestId":"AWQQL-93X1J","timestamp":"2026-04-28T21:22:55.565Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"d9659eae41503420a9fbe1a137386f211e1880fefe827828f600907f56f92f0e","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"d9659eae41503420a9fbe1a137386f211e1880fefe827828f600907f56f92f0e","toolName":"scoped_echo","requestId":"AWQQL-93X1J","timestamp":"2026-04-28T21:22:55.565Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:72:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:107:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
2
- {"level":50,"time":1777411376971,"env":"testing","version":"0.8.0","pid":21504,"requestId":"T5AF5-CUWA1","timestamp":"2026-04-28T21:22:56.971Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"T5AF5-CUWA1","timestamp":"2026-04-28T21:22:56.971Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
3
- {"level":50,"time":1777411376988,"env":"testing","version":"0.8.0","pid":21504,"requestId":"AYH25-LS56D","timestamp":"2026-04-28T21:22:56.988Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"AYH25-LS56D","timestamp":"2026-04-28T21:22:56.988Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
4
- {"level":50,"time":1777411376991,"env":"testing","version":"0.8.0","pid":21504,"requestId":"0BLY1-FMRXN","timestamp":"2026-04-28T21:22:56.991Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"0BLY1-FMRXN","timestamp":"2026-04-28T21:22:56.991Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
1
+ {"level":50,"time":1777420386266,"env":"testing","version":"0.0.0-test","pid":93036,"requestId":"9SR3Y-96Q5Q","timestamp":"2026-04-28T23:53:06.265Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"b6d7f21343ef3d0098ee5154572d21e4f3453c49f591d9a06424ae7d25e95865","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"b6d7f21343ef3d0098ee5154572d21e4f3453c49f591d9a06424ae7d25e95865","toolName":"scoped_echo","requestId":"9SR3Y-96Q5Q","timestamp":"2026-04-28T23:53:06.265Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:72:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:107:42)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
2
+ {"level":50,"time":1777420387550,"env":"testing","version":"0.8.2","pid":93075,"requestId":"EOXXJ-UGLBI","timestamp":"2026-04-28T23:53:07.549Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"EOXXJ-UGLBI","timestamp":"2026-04-28T23:53:07.549Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
3
+ {"level":50,"time":1777420387567,"env":"testing","version":"0.8.2","pid":93075,"requestId":"H0RA2-3FZ2J","timestamp":"2026-04-28T23:53:07.567Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"H0RA2-3FZ2J","timestamp":"2026-04-28T23:53:07.567Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
4
+ {"level":50,"time":1777420387570,"env":"testing","version":"0.8.2","pid":93075,"requestId":"GUJJZ-AY2OQ","timestamp":"2026-04-28T23:53:07.570Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"GUJJZ-AY2OQ","timestamp":"2026-04-28T23:53:07.570Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
@@ -1,8 +1,17 @@
1
1
  /**
2
- * @fileoverview Inlined copy-to-clipboard script. Single delegated click
3
- * handler triggered by any element carrying `[data-copy]`; the copy target is
4
- * either a CSS selector (`[data-copy-target]`) or the literal `data-copy`
5
- * value. Renders under 1 KB so it ships inline with the page.
2
+ * @fileoverview Inlined client-side scripts for the landing page. Two
3
+ * delegated handlers, both keyed by data attributes:
4
+ *
5
+ * - Copy-to-clipboard: any element carrying `[data-copy]` triggers a copy
6
+ * of the target's `textContent` (CSS selector via `[data-copy-target]`)
7
+ * or the literal `data-copy` value.
8
+ * - Tool filtering: chip clicks toggle a mutability filter, the search
9
+ * input filters by `data-name` + indexed `data-search` substring, and
10
+ * cards/groups update via `hidden`. No framework, no transitions,
11
+ * fully accessible (chips use `aria-pressed`).
12
+ *
13
+ * The whole bundle stays well under 2 KB so it ships inline alongside the
14
+ * page HTML.
6
15
  *
7
16
  * @module src/mcp-server/transports/http/landing-page/assets/copy-script
8
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"copy-script.d.ts","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/copy-script.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,4BAA4B,CAAC;AAEtE,wBAAgB,gBAAgB,IAAI,QAAQ,CAyB3C"}
1
+ {"version":3,"file":"copy-script.d.ts","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/copy-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,4BAA4B,CAAC;AAEtE,wBAAgB,gBAAgB,IAAI,QAAQ,CA0F3C"}
@@ -1,36 +1,110 @@
1
1
  /**
2
- * @fileoverview Inlined copy-to-clipboard script. Single delegated click
3
- * handler triggered by any element carrying `[data-copy]`; the copy target is
4
- * either a CSS selector (`[data-copy-target]`) or the literal `data-copy`
5
- * value. Renders under 1 KB so it ships inline with the page.
2
+ * @fileoverview Inlined client-side scripts for the landing page. Two
3
+ * delegated handlers, both keyed by data attributes:
4
+ *
5
+ * - Copy-to-clipboard: any element carrying `[data-copy]` triggers a copy
6
+ * of the target's `textContent` (CSS selector via `[data-copy-target]`)
7
+ * or the literal `data-copy` value.
8
+ * - Tool filtering: chip clicks toggle a mutability filter, the search
9
+ * input filters by `data-name` + indexed `data-search` substring, and
10
+ * cards/groups update via `hidden`. No framework, no transitions,
11
+ * fully accessible (chips use `aria-pressed`).
12
+ *
13
+ * The whole bundle stays well under 2 KB so it ships inline alongside the
14
+ * page HTML.
6
15
  *
7
16
  * @module src/mcp-server/transports/http/landing-page/assets/copy-script
8
17
  */
9
18
  import { unsafeRaw } from '../../../../../utils/formatting/html.js';
10
19
  export function renderCopyScript() {
11
20
  const js = `
12
- document.addEventListener('click', function(e) {
13
- var btn = e.target.closest('[data-copy]');
14
- if (!btn) return;
15
- var selector = btn.getAttribute('data-copy-target');
16
- var text = '';
17
- if (selector) {
18
- var node = document.querySelector(selector);
19
- if (node) text = node.textContent || '';
20
- } else {
21
- text = btn.getAttribute('data-copy') || '';
22
- }
23
- if (!text || !navigator.clipboard) return;
24
- navigator.clipboard.writeText(text).then(function() {
25
- var prev = btn.textContent;
26
- btn.setAttribute('data-copied', 'true');
27
- btn.textContent = 'Copied';
28
- setTimeout(function() {
29
- btn.removeAttribute('data-copied');
30
- btn.textContent = prev;
31
- }, 1500);
21
+ (function() {
22
+ // ---------- Copy to clipboard ----------
23
+ document.addEventListener('click', function(e) {
24
+ var btn = e.target.closest('[data-copy]');
25
+ if (!btn) return;
26
+ var selector = btn.getAttribute('data-copy-target');
27
+ var text = '';
28
+ if (selector) {
29
+ var node = document.querySelector(selector);
30
+ if (node) text = node.textContent || '';
31
+ } else {
32
+ text = btn.getAttribute('data-copy') || '';
33
+ }
34
+ if (!text || !navigator.clipboard) return;
35
+ navigator.clipboard.writeText(text).then(function() {
36
+ var prev = btn.textContent;
37
+ btn.setAttribute('data-copied', 'true');
38
+ btn.textContent = 'Copied';
39
+ setTimeout(function() {
40
+ btn.removeAttribute('data-copied');
41
+ btn.textContent = prev;
42
+ }, 1500);
43
+ });
32
44
  });
33
- });`;
45
+
46
+ // ---------- Tool filter + search ----------
47
+ var section = document.querySelector('[data-tools-section]');
48
+ if (!section) return;
49
+ var cards = Array.prototype.slice.call(section.querySelectorAll('[data-tool-card]'));
50
+ if (cards.length === 0) return;
51
+ var chips = Array.prototype.slice.call(section.querySelectorAll('[data-filter-mutability]'));
52
+ var searchInput = section.querySelector('[data-tool-search]');
53
+ var groups = Array.prototype.slice.call(section.querySelectorAll('[data-group]'));
54
+ var grids = Array.prototype.slice.call(section.querySelectorAll('[data-grid]'));
55
+ var emptyState = section.querySelector('.tools-empty');
56
+
57
+ var activeMutability = 'all';
58
+ var query = '';
59
+
60
+ function apply() {
61
+ var visibleCount = 0;
62
+ var perGroup = Object.create(null);
63
+ for (var i = 0; i < cards.length; i++) {
64
+ var card = cards[i];
65
+ var m = card.getAttribute('data-mutability') || '';
66
+ var search = card.getAttribute('data-search') || '';
67
+ var matchesMutability = activeMutability === 'all' || m === activeMutability;
68
+ var matchesSearch = query === '' || search.indexOf(query) !== -1;
69
+ var visible = matchesMutability && matchesSearch;
70
+ card.hidden = !visible;
71
+ if (visible) {
72
+ visibleCount++;
73
+ perGroup[m] = (perGroup[m] || 0) + 1;
74
+ }
75
+ }
76
+ // Hide group headings + grids whose buckets are now empty.
77
+ for (var g = 0; g < groups.length; g++) {
78
+ var key = groups[g].getAttribute('data-group');
79
+ groups[g].hidden = !perGroup[key];
80
+ }
81
+ for (var k = 0; k < grids.length; k++) {
82
+ var gk = grids[k].getAttribute('data-grid');
83
+ grids[k].hidden = !perGroup[gk];
84
+ }
85
+ if (emptyState) emptyState.hidden = visibleCount > 0;
86
+ }
87
+
88
+ for (var c = 0; c < chips.length; c++) {
89
+ chips[c].addEventListener('click', function(ev) {
90
+ var target = ev.currentTarget;
91
+ var value = target.getAttribute('data-filter-mutability') || 'all';
92
+ activeMutability = value;
93
+ for (var j = 0; j < chips.length; j++) {
94
+ var pressed = chips[j] === target;
95
+ chips[j].setAttribute('aria-pressed', pressed ? 'true' : 'false');
96
+ }
97
+ apply();
98
+ });
99
+ }
100
+
101
+ if (searchInput) {
102
+ searchInput.addEventListener('input', function(ev) {
103
+ query = (ev.currentTarget.value || '').trim().toLowerCase();
104
+ apply();
105
+ });
106
+ }
107
+ })();`;
34
108
  return unsafeRaw(`<script>${js}</script>`);
35
109
  }
36
110
  //# sourceMappingURL=copy-script.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"copy-script.js","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/copy-script.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;IAsBT,CAAC;IACH,OAAO,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"copy-script.js","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/copy-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuFP,CAAC;IACL,OAAO,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,4BAA4B,CAAC;AAKtE;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAi4BrD"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/mcp-server/transports/http/landing-page/assets/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,QAAQ,EAAa,MAAM,4BAA4B,CAAC;AAKtE;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAurCrD"}