@cyanheads/mcp-ts-core 0.10.14 → 0.10.15

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.
package/AGENTS.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Package:** `@cyanheads/mcp-ts-core`
4
- **Version:** 0.10.14
4
+ **Version:** 0.10.15
5
5
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
6
6
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
7
7
  **Zod:** ^4.4.3
package/CLAUDE.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Developer Protocol
2
2
 
3
3
  **Package:** `@cyanheads/mcp-ts-core`
4
- **Version:** 0.10.14
4
+ **Version:** 0.10.15
5
5
  **Engines:** Bun ≥1.3.0, Node ≥24.0.0
6
6
  **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
7
7
  **Zod:** ^4.4.3
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.10.14-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![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)
8
+ [![Version](https://img.shields.io/badge/Version-0.10.15-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![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)
9
9
 
10
10
  [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![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.0%2B-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  `@cyanheads/mcp-ts-core` is the infrastructure layer for TypeScript MCP servers. Install it as a dependency — don't fork it. Your agent collaborates with you to design and build the tools, resources, and prompts for your server.
21
21
 
22
- The framework handles the plumbing: transports, auth, config, logging, telemetry, & more. Define your domain logic with the builders and let the framework take care of the rest.
22
+ The framework handles the plumbing: transports, auth, config, logging, telemetry, & more.
23
23
 
24
24
  ```ts
25
25
  import { createApp, tool, z } from '@cyanheads/mcp-ts-core';
@@ -63,7 +63,11 @@ const search = tool('search', {
63
63
  await createApp({ tools: [search] });
64
64
  ```
65
65
 
66
- That's a complete MCP server, showing both flagship contracts. **`enrichment`** carries the context an agent reasons with — the parsed query, the true total, an empty-result notice — which the framework merges into `structuredContent` *and* mirrors into `content[]`, so `structuredContent`-only clients (Claude Code) and `content[]`-only clients (Claude Desktop) both see it, no `format()` needed. The typed **`errors[]`** contract handles genuine failures (an empty result is a `notice`, not a throw). The linter cross-checks both against the handler body, and both publish in `tools/list` so clients preview a tool's success *and* failure shapes. Every tool call is automatically logged with duration, payload sizes, and request correlation — no instrumentation code needed; `createApp()` handles config parsing, logger init, transport startup, signal handlers, and graceful shutdown.
66
+ That's a complete MCP server, and it shows both of the framework's core contracts.
67
+
68
+ **`enrichment`** carries the context an agent reasons with (the parsed query, the true total, an empty-result notice); the framework merges it into `structuredContent` *and* mirrors it into `content[]`, so `structuredContent`-only clients (Claude Code) and `content[]`-only clients (Claude Desktop) both see it, no `format()` needed. The typed **`errors[]`** contract handles genuine failures (an empty result is a `notice`, not a throw), and the linter cross-checks both against the handler body. Both publish in `tools/list`, so clients preview a tool's success *and* failure shapes.
69
+
70
+ The rest is automatic: every tool call is logged with duration, payload sizes, and request correlation, and `createApp()` handles config parsing, logger init, transport startup, signal handlers, and graceful shutdown.
67
71
 
68
72
  ## Quick start
69
73
 
@@ -73,13 +77,13 @@ cd my-mcp-server
73
77
  bun install
74
78
  ```
75
79
 
76
- You get a scaffolded project with `CLAUDE.md`/`AGENTS.md`, Agent Skills, plugin metadata (Codex + Claude Code), and a `src/` tree ready for your tools. Infrastructure transports, auth, storage, telemetry, lifecycle, linting lives in `node_modules`. What's left is domain: which APIs to wrap, which workflows to expose.
80
+ You get a scaffolded project with `CLAUDE.md`/`AGENTS.md`, Agent Skills, plugin metadata (Codex + Claude Code), and a `src/` tree ready for your tools. Infrastructure (transports, auth, storage, telemetry, lifecycle, linting) lives in `node_modules`. What's left is domain: which APIs to wrap, which workflows to expose.
77
81
 
78
- Start your coding agent (i.e. Claude Code, Codex) and describe what you want. The agent knows what to do from there. The included Agent Skills cover the full cycle: `setup`, `design-mcp-server`, scaffolding, testing, `security-pass`, `release-and-publish`, `maintenance`, & more.
82
+ Start your coding agent (e.g. Claude Code, Codex) and describe what you want. The agent knows what to do from there. The included Agent Skills cover the full cycle: `setup`, `design-mcp-server`, scaffolding, testing, `security-pass`, `release-and-publish`, `maintenance`, & more.
79
83
 
80
84
  ### What you get
81
85
 
82
- The headline tool returns structured output clients that read `structuredContent` (Claude Code) get it directly. To also render markdown for clients that read `content[]` (Claude Desktop), add a `format()`. The `format-parity` linter checks it renders every `output` field, so the two surfaces never drift:
86
+ The headline tool returns structured output. Clients that read `structuredContent` (Claude Code) get it directly. To also render markdown for clients that read `content[]` (Claude Desktop), add a `format()`. The `format-parity` linter checks it renders every `output` field, so the two surfaces never drift:
83
87
 
84
88
  ```ts
85
89
  import { tool, z } from '@cyanheads/mcp-ts-core';
package/biome.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.5.2/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.5.4/schema.json",
3
3
  "vcs": {
4
4
  "enabled": true,
5
5
  "clientKind": "git",
@@ -6,8 +6,8 @@ agent-notes: |
6
6
  No `src/` changes — upgrading is runtime-inert for existing servers. Adoptable
7
7
  from `templates/`: the supply-chain guard (copy `bunfig.toml`'s
8
8
  `minimumReleaseAge` + `[install.security]` block, add the
9
- `@socketsecurity/bun-security-scanner` devDependency and a matching
10
- `trustedDependencies` entry), a scaffolded `LICENSE` and `.gitattributes`, and
9
+ `@socketsecurity/bun-security-scanner` devDependency), a scaffolded
10
+ `LICENSE` and `.gitattributes`, and
11
11
  the `oven/bun:1.3.14` Dockerfile pin with BuildKit install-cache mounts.
12
12
  Worker-deployed servers migrating `wrangler.toml` → `wrangler.jsonc` need the
13
13
  `@duckdb/node-api` → local stub alias (api-workers skill 1.6). Skills bumped:
@@ -0,0 +1,57 @@
1
+ ---
2
+ summary: "withRetry honors Retry-After (delta-seconds and HTTP-date, capped at maxDelayMs); fetchWithTimeout adds an expectedStatuses log opt-out and canonical status/body error fields (legacy aliases kept); fixes duplicate error logging and a stale 0.10.13 changelog note; biome 2.5.4 migration, dependency refresh, skill updates."
3
+ breaking: false
4
+ security: false
5
+ agent-notes: |
6
+ Read upstream status/body from error.data via the canonical names
7
+ (legacy statusCode/responseBody aliases still emitted). Pass
8
+ expectedStatuses for endpoints where a non-2xx is an expected outcome
9
+ (e.g. 404 → empty result) to stop error-level log noise. Retry-After
10
+ handling is automatic — no adoption needed. Servers bumping their own
11
+ biome pin to 2.5.4 should run `bunx biome migrate`.
12
+ ---
13
+
14
+ # 0.10.15 — 2026-07-19
15
+
16
+ ## Added
17
+
18
+ - **`expectedStatuses`** option on `fetchWithTimeout` — a non-2xx status listed here logs at `debug` instead of `error`; the thrown, status-mapped `McpError` is unchanged. [#256](https://github.com/cyanheads/mcp-ts-core/issues/256)
19
+
20
+ ## Changed
21
+
22
+ - **Skills** — `git-wrapup` 1.8 (tag annotation is now a flat-bullet headline digest — no Keep-a-Changelog section headers in the tag, no gates line, deps capped at one line), `orchestrations` 1.7 (verification-quality bullet matches the new tag format), `field-test` 2.7 (the `content[]` parity check must dump the whole array — the enrichment trailer renders as a separate trailing block, not inside `content[0]`), `tool-defs-analysis` 1.4 (12 → 15 audit categories, adding validator-enforced constraints, annotations truthfulness, and single-line strings, plus a cross-surface pass for naming taxonomy, parameter vocabulary, tool overlap, instructions drift, and length outliers).
23
+
24
+ ## Fixed
25
+
26
+ - **`withRetry` honors `Retry-After`** — a transient error carrying `data.retryAfter` (captured by `fetchWithTimeout`/`httpErrorFromResponse` from the response header) waits the requested delay instead of blind exponential backoff. Parses both delta-seconds and HTTP-date forms (RFC 9110 §10.2.3); the honored delay is not jittered. A requested wait beyond `maxDelayMs` fails fast with the original error rather than burning an attempt that can't succeed in time. [#285](https://github.com/cyanheads/mcp-ts-core/issues/285)
27
+ - **Canonical `status`/`body` error-data fields** — `fetchWithTimeout` and `httpErrorFromResponse` both emit `status`/`body` on `error.data` (Fetch `Response`-aligned names) alongside the pre-existing `statusCode`/`responseBody` aliases (kept, identical values), so a consumer can read either helper's error the same way. [#279](https://github.com/cyanheads/mcp-ts-core/issues/279)
28
+ - **Duplicate error logging** — `fetchWithTimeout`'s catch block re-throws a `FetchHttpError`-tagged `McpError` as-is instead of relabeling and re-logging it as a network failure; a status-mapped error is now logged once, at the severity the caller asked for.
29
+ - **0.10.13 changelog** — the agent-notes no longer tell adopters to add a `trustedDependencies` entry that doesn't exist in that release. [#281](https://github.com/cyanheads/mcp-ts-core/issues/281)
30
+
31
+ ## Dependencies
32
+
33
+ - `@biomejs/biome` `2.5.2` → `2.5.4` (`biome.json` `$schema` migrated via `bunx biome migrate`; the new `noUnsafeOptionalChaining` finding fixed across 7 test files — auto-format and behavior-preserving casts only)
34
+ - `@cloudflare/vitest-pool-workers` `^0.18.0` → `^0.18.4`
35
+ - `@cloudflare/workers-types` `5.20260705.1` → `5.20260706.1`
36
+ - `@hono/mcp` `^0.3.0` → `^0.3.1`
37
+ - `@hono/node-server` `^2.0.8` → `^2.0.10`
38
+ - `@opentelemetry/semantic-conventions` `^1.41.1` → `^1.43.0`
39
+ - `@supabase/supabase-js` `^2.110.0` → `^2.110.6`
40
+ - `@types/node` `26.1.0` → `26.1.1`
41
+ - `@vitest/coverage-istanbul`, `@vitest/ui` `4.1.9` → `4.1.10`
42
+ - `chrono-node` `^2.9.1` → `^2.10.0`
43
+ - `fast-check` `^4.8.0` → `^4.9.0`
44
+ - `fast-xml-parser` `^5.9.3` → `^5.10.1`
45
+ - `hono` `^4.12.27` → `^4.12.30`
46
+ - `ignore` `^7.0.5` → `^7.0.6`
47
+ - `linkedom` `^0.18.12` → `^0.18.13`
48
+ - `node-cron` `^4.5.0` → `^4.6.0`
49
+ - `openai` `^6.45.0` → `^6.46.0`
50
+ - `repomix` `^1.16.0` → `^1.16.1`
51
+ - `sanitize-html` `^2.17.5` → `^2.17.6`
52
+ - `tsc-alias` `^1.9.0` → `^1.9.1`
53
+ - `typedoc` `^0.28.19` → `^0.28.20`
54
+ - `vite` `8.1.3` → `8.1.5`
55
+ - `vitest` `^4.1.9` → `^4.1.10`
56
+ - `typescript` stays `^6.0.3` — the `7.0.2` major is deliberately held, now allowlisted in `devcheck.config.json`'s `outdated` gate
57
+ - `templates/package.json` — `@biomejs/biome` and `@types/node` pins aligned to root
@@ -0,0 +1,8 @@
1
+ {"level":40,"time":1784463726918,"env":"testing","version":"0.10.15","pid":20442,"transport":"http","requestId":"SJ7RF-DW9U8","timestamp":"2026-07-19T12:22:06.917Z","operation":"TransportManager.start","component":"HttpTransportSetup","msg":"MCP_ALLOWED_ORIGINS is not set — CORS is wildcard for CLI clients; browser Origin headers are restricted to loopback. Set MCP_ALLOWED_ORIGINS for production deployments accepting remote browser origins."}
2
+ {"level":40,"time":1784463728832,"env":"testing","version":"0.10.15","pid":20442,"component":"HttpTransport","requestId":"XNPRU-GET29","timestamp":"2026-07-19T12:22:08.832Z","operation":"HttpRpcRequest","sessionId":"not-a-real-session-1784463728830","msg":"Session validation failed - invalid or hijacked session"}
3
+ {"level":50,"time":1784463736219,"env":"testing","version":"0.0.0-test","pid":20540,"requestId":"9CXBP-MQGEX","timestamp":"2026-07-19T12:22:16.218Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"50919d4072d1a5c63983f13bee49adf78b38bf5146ed1f491e462ef641f1a7db","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"50919d4072d1a5c63983f13bee49adf78b38bf5146ed1f491e462ef641f1a7db","toolName":"scoped_echo","requestId":"9CXBP-MQGEX","timestamp":"2026-07-19T12:22:16.218Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (file:///Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:54)\n at withRequiredScopes (file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:68:15)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287:17\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)"},"stack":"McpError: Insufficient permissions.\n at ErrorHandler.handleError (file:///Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:19)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
4
+ {"level":50,"time":1784463736230,"env":"testing","version":"0.0.0-test","pid":20540,"requestId":"USN67-SZ7PQ","timestamp":"2026-07-19T12:22:16.230Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"6608ad9911177662bee2535c538f58a79042aee685bfd873a9d3f0b1c7fd3aeb","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"6608ad9911177662bee2535c538f58a79042aee685bfd873a9d3f0b1c7fd3aeb","toolName":"scoped_echo","requestId":"USN67-SZ7PQ","timestamp":"2026-07-19T12:22:16.230Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (file:///Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:54)\n at withRequiredScopes (file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:68:15)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287:17\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)"},"stack":"McpError: Insufficient permissions.\n at ErrorHandler.handleError (file:///Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:19)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
5
+ {"level":40,"time":1784463750258,"env":"testing","version":"0.10.15","pid":20719,"transport":"http","requestId":"PDUMP-K2FFI","timestamp":"2026-07-19T12:22:30.258Z","operation":"TransportManager.start","component":"HttpTransportSetup","msg":"MCP_ALLOWED_ORIGINS is not set — CORS is wildcard for CLI clients; browser Origin headers are restricted to loopback. Set MCP_ALLOWED_ORIGINS for production deployments accepting remote browser origins."}
6
+ {"level":40,"time":1784463752032,"env":"testing","version":"0.10.15","pid":20719,"component":"HttpTransport","requestId":"5Q4WB-N823H","timestamp":"2026-07-19T12:22:32.032Z","operation":"HttpRpcRequest","sessionId":"not-a-real-session-1784463752032","msg":"Session validation failed - invalid or hijacked session"}
7
+ {"level":50,"time":1784463752496,"env":"testing","version":"0.0.0-test","pid":20737,"requestId":"7YESW-C0G0N","timestamp":"2026-07-19T12:22:32.495Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"86c21ab46a1a20e61021eafd1611cb1e9489c48d291606d4b725984f423424f7","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"86c21ab46a1a20e61021eafd1611cb1e9489c48d291606d4b725984f423424f7","toolName":"scoped_echo","requestId":"7YESW-C0G0N","timestamp":"2026-07-19T12:22:32.495Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"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:68:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287: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:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26)\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."}
8
+ {"level":50,"time":1784463752503,"env":"testing","version":"0.0.0-test","pid":20737,"requestId":"4AQZB-4MTOZ","timestamp":"2026-07-19T12:22:32.502Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"d974799d1cc98d4b27699d0fe084da6b8b4268c24fd66ce337d109be228ad96c","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"d974799d1cc98d4b27699d0fe084da6b8b4268c24fd66ce337d109be228ad96c","toolName":"scoped_echo","requestId":"4AQZB-4MTOZ","timestamp":"2026-07-19T12:22:32.502Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"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:68:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287: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:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26)\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."}
@@ -0,0 +1,4 @@
1
+ {"level":50,"time":1784463736219,"env":"testing","version":"0.0.0-test","pid":20540,"requestId":"9CXBP-MQGEX","timestamp":"2026-07-19T12:22:16.218Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"50919d4072d1a5c63983f13bee49adf78b38bf5146ed1f491e462ef641f1a7db","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"50919d4072d1a5c63983f13bee49adf78b38bf5146ed1f491e462ef641f1a7db","toolName":"scoped_echo","requestId":"9CXBP-MQGEX","timestamp":"2026-07-19T12:22:16.218Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (file:///Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:54)\n at withRequiredScopes (file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:68:15)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287:17\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)"},"stack":"McpError: Insufficient permissions.\n at ErrorHandler.handleError (file:///Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:19)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
2
+ {"level":50,"time":1784463736230,"env":"testing","version":"0.0.0-test","pid":20540,"requestId":"USN67-SZ7PQ","timestamp":"2026-07-19T12:22:16.230Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"6608ad9911177662bee2535c538f58a79042aee685bfd873a9d3f0b1c7fd3aeb","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"6608ad9911177662bee2535c538f58a79042aee685bfd873a9d3f0b1c7fd3aeb","toolName":"scoped_echo","requestId":"USN67-SZ7PQ","timestamp":"2026-07-19T12:22:16.230Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (file:///Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:54)\n at withRequiredScopes (file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:68:15)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287:17\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)"},"stack":"McpError: Insufficient permissions.\n at ErrorHandler.handleError (file:///Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:170:19)\n at file:///Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26\n at McpServer.executeToolHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:233:42)\n at file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43\n at async wrappedHandler (file:///Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js:125:32)","msg":"Error in tool:scoped_echo: Insufficient permissions."}
3
+ {"level":50,"time":1784463752496,"env":"testing","version":"0.0.0-test","pid":20737,"requestId":"7YESW-C0G0N","timestamp":"2026-07-19T12:22:32.495Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"86c21ab46a1a20e61021eafd1611cb1e9489c48d291606d4b725984f423424f7","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"86c21ab46a1a20e61021eafd1611cb1e9489c48d291606d4b725984f423424f7","toolName":"scoped_echo","requestId":"7YESW-C0G0N","timestamp":"2026-07-19T12:22:32.495Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"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:68:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287: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:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26)\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."}
4
+ {"level":50,"time":1784463752503,"env":"testing","version":"0.0.0-test","pid":20737,"requestId":"4AQZB-4MTOZ","timestamp":"2026-07-19T12:22:32.502Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"d974799d1cc98d4b27699d0fe084da6b8b4268c24fd66ce337d109be228ad96c","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"errorData":{"sessionId":"d974799d1cc98d4b27699d0fe084da6b8b4268c24fd66ce337d109be228ad96c","toolName":"scoped_echo","requestId":"4AQZB-4MTOZ","timestamp":"2026-07-19T12:22:32.502Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["openid","email","profile","offline_access"],"clientId":"authz-client","tenantId":"authz-tenant","token":"[REDACTED]"},"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:68:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:287: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:170:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:336:26)\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."}
File without changes
@@ -9,6 +9,16 @@ export declare function initHttpClientMetrics(): void;
9
9
  * cancellation options.
10
10
  */
11
11
  export interface FetchWithTimeoutOptions extends Omit<RequestInit, 'signal'> {
12
+ /**
13
+ * HTTP status codes the caller treats as an *expected* outcome rather than a
14
+ * failure — e.g. a service that maps `404` to an empty result set. A non-2xx
15
+ * response whose status is listed is logged at `debug` instead of `error`;
16
+ * the status-mapped `McpError` is still thrown, unchanged, so the caller's
17
+ * catch and classification stay byte-identical — only the log severity drops.
18
+ *
19
+ * Default: empty — every non-2xx response is logged at `error`.
20
+ */
21
+ expectedStatuses?: number[];
12
22
  /**
13
23
  * When `true`, rejects requests to private/reserved IP ranges and localhost.
14
24
  *
@@ -83,7 +93,10 @@ export interface FetchWithTimeoutOptions extends Omit<RequestInit, 'signal'> {
83
93
  * @throws {McpError} `InternalError` if the request is cancelled via the external signal.
84
94
  * @throws {McpError} A status-mapped code (`InvalidParams`/`Unauthorized`/`Forbidden`/
85
95
  * `NotFound`/`RateLimited`/`ServiceUnavailable`/...) if the server returns a non-2xx
86
- * status. `error.data` carries `{ statusCode, statusText, responseBody, retryAfter? }`.
96
+ * status. `error.data` carries `{ status, statusText, body, retryAfter? }` — plus the
97
+ * legacy aliases `statusCode` (= `status`) and `responseBody` (= `body`), kept for
98
+ * existing consumers and slated for consolidation in a future major. List a status in
99
+ * `options.expectedStatuses` to log it at `debug` rather than `error` (still thrown).
87
100
  * @throws {McpError} `ServiceUnavailable` if a network-level error occurs.
88
101
  * @example
89
102
  * ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"fetchWithTimeout.d.ts","sourceRoot":"","sources":["../../../src/utils/network/fetchWithTimeout.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAmBzE,4FAA4F;AAC5F,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AA2BD;;;;;;GAMG;AACH,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAiKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,QAAQ,CAAC,CAyKnB"}
1
+ {"version":3,"file":"fetchWithTimeout.d.ts","sourceRoot":"","sources":["../../../src/utils/network/fetchWithTimeout.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAmBzE,4FAA4F;AAC5F,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AA2BD;;;;;;GAMG;AACH,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC1E;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAiKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,QAAQ,CAAC,CAkMnB"}
@@ -231,7 +231,10 @@ async function assertDnsNotPrivate(hostname) {
231
231
  * @throws {McpError} `InternalError` if the request is cancelled via the external signal.
232
232
  * @throws {McpError} A status-mapped code (`InvalidParams`/`Unauthorized`/`Forbidden`/
233
233
  * `NotFound`/`RateLimited`/`ServiceUnavailable`/...) if the server returns a non-2xx
234
- * status. `error.data` carries `{ statusCode, statusText, responseBody, retryAfter? }`.
234
+ * status. `error.data` carries `{ status, statusText, body, retryAfter? }` — plus the
235
+ * legacy aliases `statusCode` (= `status`) and `responseBody` (= `body`), kept for
236
+ * existing consumers and slated for consolidation in a future major. List a status in
237
+ * `options.expectedStatuses` to log it at `debug` rather than `error` (still thrown).
235
238
  * @throws {McpError} `ServiceUnavailable` if a network-level error occurs.
236
239
  * @example
237
240
  * ```ts
@@ -267,7 +270,7 @@ export async function fetchWithTimeout(url, timeoutMs, context, options) {
267
270
  const operationDescription = `fetch ${options?.method || 'GET'} ${redactUrl(urlString)}`;
268
271
  logger.debug(`Attempting ${operationDescription} with ${timeoutMs}ms timeout.`, context);
269
272
  // Strip custom options before passing to native fetch
270
- const { rejectPrivateIPs: rejectPrivate, signal: externalSignal, ...fetchInit } = options ?? {};
273
+ const { rejectPrivateIPs: rejectPrivate, signal: externalSignal, expectedStatuses, ...fetchInit } = options ?? {};
271
274
  // When SSRF protection is active, handle redirects manually to validate each hop
272
275
  if (rejectPrivate) {
273
276
  fetchInit.redirect = 'manual';
@@ -316,20 +319,34 @@ export async function fetchWithTimeout(url, timeoutMs, context, options) {
316
319
  if (!response.ok) {
317
320
  const rawBody = await response.text().catch(() => 'Could not read response body');
318
321
  const responseBody = rawBody.length > ERROR_BODY_LIMIT ? `${rawBody.slice(0, ERROR_BODY_LIMIT)}…` : rawBody;
319
- logger.error(`Fetch failed for ${redactUrl(currentUrl)} with status ${response.status}.`, {
322
+ // Callers that treat a status as expected (e.g. 404 → empty result) get a
323
+ // debug line instead of error; the thrown McpError below is unchanged.
324
+ const logMessage = `Fetch failed for ${redactUrl(currentUrl)} with status ${response.status}.`;
325
+ const logPayload = {
320
326
  ...context,
321
327
  statusCode: response.status,
322
328
  statusText: response.statusText,
323
329
  responseBody,
324
330
  errorSource: 'FetchHttpError',
325
- });
331
+ };
332
+ if (expectedStatuses?.includes(response.status)) {
333
+ logger.debug(logMessage, logPayload);
334
+ }
335
+ else {
336
+ logger.error(logMessage, logPayload);
337
+ }
326
338
  const code = httpStatusToErrorCode(response.status) ?? JsonRpcErrorCode.InternalError;
327
339
  const retryAfter = response.headers.get('retry-after');
328
340
  throw new McpError(code, `Fetch failed for ${redactUrl(currentUrl)}. Status: ${response.status}`, {
329
341
  requestId: context.requestId,
330
342
  operation: context.operation,
331
- statusCode: response.status,
343
+ // Canonical (Fetch `Response`-aligned) field names.
344
+ status: response.status,
332
345
  statusText: response.statusText,
346
+ body: responseBody,
347
+ // Legacy aliases — kept for consumers reading the original shape;
348
+ // slated for consolidation onto `status`/`body` in a future major.
349
+ statusCode: response.status,
333
350
  responseBody,
334
351
  ...(retryAfter !== null && { retryAfter }),
335
352
  errorSource: 'FetchHttpError',
@@ -340,6 +357,12 @@ export async function fetchWithTimeout(url, timeoutMs, context, options) {
340
357
  }
341
358
  }
342
359
  catch (error) {
360
+ // A status-mapped HTTP error from the non-OK branch was already logged there,
361
+ // at the severity the caller asked for (`expectedStatuses` → debug). Re-throw
362
+ // it as-is instead of relabeling it a network error and logging it again.
363
+ if (error instanceof McpError && error.data?.errorSource === 'FetchHttpError') {
364
+ throw error;
365
+ }
343
366
  if (error instanceof Error && (error.name === 'TimeoutError' || error.name === 'AbortError')) {
344
367
  const isTimeout = error.name === 'TimeoutError' || controller.signal.reason === timeoutSentinel;
345
368
  if (isTimeout) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchWithTimeout.js","sourceRoot":"","sources":["../../../src/utils/network/fetchWithTimeout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetchWithTimeout.js","sourceRoot":"","sources":["../../../src/utils/network/fetchWithTimeout.ts"],"names":[],"mappings":"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"}
@@ -62,7 +62,10 @@ export interface HttpErrorFromResponseOptions {
62
62
  codeOverride?: (status: number) => JsonRpcErrorCode | undefined;
63
63
  /**
64
64
  * Additional fields merged into `error.data`. Always includes
65
- * `{ url, status, statusText, body? }` from the response itself.
65
+ * `{ url, status, statusText, body? }` from the response itself, plus the
66
+ * legacy aliases `statusCode` (= `status`) and `responseBody` (= `body`) for
67
+ * consumers reading `fetchWithTimeout`'s shape — slated for consolidation in a
68
+ * future major. Fields passed here override the defaults on key collision.
66
69
  */
67
70
  data?: Record<string, unknown>;
68
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"httpError.d.ts","sourceRoot":"","sources":["../../../src/utils/network/httpError.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAqClF;AAED,uDAAuD;AACvD,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,GAAG,SAAS,CAAC;IAChE;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,QAAQ,CAAC,CA6CnB"}
1
+ {"version":3,"file":"httpError.d.ts","sourceRoot":"","sources":["../../../src/utils/network/httpError.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAqClF;AAED,uDAAuD;AACvD,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,GAAG,SAAS,CAAC;IAChE;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,QAAQ,CAAC,CAmDnB"}
@@ -131,9 +131,15 @@ export async function httpErrorFromResponse(response, options = {}) {
131
131
  const retryAfter = response.headers.get('retry-after') ?? undefined;
132
132
  const data = {
133
133
  url: response.url || undefined,
134
+ // Canonical (Fetch `Response`-aligned) field names.
134
135
  status: response.status,
135
136
  statusText: response.statusText || undefined,
136
137
  ...(body !== undefined && { body }),
138
+ // Legacy aliases — mirror fetchWithTimeout's original shape so a consumer can
139
+ // classify either helper's error without knowing which raised it; slated for
140
+ // consolidation onto `status`/`body` in a future major.
141
+ statusCode: response.status,
142
+ ...(body !== undefined && { responseBody: body }),
137
143
  ...(retryAfter !== undefined && { retryAfter }),
138
144
  ...extraData,
139
145
  };
@@ -1 +1 @@
1
- {"version":3,"file":"httpError.js","sourceRoot":"","sources":["../../../src/utils/network/httpError.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"httpError.js","sourceRoot":"","sources":["../../../src/utils/network/httpError.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO;IAEzB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,aAAa,CAAC;QACxC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,YAAY,CAAC;QACvC,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,SAAS,CAAC;QACpC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QACnC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QACnC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,eAAe,CAAC;QAC1C,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,QAAQ,CAAC;QACnC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,WAAW,CAAC;QACtC,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,aAAa,CAAC;QACxC,KAAK,GAAG,CAAC;QACT,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,kBAAkB,CAAC;QAC7C,KAAK,GAAG;YACN,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC;YACE,OAAO,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC;IACjG,CAAC;AACH,CAAC;AAyCD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAkB,EAClB,UAAwC,EAAE;IAE1C,MAAM,EACJ,WAAW,GAAG,IAAI,EAClB,SAAS,GAAG,kBAAkB,EAC9B,OAAO,EACP,IAAI,EAAE,SAAS,EACf,KAAK,EACL,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,MAAM,IAAI,GACR,YAAY,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC/B,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC;QACtC,gBAAgB,CAAC,aAAa,CAAC;IAEjC,MAAM,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC;IAChE,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExE,IAAI,IAAwB,CAAC;IAC7B,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC;IAEpE,MAAM,IAAI,GAA4B;QACpC,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI,SAAS;QAC9B,oDAAoD;QACpD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,SAAS;QAC5C,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;QACnC,8EAA8E;QAC9E,6EAA6E;QAC7E,wDAAwD;QACxD,UAAU,EAAE,QAAQ,CAAC,MAAM;QAC3B,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACjD,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;QAC/C,GAAG,SAAS;KACb,CAAC;IAEF,OAAO,IAAI,QAAQ,CACjB,IAAI,EACJ,GAAG,OAAO,kBAAkB,QAAQ,CAAC,MAAM,GAAG,UAAU,GAAG,EAC3D,IAAI,EACJ,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAC5C,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC"}
@@ -38,6 +38,10 @@ export interface RetryOptions {
38
38
  /**
39
39
  * Maximum delay cap in milliseconds. Prevents unbounded growth on high
40
40
  * retry counts. Default: `30000` (30s).
41
+ *
42
+ * Also the ceiling for an honored upstream `Retry-After`: when the error
43
+ * carries `data.retryAfter` and the requested wait exceeds this cap, the
44
+ * error is treated as non-transient and fails fast (see {@link withRetry}).
41
45
  */
42
46
  maxDelayMs?: number;
43
47
  /**
@@ -70,6 +74,14 @@ export interface RetryOptions {
70
74
  * via `ctx.fail`) for failures that can never succeed on retry (oversized query,
71
75
  * malformed request surfaced as HTTP 200 + error body, etc.).
72
76
  *
77
+ * **Retry-After honoring.** When a transient error carries `data.retryAfter`
78
+ * (captured by `fetchWithTimeout` / `httpErrorFromResponse` from the upstream
79
+ * header), the retry delay honors it — parsing both delta-seconds and HTTP-date
80
+ * forms (RFC 9110 §10.2.3) — instead of the exponential value. If the requested
81
+ * wait exceeds `maxDelayMs`, the error is treated as non-transient and fails
82
+ * fast: a window that won't clear within the retry budget is surfaced to the
83
+ * caller immediately rather than burning attempts that cannot succeed.
84
+ *
73
85
  * When retries exhaust, the final error is enriched with attempt count in both
74
86
  * the message and structured data, so callers know retries were already attempted.
75
87
  *
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/utils/network/retry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAYzE,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAE1C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAyED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,CAiD/F"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/utils/network/retry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAYzE,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAE1C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA8GD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,CAgE/F"}
@@ -31,6 +31,43 @@ function computeDelay(attempt, baseDelayMs, maxDelayMs, jitter) {
31
31
  const jitterRange = exponential * jitter;
32
32
  return exponential - jitterRange + Math.random() * jitterRange * 2;
33
33
  }
34
+ /**
35
+ * Parses an upstream `Retry-After` hint into milliseconds. The two HTTP helpers
36
+ * (`fetchWithTimeout`, `httpErrorFromResponse`) capture the raw header value into
37
+ * `error.data.retryAfter`; this reads it back so the retry delay can honor the
38
+ * wait the upstream explicitly asked for instead of blind exponential backoff.
39
+ *
40
+ * Handles both RFC 9110 §10.2.3 forms:
41
+ * - **delta-seconds** — a bare non-negative integer (`"30"` → `30_000`).
42
+ * - **HTTP-date** — an absolute instant, converted to a wait from now and
43
+ * clamped at `0` (a past date means "retry now").
44
+ *
45
+ * A numeric `data.retryAfter` is also accepted and interpreted as delta-seconds,
46
+ * matching the header's units. Returns `undefined` when the error carries no
47
+ * parseable hint, so callers fall back to exponential backoff.
48
+ */
49
+ function parseRetryAfterMs(error) {
50
+ if (!(error instanceof McpError))
51
+ return;
52
+ const raw = error.data?.retryAfter;
53
+ if (typeof raw === 'number') {
54
+ return Number.isFinite(raw) && raw >= 0 ? raw * 1000 : undefined;
55
+ }
56
+ if (typeof raw !== 'string')
57
+ return;
58
+ const trimmed = raw.trim();
59
+ if (trimmed === '')
60
+ return;
61
+ // delta-seconds: a bare non-negative integer. Checked before Date.parse so a
62
+ // value like "120" is never misread as a calendar year.
63
+ if (/^\d+$/.test(trimmed))
64
+ return Number(trimmed) * 1000;
65
+ // HTTP-date: absolute instant → wait from now, clamped at 0.
66
+ const dateMs = Date.parse(trimmed);
67
+ if (Number.isNaN(dateMs))
68
+ return;
69
+ return Math.max(0, dateMs - Date.now());
70
+ }
34
71
  /**
35
72
  * Default transient check: `McpError` with a transient code, or any non-McpError
36
73
  * (network failures, unexpected throws) which are assumed transient.
@@ -92,6 +129,14 @@ function enrichExhaustedError(error, totalAttempts, operation) {
92
129
  * via `ctx.fail`) for failures that can never succeed on retry (oversized query,
93
130
  * malformed request surfaced as HTTP 200 + error body, etc.).
94
131
  *
132
+ * **Retry-After honoring.** When a transient error carries `data.retryAfter`
133
+ * (captured by `fetchWithTimeout` / `httpErrorFromResponse` from the upstream
134
+ * header), the retry delay honors it — parsing both delta-seconds and HTTP-date
135
+ * forms (RFC 9110 §10.2.3) — instead of the exponential value. If the requested
136
+ * wait exceeds `maxDelayMs`, the error is treated as non-transient and fails
137
+ * fast: a window that won't clear within the retry budget is surfaced to the
138
+ * caller immediately rather than burning attempts that cannot succeed.
139
+ *
95
140
  * When retries exhaust, the final error is enriched with attempt count in both
96
141
  * the message and structured data, so callers know retries were already attempted.
97
142
  *
@@ -133,13 +178,23 @@ export async function withRetry(fn, options = {}) {
133
178
  if (!isTransient(error)) {
134
179
  throw error;
135
180
  }
181
+ // Honor an upstream Retry-After hint over blind exponential backoff.
182
+ const retryAfterMs = parseRetryAfterMs(error);
183
+ // A requested wait longer than the cap can't clear within the retry budget —
184
+ // surface the limit immediately instead of burning an attempt on a window
185
+ // that won't open in time.
186
+ if (retryAfterMs !== undefined && retryAfterMs > maxDelayMs) {
187
+ logger.debug(`Retry-After ${Math.round(retryAfterMs)}ms exceeds maxDelayMs ${maxDelayMs}ms for ${operation ?? 'operation'} — failing fast`, context);
188
+ throw error;
189
+ }
136
190
  if (isLastAttempt) {
137
191
  throw enrichExhaustedError(error, totalAttempts, operation);
138
192
  }
139
- // Log and backoff
140
- const delay = computeDelay(attempt, baseDelayMs, maxDelayMs, jitter);
193
+ // Log and backoff — the honored Retry-After wins over the exponential value.
194
+ const delay = retryAfterMs ?? computeDelay(attempt, baseDelayMs, maxDelayMs, jitter);
141
195
  const errorMessage = error instanceof Error ? error.message : String(error);
142
- logger.debug(`Retry ${attempt + 1}/${maxRetries} for ${operation ?? 'operation'}: ${errorMessage} — waiting ${Math.round(delay)}ms`, context);
196
+ const delaySource = retryAfterMs === undefined ? '' : ' (Retry-After)';
197
+ logger.debug(`Retry ${attempt + 1}/${maxRetries} for ${operation ?? 'operation'}: ${errorMessage} — waiting ${Math.round(delay)}ms${delaySource}`, context);
143
198
  await sleep(delay, signal);
144
199
  }
145
200
  }
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/network/retry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/network/retry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/mcp-ts-core",
3
- "version": "0.10.14",
3
+ "version": "0.10.15",
4
4
  "mcpName": "io.github.cyanheads/mcp-ts-core",
5
5
  "description": "Agent-native TypeScript framework for building MCP servers. Declarative definitions with auth, multi-backend storage, OpenTelemetry, and first-class support for Bun/Node/Cloudflare Workers.",
6
6
  "files": [
@@ -193,9 +193,9 @@
193
193
  "publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish"
194
194
  },
195
195
  "devDependencies": {
196
- "@biomejs/biome": "2.5.2",
197
- "@cloudflare/vitest-pool-workers": "^0.18.0",
198
- "@cloudflare/workers-types": "5.20260705.1",
196
+ "@biomejs/biome": "2.5.4",
197
+ "@cloudflare/vitest-pool-workers": "^0.18.4",
198
+ "@cloudflare/workers-types": "5.20260706.1",
199
199
  "@duckdb/node-api": "^1.5.4-r.1",
200
200
  "@hono/otel": "^1.1.2",
201
201
  "@opentelemetry/exporter-metrics-otlp-http": "^0.220.0",
@@ -206,44 +206,44 @@
206
206
  "@opentelemetry/sdk-metrics": "^2.9.0",
207
207
  "@opentelemetry/sdk-node": "^0.220.0",
208
208
  "@opentelemetry/sdk-trace-node": "^2.9.0",
209
- "@opentelemetry/semantic-conventions": "^1.41.1",
209
+ "@opentelemetry/semantic-conventions": "^1.43.0",
210
210
  "@socketsecurity/bun-security-scanner": "^1.1.2",
211
- "@supabase/supabase-js": "^2.110.0",
211
+ "@supabase/supabase-js": "^2.110.6",
212
212
  "@types/bun": "^1.3.14",
213
- "@types/node": "26.1.0",
213
+ "@types/node": "26.1.1",
214
214
  "@types/papaparse": "^5.5.2",
215
215
  "@types/sanitize-html": "^2.16.1",
216
216
  "@types/validator": "^13.15.10",
217
- "@vitest/coverage-istanbul": "4.1.9",
218
- "@vitest/ui": "4.1.9",
217
+ "@vitest/coverage-istanbul": "4.1.10",
218
+ "@vitest/ui": "4.1.10",
219
219
  "better-sqlite3": "^12.11.1",
220
220
  "bun-types": "^1.3.14",
221
- "chrono-node": "^2.9.1",
221
+ "chrono-node": "^2.10.0",
222
222
  "clipboardy": "^5.3.1",
223
223
  "defuddle": "^0.19.1",
224
224
  "depcheck": "^1.4.7",
225
225
  "diff": "^9.0.0",
226
226
  "execa": "^9.6.1",
227
- "fast-check": "^4.8.0",
228
- "fast-xml-parser": "^5.9.3",
229
- "ignore": "^7.0.5",
227
+ "fast-check": "^4.9.0",
228
+ "fast-xml-parser": "^5.10.1",
229
+ "ignore": "^7.0.6",
230
230
  "js-yaml": "^5.2.1",
231
- "linkedom": "^0.18.12",
232
- "node-cron": "^4.5.0",
233
- "openai": "^6.45.0",
231
+ "linkedom": "^0.18.13",
232
+ "node-cron": "^4.6.0",
233
+ "openai": "^6.46.0",
234
234
  "papaparse": "^5.5.4",
235
235
  "partial-json": "^0.1.7",
236
236
  "pdf-lib": "^1.17.1",
237
237
  "pino-pretty": "^13.1.3",
238
- "repomix": "^1.16.0",
239
- "sanitize-html": "^2.17.5",
240
- "tsc-alias": "^1.9.0",
241
- "typedoc": "^0.28.19",
238
+ "repomix": "^1.16.1",
239
+ "sanitize-html": "^2.17.6",
240
+ "tsc-alias": "^1.9.1",
241
+ "typedoc": "^0.28.20",
242
242
  "typescript": "^6.0.3",
243
243
  "unpdf": "^1.6.2",
244
244
  "validator": "^13.15.35",
245
- "vite": "8.1.3",
246
- "vitest": "^4.1.9"
245
+ "vite": "8.1.5",
246
+ "vitest": "^4.1.10"
247
247
  },
248
248
  "keywords": [
249
249
  "agent",
@@ -295,13 +295,13 @@
295
295
  "access": "public"
296
296
  },
297
297
  "dependencies": {
298
- "@hono/mcp": "^0.3.0",
299
- "@hono/node-server": "^2.0.8",
298
+ "@hono/mcp": "^0.3.1",
299
+ "@hono/node-server": "^2.0.10",
300
300
  "@modelcontextprotocol/ext-apps": "^1.7.4",
301
301
  "@modelcontextprotocol/sdk": "^1.29.0",
302
302
  "@opentelemetry/api": "^1.9.1",
303
303
  "dotenv": "^17.4.2",
304
- "hono": "^4.12.27",
304
+ "hono": "^4.12.30",
305
305
  "jose": "^6.2.3",
306
306
  "pino": "^10.3.1",
307
307
  "zod": "^4.4.3"
@@ -4,7 +4,7 @@ description: >
4
4
  API reference for all utilities exported from `@cyanheads/mcp-ts-core/utils`. Use when looking up utility method signatures, options, peer dependencies, or usage patterns.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.4"
7
+ version: "2.5"
8
8
  audience: external
9
9
  type: reference
10
10
  ---
@@ -29,9 +29,9 @@ Utility exports from `@cyanheads/mcp-ts-core/utils`. Utilities with complex APIs
29
29
 
30
30
  | Export | API | Notes |
31
31
  |:-------|:----|:------|
32
- | `fetchWithTimeout` | `(url, timeoutMs, context: RequestContext, options?: FetchWithTimeoutOptions) -> Promise<Response>` | Wraps `fetch` with `AbortController` timeout. `FetchWithTimeoutOptions` extends `RequestInit` (minus `signal`) and adds `rejectPrivateIPs?: boolean` and `signal?: AbortSignal` (external cancellation). SSRF guard (best-effort, not hard isolation): blocks RFC 1918, loopback, link-local, CGNAT, cloud metadata. DNS validation on Node, Bun, and Cloudflare Workers under `nodejs_compat`; hostname-only fallback otherwise. Manual redirect following (max 5) with per-hop SSRF check. **DNS rebinding / TOCTOU gap** — the validation lookup and `fetch`'s own resolution are independent; pair with egress controls or a DNS-pinning fetch proxy for strong isolation. **Error/log redaction:** URLs written into thrown errors and log lines are reduced to `origin + pathname` — the query string (where API keys commonly ride: `?api-key=…`, `?api_key=…`) never reaches the client or the logs. The actual request still uses the full URL. |
33
- | `withRetry` | `<T>(fn: () => Promise<T>, options?: RetryOptions) -> Promise<T>` | Executes `fn` with exponential backoff. Retries on transient errors (`ServiceUnavailable`, `Timeout`, `RateLimited`); non-transient errors fail immediately. On exhaustion, enriches the final error with attempt count in message and `data.retryAttempts`. **Place the retry boundary around the full pipeline** (fetch + parse), not just the network call. `RetryOptions`: `maxRetries` (default `3`), `baseDelayMs` (default `1000`), `maxDelayMs` (default `30000`), `jitter` (default `0.25`), `operation` (log label), `context` (RequestContext), `signal` (AbortSignal), `isTransient` (custom predicate). |
34
- | `httpErrorFromResponse` | `(response: Response, options?: HttpErrorFromResponseOptions) -> Promise<McpError>` | Maps an HTTP `Response` to a properly classified `McpError` — full status table including 401/403/408/422/429/5xx, body capture (truncated), `retry-after` header, optional `cause`. Use this instead of hand-rolling `if (status === 429) ...` ladders. Reads the response body — `clone()` first if you need it elsewhere. `HttpErrorFromResponseOptions`: `service?` (logical name in message, e.g. `'NCBI'`), `captureBody?` (default `true`), `bodyLimit?` (default `500`), `data?` (extra fields merged into `error.data`), `cause?`, `codeOverride?` (per-status mapping override). Pairs naturally with `withRetry` — both classify codes the same way. |
32
+ | `fetchWithTimeout` | `(url, timeoutMs, context: RequestContext, options?: FetchWithTimeoutOptions) -> Promise<Response>` | Wraps `fetch` with `AbortController` timeout. `FetchWithTimeoutOptions` extends `RequestInit` (minus `signal`) and adds `rejectPrivateIPs?: boolean`, `expectedStatuses?: number[]` (listed non-2xx statuses logged at `debug` not `error`, still thrown), and `signal?: AbortSignal` (external cancellation). On a non-2xx, `error.data` carries `status`/`body` plus the legacy `statusCode`/`responseBody` aliases (identical values; consolidating in a future major). SSRF guard (best-effort, not hard isolation): blocks RFC 1918, loopback, link-local, CGNAT, cloud metadata. DNS validation on Node, Bun, and Cloudflare Workers under `nodejs_compat`; hostname-only fallback otherwise. Manual redirect following (max 5) with per-hop SSRF check. **DNS rebinding / TOCTOU gap** — the validation lookup and `fetch`'s own resolution are independent; pair with egress controls or a DNS-pinning fetch proxy for strong isolation. **Error/log redaction:** URLs written into thrown errors and log lines are reduced to `origin + pathname` — the query string (where API keys commonly ride: `?api-key=…`, `?api_key=…`) never reaches the client or the logs. The actual request still uses the full URL. |
33
+ | `withRetry` | `<T>(fn: () => Promise<T>, options?: RetryOptions) -> Promise<T>` | Executes `fn` with exponential backoff. Retries on transient errors (`ServiceUnavailable`, `Timeout`, `RateLimited`); non-transient errors fail immediately. Honors an upstream `Retry-After` on `data.retryAfter` (delta-seconds or HTTP-date) over exponential backoff, capped at `maxDelayMs`; a requested wait beyond the cap fails fast rather than sleeping. On exhaustion, enriches the final error with attempt count in message and `data.retryAttempts`. **Place the retry boundary around the full pipeline** (fetch + parse), not just the network call. `RetryOptions`: `maxRetries` (default `3`), `baseDelayMs` (default `1000`), `maxDelayMs` (default `30000`), `jitter` (default `0.25`), `operation` (log label), `context` (RequestContext), `signal` (AbortSignal), `isTransient` (custom predicate). |
34
+ | `httpErrorFromResponse` | `(response: Response, options?: HttpErrorFromResponseOptions) -> Promise<McpError>` | Maps an HTTP `Response` to a properly classified `McpError` — full status table including 401/403/408/422/429/5xx, body capture (truncated), `retry-after` header, optional `cause`. `error.data` carries `status`/`body` plus the legacy `statusCode`/`responseBody` aliases (identical values), so a consumer can classify either helper's error without knowing which raised it. Use this instead of hand-rolling `if (status === 429) ...` ladders. Reads the response body — `clone()` first if you need it elsewhere. `HttpErrorFromResponseOptions`: `service?` (logical name in message, e.g. `'NCBI'`), `captureBody?` (default `true`), `bodyLimit?` (default `500`), `data?` (extra fields merged into `error.data`), `cause?`, `codeOverride?` (per-status mapping override). Pairs naturally with `withRetry` — both classify codes the same way. |
35
35
  | `httpStatusToErrorCode` | `(status: number) -> JsonRpcErrorCode \| undefined` | Sync status → code lookup. Returns `undefined` for 1xx/2xx/3xx. Use when you need just the code without a `Response` object handy. |
36
36
 
37
37
  ---
@@ -4,7 +4,7 @@ description: >
4
4
  Exercise tools, resources, and prompts against a live HTTP server via MCP JSON-RPC over curl. Starts the server, surfaces the catalog, runs real and adversarial inputs, and produces a tight report with concrete findings and numbered follow-up options. Use after adding or modifying definitions, or when the user asks to test, try out, or verify their MCP surface.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "2.6"
7
+ version: "2.7"
8
8
  audience: external
9
9
  type: debug
10
10
  ---
@@ -232,7 +232,7 @@ Treat any hit as a `ux` finding in the report. The authoring rule lives under *T
232
232
  | Category | What to verify |
233
233
  |:---------|:---------------|
234
234
  | Happy path | One realistic input. Output shape matches schema. `content[]` text reads clearly to a human. |
235
- | `structuredContent` ↔ `content[]` parity | Every field in `structuredContent` is surfaced in the text. Parity gap = client-specific blindness. |
235
+ | `structuredContent` ↔ `content[]` parity | Dump the whole array (`jq '.result.content'`) and check every `structuredContent` field is surfaced *somewhere* in it enrichment lands in its own trailing block, not in `content[0]`. Parity gap = client-specific blindness. |
236
236
  | Input error | One invalid input (wrong type or missing required). Error text says *what*, *why*, *how to fix*. |
237
237
 
238
238
  **Situational — add only when triggered**
@@ -271,6 +271,7 @@ When a call surprises you — slow, hangs, returns terse output, surfaces an unh
271
271
 
272
272
  **Interpreting responses**
273
273
 
274
+ - **`content[]` is an array of blocks — read all of them, never just `content[0]`.** A success result is assembled as `[...ctx.content media blocks, ...the format()/JSON domain render, ...the enrichment trailer]`. Everything the handler put on `ctx.enrich` — empty-result notices, totals, query echoes, truncation disclosure — renders in that trailer, a **separate trailing block**, not inside the `format()` block. Quoting `content[0].text` and reporting those fields as absent from `content[]` is a false parity gap; the suggested fix (render them in `format()` too) would double-render them. Dump `.result.content` in full before claiming drift.
274
275
  - Tool domain errors return `{result: {content: [...], isError: true}}` — they live in `result`, not `error`. Check `isError`, not the JSON-RPC error field.
275
276
  - **Tool error code/reason** rides on `result.structuredContent.error.{code, message, data?.reason}` — inspect that, not just the text. `data` is only spread when the handler threw an `McpError` (or `ZodError`); plain `throw new Error(...)` won't populate `data.reason`. Use `ctx.fail`-thrown errors when the contract reason matters. The text in `result.content[0].text` mirrors the message and includes `Recovery: <hint>` when `data.recovery.hint` is present.
276
277
  - **Resource errors** are JSON-RPC-level — they appear in the top-level `error.{code, data.reason}` field, not inside `result`. Resource handlers re-throw rather than producing an `isError` envelope.
@@ -297,7 +298,7 @@ One paragraph. How many definitions exercised, how many passed clean, how many h
297
298
 
298
299
  #### Findings
299
300
 
300
- Only include definitions with issues. Group by severity. Each finding is 2–4 lines unless it genuinely needs more.
301
+ Only include definitions with issues. Group by severity. Each finding is 2–4 lines unless it genuinely needs more. A parity finding cites the full `content[]` dump as its evidence — a quote from one index doesn't establish drift.
301
302
 
302
303
  | Severity | Meaning |
303
304
  |:---------|:--------|
@@ -336,7 +337,7 @@ End with:
336
337
  - [ ] HTTP server built and started; real port parsed from log
337
338
  - [ ] Session initialized; `notifications/initialized` sent
338
339
  - [ ] Catalog surfaced and presented; descriptions audited for leaks (implementation details, meta-coaching, consumer-aware phrasing)
339
- - [ ] Universal battery run on every definition (happy path, parity, input error)
340
+ - [ ] Universal battery run on every definition (happy path, parity against the full `content[]` array, input error)
340
341
  - [ ] Situational categories applied only when triggered
341
342
  - [ ] **If >15 tools:** sampled 30–40% for situational testing; skipped definitions listed in report
342
343
  - [ ] **If a tool declared an `errors: [...]` contract:** ≥1 declared failure mode triggered; `result.structuredContent.error.code` and `data.reason` verified against the contract entry
@@ -4,7 +4,7 @@ description: >
4
4
  Land working-tree changes as logical commits — the work grouped by concern, topped by a release commit (version bump, changelog, regenerated artifacts) and an annotated tag. Verify, commit, tag. Stops at "committed and tagged locally" — no push, no publish. The release-and-publish skill picks up from here. Distilled from the git_wrapup_instructions protocol.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.7"
7
+ version: "1.8"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -160,40 +160,28 @@ Use `-m` with embedded newlines in the string (the commit `-m`-only constraint a
160
160
 
161
161
  `--cleanup=whitespace` is load-bearing. The default cleanup (`strip`) deletes `#`-leading lines as comments, so markdown headers silently vanish from the tag body. `--cleanup=verbatim` is worse: it skips end-of-message normalization, so with tag signing enabled the signature is appended flush against the message's last character — git then can't parse its own signature (the tag reads as unsigned) and the whole `-----BEGIN SSH SIGNATURE-----` block publishes verbatim into the GitHub Release body.
162
162
 
163
- Format:
163
+ Format — a **headline digest**, never a section-by-section changelog mirror:
164
164
 
165
165
  ```
166
166
  <theme — omit version number, GitHub prepends v<VERSION>:>
167
167
 
168
- <optional context one concise line, two max>
169
-
170
- <Sections Keep a Changelog names, only those with entries>
171
-
172
- Added:
173
-
174
- - <bullet>
175
-
176
- Changed:
177
-
178
- - <bullet>
179
-
180
- <dep arrows if applicable>
181
-
182
- Dependency bumps:
183
-
184
- - `pkg` ^old → ^new
185
-
186
- <N> tests pass; `bun run devcheck` clean.
168
+ - <notable user-facing change> (#N)
169
+ - <notable user-facing change> (#N)
170
+ - <ONE compact grouped line for the minor/internal changes — build config, repo hygiene, metadata>
171
+ - deps: `@cyanheads/mcp-ts-core` ^0.10.6 → ^0.10.14 (+ dev-dep bumps)
187
172
 
188
173
  [CHANGELOG v<version>](https://github.com/<OWNER>/<REPO>/blob/main/changelog/<major.minor>.x/<version>.md)
189
174
  ```
190
175
 
191
176
  **Rules:**
192
177
  - Subject line omits the version number (GitHub prepends `v<VERSION>:` to the release title)
193
- - **No narrative preamble**context under the subject is one concise line, two max; never paragraph blocks. Detail belongs in the bullets
194
- - Not a CHANGELOG copyterse, scannable
178
+ - **Flat bullets onlynever Keep-a-Changelog section headers.** `Added:`/`Changed:`/`Fixed:`/`Dependency bumps:` belong in the changelog file; a tag that mirrors the changelog's structure is wrong even when every line is accurate
179
+ - **Complete at headline granularity**every changelog-worthy change stays visible: notable changes get their own bullet, minor/internal items (build config, repo hygiene, metadata) share ONE grouped compact bullet. Nothing silently dropped, nothing expanded — the changelog carries the depth, the tag carries the existence
180
+ - **Deps: one line max**, naming only what earns it (the framework bump, a major); per-package arrows for the rest live in the changelog entry only
181
+ - **No gates line** — test counts and devcheck status are changelog detail, not release-body material
182
+ - No narrative preamble — bullets under the subject, no paragraph blocks
195
183
  - No marketing adjectives
196
- - Length is earned — two-line tags are fine for small patches
184
+ - Length is earned — a subject + two bullets + changelog link is a fine tag for a small patch
197
185
  - **Issue backlinks:** when changes address GitHub issues, include `(#N)` references in the relevant bullets — same as the changelog entry. The backlinks render as clickable links in the GitHub Release body.
198
186
  - **Changelog link (final line):** end the tag body with a Markdown link to this version's changelog file, so the GitHub Release offers a one-click jump to the full entry — `[CHANGELOG v<version>](https://github.com/<OWNER>/<REPO>/blob/main/changelog/<major.minor>.x/<version>.md)`. Derive `<OWNER>/<REPO>` from the origin remote; the path mirrors the file authored in step 4 (e.g. `changelog/0.10.x/0.10.12.md`). Keep the blank line above it so it renders as its own paragraph, not appended to the gates line.
199
187
 
@@ -4,7 +4,7 @@ description: >
4
4
  Pick and run a multi-phase workflow that chains foundational task skills (`git-wrapup`, `release-and-publish`, `maintenance`, `field-test`, `setup`, etc.) end-to-end. Routes user intent to a workflow file under `workflows/` — greenfield builds, maintenance + release, field-test + fix, or known-work + release. Single source for the universal rules (no commits without authorization, no destructive git, no marketing language), the orchestrator posture (own the goal, ground sub-agents in primary sources, verify against the goal), and the sub-agent strategy (orient block, parallel fanout, isolation, normalization) that apply across every workflow. Sub-agents are an optional capability — workflows run linearly when fanout isn't available.
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.6"
7
+ version: "1.7"
8
8
  audience: external
9
9
  type: workflow
10
10
  ---
@@ -189,7 +189,7 @@ Sub-agent self-reports describe intent, not always reality. After every phase th
189
189
  - **GitHub** — `gh repo view --json visibility`, `gh release view v<VERSION>`, `gh issue list`, `gh issue view <N> --comments` to confirm the fix comment landed
190
190
  - **npm / registries** — `npm view <pkg>@<version>`, registry-specific checks
191
191
  - **Build state** — re-run `bun run devcheck` if the previous phase was supposed to land green
192
- - **Quality** — tag annotation reads as structured markdown (not flat string), subject omits the version number, no marketing adjectives, dep arrows present where applicable, issue backlinks where applicable
192
+ - **Quality** — tag annotation is a headline digest covering every change (flat bullets — notable ones named, minor ones in one grouped bullet; no changelog section headers, deps ≤1 line, no gates line), subject omits the version number, no marketing adjectives, issue backlinks where applicable, changelog link as final line
193
193
 
194
194
  If verification disagrees with the sub-agent's report, that's the signal to re-spawn with the actual state and the unmet goal in the prompt — not to trust the report. The goal hasn't changed; only the path needs to.
195
195
 
@@ -137,7 +137,7 @@ Each sub-agent reads both `skills/git-wrapup/SKILL.md` and `skills/release-and-p
137
137
  4. Release commit on top — version bump + changelog + regenerated artifacts as `chore(release): v<version>`
138
138
  5. Tag the release commit
139
139
 
140
- The tag annotation and changelog cover ALL fixesthe commit split is about git history, not release notes.
140
+ The changelog carries the depth; the tag annotation covers every change at headline granularity notable ones named, minor ones in one grouped bullet (per git-wrapup step 8). The commit split is about git history, not release notes.
141
141
 
142
142
  **Version bump.** Default **patch** for field-test fix releases. **Minor** when enhancements are bundled in.
143
143
 
@@ -123,7 +123,7 @@ Each sub-agent reads BOTH `skills/git-wrapup/SKILL.md` AND `skills/release-and-p
123
123
  4. Release commit on top: `chore(release): v<version>` — version bump + changelog + regenerated artifacts
124
124
  5. Tag the release commit
125
125
 
126
- The tag annotation and changelog cover ALL fixesthe commit split is about git history, not release notes.
126
+ The changelog carries the depth; the tag annotation covers every change at headline granularity notable ones named, minor ones in one grouped bullet (per git-wrapup step 8). The commit split is about git history, not release notes.
127
127
 
128
128
  **Version bump.** Default **patch** for bug-fix releases. **Minor** when enhancements are included.
129
129
 
@@ -134,7 +134,7 @@ The tag annotation and changelog cover ALL fixes — the commit split is about g
134
134
  | Private / in-development | Version bump → changelog → commit → tag → mcpb bundle → push → `gh release create`. Skip `bun publish`, Docker, MCP Registry. |
135
135
  | Public / launched | Full `release-and-publish`: push + `bun publish` + `publish-mcp` + bundle + GH release + Docker (if Dockerfile). |
136
136
 
137
- **Tag annotations** are for end users — internal dev cleanup (lockfile refreshes, linter fixes, build config) belongs in commit bodies, not the tag annotation.
137
+ **Tag annotations** are for end users — every changelog-worthy change stays visible in the tag, with minor/internal items (build config, repo hygiene, metadata) grouped into ONE compact bullet; only non-changelog churn (lockfile refreshes, lint fixes) stays in commit bodies alone.
138
138
 
139
139
  ### Phase 4: Issue cleanup
140
140
  Close issues that shipped — only those. Skipped issues stay open.
@@ -119,7 +119,7 @@ If a target's diff suggests minor-or-above, **pause that target and surface to t
119
119
  ### Phase 4: Wrap-up + release
120
120
  Each sub-agent reads BOTH `skills/git-wrapup/SKILL.md` AND `skills/release-and-publish/SKILL.md`. Runs wrap-up (version bump, changelog authoring, commit, annotated tag), then release (push, npm publish, MCP Registry, GH release, Docker).
121
121
 
122
- **Framework changelog reading.** When `mcp-ts-core` was updated, the sub-agent must read the framework's changelog files for the version delta (e.g. `node_modules/@cyanheads/mcp-ts-core/changelog/0.9.x/0.9.2.md` through `0.9.6.md`) and distill user-facing changes relevant to this server into the changelog entry and tag annotation. "Picks up upstream fixes" is not acceptable — name what changed.
122
+ **Framework changelog reading.** When `mcp-ts-core` was updated, the sub-agent must read the framework's changelog files for the version delta (e.g. `node_modules/@cyanheads/mcp-ts-core/changelog/0.9.x/0.9.2.md` through `0.9.6.md`) and distill user-facing changes relevant to this server into the changelog entry; the tag annotation carries at most a one-line framework mention with the version arrow. "Picks up upstream fixes" is not acceptable in the changelog — name what changed.
123
123
 
124
124
  **Wrap-up scope.** Determined by repo visibility (`gh repo view --json visibility`):
125
125
 
@@ -135,7 +135,7 @@ Each sub-agent reads BOTH `skills/git-wrapup/SKILL.md` AND `skills/release-and-p
135
135
 
136
136
  **Commit structure.** Group the work by concern, then land the release artifacts (version bumps + changelog + regenerated `docs/tree.md`/`server.json`/`manifest.json`) as a `chore(release): <version> — <theme>` commit on top — same model as `git-wrapup` Step 7. A single-concern pass (just dep updates, or one framework adoption) is one work commit plus the release commit; a pass spanning multiple distinct concerns splits into per-concern work commits with the release commit last. Regenerated meta-drift is release-artifact-shaped — it rides in the release commit, never carved out as its own.
137
137
 
138
- **Tag annotations are for end users.** Internal dev cleanup (lockfile refreshes, linter fixes, build config) belongs in the commit body, not the tag annotation.
138
+ **Tag annotations are for end users.** Every changelog-worthy change stays visible in the tag, with minor/internal items (build config, repo hygiene, metadata) grouped into ONE compact bullet; only non-changelog churn (lockfile refreshes, lint fixes) stays in commit bodies alone.
139
139
 
140
140
  **Tag-moving protocol.** If post-version doc changes land after the version commit, move the tag to HEAD: delete remote release, delete remote + local tag, recreate tag at new HEAD with same annotation, re-push, recreate release with `.mcpb`. Authorized within the workflow — same-day forward move.
141
141
 
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: tool-defs-analysis
3
3
  description: >
4
- Read-only audit of MCP definition language across an existing surface — tools, resources, prompts. Walks every definition file and checks 12 categories the LLM reads to decide whether and how to call: voice & tense, internal leaks, audience leaks, defaults, recovery hints, output descriptions, cross-references, sparsity, examples, structure, mutator observability, unit-bearing numeric names. Produces grouped findings with file:line citations and a numbered options list. Use during polish, after a refactor, or before a release. Complements `field-test` (behavior testing) and `security-pass` (security audit).
4
+ Read-only audit of MCP definition language across an existing surface — tools, resources, prompts, server instructions. Walks every definition file and checks 15 categories the LLM reads to decide whether and how to call: voice & tense, internal leaks, audience leaks, defaults, recovery hints, field descriptions, cross-references, sparsity, examples, structure, mutator observability, unit-bearing numeric names, validator-enforced constraints, annotations truthfulness, single-line strings — then a cross-surface pass: naming taxonomy, parameter vocabulary, tool overlap, instructions drift, length outliers. Produces grouped findings with file:line citations and a numbered options list. Use during polish, after a refactor, or before a release. Complements `field-test` (behavior testing) and `security-pass` (security audit).
5
5
  metadata:
6
6
  author: cyanheads
7
- version: "1.3"
7
+ version: "1.4"
8
8
  audience: external
9
9
  type: audit
10
10
  ---
@@ -22,7 +22,7 @@ This skill is the **review-time pass** for that drift. Read each definition the
22
22
  | `security-pass` | Injection, scopes, input sinks |
23
23
  | `tool-defs-analysis` (this) | LLM-facing language across the existing surface |
24
24
 
25
- `field-test` already audits descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing during its catalog step — that's a fast shallow pass alongside live tool calls. This skill is the deeper review: 12 categories, every field, every recovery hint, every default value, with file:line citations.
25
+ `field-test` already audits descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing during its catalog step — that's a fast shallow pass alongside live tool calls. This skill is the deeper review: 15 categories, every field, every recovery hint, every default value, with file:line citations — plus a cross-surface pass for the drift no single file shows.
26
26
 
27
27
  **Read-only.** This skill produces a report; the maintainer applies fixes. While running it, do not run git, do not stage or commit, do not update the changelog, do not run `devcheck`, do not invoke wrapup or release workflows. Fixes flow through the normal authoring path (edit the definition, then re-run this skill if you want to verify).
28
28
 
@@ -53,11 +53,11 @@ find src/mcp-server/resources/definitions -type f -name "*resource.ts" 2>/dev/nu
53
53
  find src/mcp-server/prompts/definitions -type f -name "*.prompt.ts" 2>/dev/null | sort
54
54
  ```
55
55
 
56
- The `*tool.ts` / `*resource.ts` patterns also catch `*.app-tool.ts` / `*.app-resource.ts`. If the server's definitions live elsewhere (`examples/`, a packages workspace, …), audit those paths too.
56
+ The `*tool.ts` / `*resource.ts` patterns also catch `*.app-tool.ts` / `*.app-resource.ts`. If the server's definitions live elsewhere (`examples/`, a packages workspace, …), audit those paths too. Also locate the server-level `instructions` string if the server sets one (the `createApp` option — `grep -rn "instructions" src/ --include="*.ts"`); it's audited in the cross-surface pass.
57
57
 
58
58
  Use `TaskCreate` — one task per file. Mark each complete after its findings are captured.
59
59
 
60
- ### 2. Walk the 12 categories per file
60
+ ### 2. Walk the 15 categories per file
61
61
 
62
62
  Read each definition file in full. Apply every category — most files trip more than one. Capture each hit with `file:line`, the offending excerpt, and a one-line fix.
63
63
 
@@ -79,8 +79,6 @@ Read each definition file in full. Apply every category — most files trip more
79
79
 
80
80
  **Smell:** "/api/v2/by-state", "Adds a second API call", "API requires `two_year_period`", "(deprecated; use bar_v2)", "TODO: support batch mode", "Used internally by FooService".
81
81
 
82
- Prior art: #25.
83
-
84
82
  #### 3. Audience leaks
85
83
 
86
84
  **Look in:** every `description` and `.describe()`.
@@ -89,7 +87,7 @@ Prior art: #25.
89
87
 
90
88
  **Smell:** "suitable for LLM consumption", "Treat the returned ID as the canonical Y", "Agents should…", "Callers should…", "When you call this tool…", any reference to "LLM", "agent", "Claude", "the model".
91
89
 
92
- Prior art: #74. Field-test catches this in its leak audit; this skill is the more thorough pass.
90
+ Field-test catches this in its leak audit; this skill is the more thorough pass.
93
91
 
94
92
  #### 4. Defaults
95
93
 
@@ -107,19 +105,21 @@ Prior art: #74. Field-test catches this in its leak audit; this skill is the mor
107
105
 
108
106
  **Smell:** "Check the logs", "See documentation", "Contact admin", "Try again later" (with no condition), generic non-actionable text, hints that name internal classes or files.
109
107
 
110
- #### 6. Output descriptions
108
+ #### 6. Field descriptions
111
109
 
112
- **Look in:** every field `.describe()` inside `output: z.object({ ... })`.
110
+ **Look in:** every field in `input` and `output` schemas; resource URI template variables.
113
111
 
114
- **Check:** the description tells the agent what the *value* is — not just the field name restated, not silent on dynamic shapes.
112
+ **Check:** every field carries a `.describe()`, and it tells the agent what the *value* is — not just the field name restated, not silent on dynamic shapes. Enum variants — especially operation discriminators — are explained.
115
113
 
116
114
  **Smell:**
117
115
 
116
+ - An input field with no `.describe()` at all
118
117
  - `name: z.string().describe('Name')` — tautology
119
- - `description: z.string().describe('Description.')` tautology
118
+ - `operation: z.enum([...])` whose variants are never explained
120
119
  - `metadata: z.record(z.string(), z.unknown()).describe('Metadata')` — opaque dynamic shape with no hint about keys/values
121
120
  - Optional fields with no note on when they're absent
122
- - Enum fields with no `.describe()` on the variants
121
+ - Paging fields (`total`, `hasMore`, `nextCursor`) with semantics unstated — or a `limit` param that doesn't say whether it caps the page or the whole result
122
+ - A URI template variable (`{cid}`) never described anywhere
123
123
 
124
124
  #### 7. Cross-references
125
125
 
@@ -157,8 +157,6 @@ Prior art: #74. Field-test catches this in its leak audit; this skill is the mor
157
157
 
158
158
  **Smell:** blank lines (`\n\n`) inside a description string, `- bullet` lines, `## Header` lines, "Operations:\n- foo: …" duplicating an enum's `.describe()` text.
159
159
 
160
- Prior art: #33.
161
-
162
160
  #### 11. Mutator observability
163
161
 
164
162
  **Look in:** mutator tools — any tool that writes, updates, deletes, appends, or patches (i.e., definitions without `annotations.readOnlyHint: true`).
@@ -171,11 +169,51 @@ Prior art: #33.
171
169
 
172
170
  **Look in:** every `z.number()` field in `output` schemas.
173
171
 
174
- **Check:** the field name carries a unit when not pinned by context — `sizeInBytes`, `durationInMs`, `priceInCents`, `latencyInMs`. The `.describe()` drops in summarization or gets truncated; the field name persists into the JSON the agent reads.
172
+ **Check:** the field name carries a unit when not pinned by context — `sizeInBytes`, `durationInMs`, `priceInCents`, `latencyInMs`. The `.describe()` drops in summarization or gets truncated; the field name persists into the JSON the agent reads. Scores, ratios, and percentages carry their range the same way — in the name or as the first thing in the describe (`0–1`).
173
+
174
+ **Smell:** `size`, `duration`, `price`, `latency` — bare names that force the agent to guess units; `score`/`confidence` with no stated range (0.87 and 87 both pass the schema). Exempt: `index`, `position`, `page`, `offset`, `limit`, `totalCount`, `itemCount` (dimensionless).
175
+
176
+ #### 13. Constraints in validators
177
+
178
+ **Look in:** input schemas — every field whose `.describe()` states a format, range, length, or pattern.
179
+
180
+ **Check:** stated constraints are machine-enforced in the schema (`.regex()`, `.min()`/`.max()`, `.int()`, `.length()`, an enum) so they emit into the JSON Schema the client renders — a constraint living only in prose reaches a weaker model unreliably and burns retries on malformed input. Opaque-ID params also say how to *obtain* the value (which sibling tool returns it), not just its shape.
181
+
182
+ **Smell:** `.describe('Date in YYYY-MM-DD format')` on a bare `z.string()`; "max 100" in prose with no `.max(100)`; an ID param whose describe gives the format but never the tool that produces it.
183
+
184
+ #### 14. Annotations truthfulness
185
+
186
+ **Look in:** the `annotations` block on every tool.
187
+
188
+ **Check:** hints match what the handler actually does — clients gate confirmation prompts and retry policy on them. A purely-read tool carries `readOnlyHint: true`; deletes and overwrites aren't marked `destructiveHint: false`; retry-safe mutators carry `idempotentHint: true`; tools calling external services carry `openWorldHint: true`. If `annotations.title` is set, it still matches the tool's current name and behavior.
189
+
190
+ **Smell:** `readOnlyHint: true` on anything that writes; a read-only tool with no `readOnlyHint` (clients assume it can mutate); `destructiveHint: false` on a delete; a stale `title` surviving a rename.
175
191
 
176
- **Smell:** `size`, `duration`, `price`, `latency` — bare names that force the agent to guess units or rely on description text. Exempt: `index`, `position`, `totalCount`, `itemCount` (dimensionless).
192
+ #### 15. Single-line strings
177
193
 
178
- ### 3. Report
194
+ **Look in:** every `description`, `.describe()`, and error `recovery` / `when` string in a definition file.
195
+
196
+ **Check:** each is a single-line string literal. NEVER split one across lines with `+` concatenation (`'part one ' + 'part two'`), and never line-wrap a description into a `\n`-bearing template literal. The formatter does not break string literals, so a long single-line string passes formatting untouched — the line-width limit is not a reason to concatenate.
197
+
198
+ **Why it's not cosmetic:** `+`-concatenation forces every fragment to hand-carry its boundary whitespace, and a dropped trailing space silently fuses two words in the rendered schema the model reads (`'…table_name. ' + 'Columns…'` renders as `table_name.Columns`). Correct output is byte-identical to the single-line form, so the concatenation buys nothing and adds a class of silent contract corruption.
199
+
200
+ **Smell:** a string literal ending in `' +` or `" +` at end of line; a `description:` value spanning multiple quoted fragments; a multi-line template literal inside a description (also a Structure finding, #10).
201
+
202
+ **Fix:** collapse to one single-line string literal.
203
+
204
+ ### 3. Cross-surface pass
205
+
206
+ The per-file walk misses drift that only shows between files. After it, sweep the whole surface:
207
+
208
+ - **Naming taxonomy** — verb prefixes mean one thing each across the surface (`search_` / `find_` / `get_` / `list_` / `lookup_`); the same verb carrying different semantics on different tools is a finding.
209
+ - **Parameter vocabulary** — one name per concept everywhere: `query` vs `q`, `limit` vs `maxResults`, `nctId` vs `nct_id` on sibling tools is a finding.
210
+ - **Tool overlap** — for any pair with adjacent scope, the two descriptions alone must answer "when X vs Y." If an agent can't pick, that's material.
211
+ - **Instructions drift** — if the server sets `instructions`: every tool it names exists, workflow guidance reflects the current surface (new tools that belong in it, renamed or removed ones purged), and nothing contradicts a per-tool description.
212
+ - **Length outliers** — a description several times longer than its siblings (attention drag), or a one-liner that underspecifies (selection risk).
213
+
214
+ Cross-surface findings use the same finding format, cited at the file:line you'd change (the `instructions` string is a citable location).
215
+
216
+ ### 4. Report
179
217
 
180
218
  Three sections.
181
219
 
@@ -194,6 +232,8 @@ Issue: <one line: what's wrong>
194
232
  Fix: <one line: what to change to>
195
233
  ```
196
234
 
235
+ Excerpts are verbatim copy-paste from the file as read, line numbers from that read — re-verify any finding written from memory before it enters the report.
236
+
197
237
  Two-level severity:
198
238
 
199
239
  - **material** — affects agent decisions (will mis-select tool, mis-fill input, mis-handle output, swallow an irrecoverable error)
@@ -219,10 +259,11 @@ End with:
219
259
 
220
260
  - [ ] Scope confirmed (whole server / module / specific files)
221
261
  - [ ] Severity floor applied — nits suppressed if user requested
222
- - [ ] Inventory built — every `*.tool.ts`, `*.app-tool.ts`, `*.resource.ts`, `*.app-resource.ts`, `*.prompt.ts` listed
223
- - [ ] Each file walked through all 12 categories (per-file, not 12 separate passes)
262
+ - [ ] Inventory built — every `*.tool.ts`, `*.app-tool.ts`, `*.resource.ts`, `*.app-resource.ts`, `*.prompt.ts` listed; server `instructions` located if set
263
+ - [ ] Each file walked through all 15 categories (per-file, not 15 separate passes)
264
+ - [ ] Cross-surface pass run — naming taxonomy, parameter vocabulary, tool overlap, instructions drift, length outliers
224
265
  - [ ] **Read-only:** no git, no commits, no changelog edits, no `devcheck`, no wrapup invoked during the audit
225
- - [ ] Findings carry file:line citation, excerpt, issue, fix
266
+ - [ ] Findings carry file:line citation, excerpt, issue, fix — excerpts verbatim, line numbers verified
226
267
  - [ ] Report: summary → grouped-by-category findings → numbered options
227
- - [ ] Options section produced — numbered, one-per-file, severity tagged, cherry-pickable
268
+ - [ ] Options section produced — numbered, each single-file-scoped, severity tagged, cherry-pickable
228
269
  - [ ] If no findings: summary states "no findings"; Findings and Options sections omitted
@@ -64,9 +64,9 @@
64
64
  "zod": "{{ZOD_VERSION}}"
65
65
  },
66
66
  "devDependencies": {
67
- "@biomejs/biome": "2.5.2",
67
+ "@biomejs/biome": "2.5.4",
68
68
  "@socketsecurity/bun-security-scanner": "^1.1.2",
69
- "@types/node": "26.1.0",
69
+ "@types/node": "26.1.1",
70
70
  "depcheck": "^1.4.7",
71
71
  "ignore": "^7.0.5",
72
72
  "tsc-alias": "^1.9.0",