@cyanheads/mcp-ts-core 0.7.5 → 0.8.0
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/CLAUDE.md +22 -7
- package/README.md +2 -2
- package/changelog/0.7.x/0.7.5.md +1 -1
- package/changelog/0.7.x/0.7.6.md +23 -0
- package/changelog/0.8.x/0.8.0.md +31 -0
- package/changelog/template.md +2 -0
- package/dist/core/context.d.ts +67 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +46 -1
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/linter/rules/error-contract-rules.d.ts +45 -0
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -0
- package/dist/linter/rules/error-contract-rules.js +321 -0
- package/dist/linter/rules/error-contract-rules.js.map +1 -0
- package/dist/linter/rules/handler-body-rules.d.ts +18 -0
- package/dist/linter/rules/handler-body-rules.d.ts.map +1 -0
- package/dist/linter/rules/handler-body-rules.js +134 -0
- package/dist/linter/rules/handler-body-rules.js.map +1 -0
- package/dist/linter/rules/index.d.ts +2 -0
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +2 -0
- package/dist/linter/rules/index.js.map +1 -1
- package/dist/linter/rules/resource-rules.d.ts.map +1 -1
- package/dist/linter/rules/resource-rules.js +9 -0
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/source-text.d.ts +19 -0
- package/dist/linter/rules/source-text.d.ts.map +1 -0
- package/dist/linter/rules/source-text.js +96 -0
- package/dist/linter/rules/source-text.js.map +1 -0
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +9 -0
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/logs/combined.log +4 -4
- package/dist/logs/error.log +4 -4
- package/dist/mcp-server/apps/appBuilders.d.ts +9 -4
- package/dist/mcp-server/apps/appBuilders.d.ts.map +1 -1
- package/dist/mcp-server/apps/appBuilders.js +4 -0
- package/dist/mcp-server/apps/appBuilders.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +3 -2
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +13 -5
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +5 -4
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +13 -7
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +64 -16
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +25 -11
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +6 -4
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/types-global/errors.d.ts +82 -0
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +25 -0
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/formatting/index.d.ts +1 -0
- package/dist/utils/formatting/index.d.ts.map +1 -1
- package/dist/utils/formatting/index.js +1 -0
- package/dist/utils/formatting/index.js.map +1 -1
- package/dist/utils/formatting/partialResult.d.ts +145 -0
- package/dist/utils/formatting/partialResult.d.ts.map +1 -0
- package/dist/utils/formatting/partialResult.js +145 -0
- package/dist/utils/formatting/partialResult.js.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/network/httpError.d.ts +112 -0
- package/dist/utils/network/httpError.d.ts.map +1 -0
- package/dist/utils/network/httpError.js +153 -0
- package/dist/utils/network/httpError.js.map +1 -0
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/network/retry.js +0 -1
- package/dist/utils/network/retry.js.map +1 -1
- package/package.json +9 -8
- package/scripts/split-changelog.ts +133 -0
- package/skills/add-app-tool/SKILL.md +12 -0
- package/skills/add-resource/SKILL.md +40 -0
- package/skills/add-service/SKILL.md +47 -0
- package/skills/add-test/SKILL.md +39 -0
- package/skills/add-tool/SKILL.md +39 -4
- package/skills/api-context/SKILL.md +75 -1
- package/skills/api-errors/SKILL.md +162 -4
- package/skills/api-linter/SKILL.md +223 -3
- package/skills/api-testing/SKILL.md +79 -4
- package/skills/api-utils/SKILL.md +4 -2
- package/skills/design-mcp-server/SKILL.md +13 -10
- package/skills/field-test/SKILL.md +8 -2
- package/skills/maintenance/SKILL.md +14 -12
- package/skills/release-and-publish/SKILL.md +9 -16
- package/skills/report-issue-framework/SKILL.md +2 -2
- package/skills/security-pass/SKILL.md +6 -5
- package/skills/setup/SKILL.md +2 -2
- package/templates/AGENTS.md +23 -8
- package/templates/CLAUDE.md +23 -8
- package/templates/changelog/template.md +2 -0
- package/templates/package.json +2 -0
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
|
-
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.
|
|
3
|
+
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.0
|
|
4
4
|
**npm:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) · **Docker:** [ghcr.io/cyanheads/mcp-ts-core](https://ghcr.io/cyanheads/mcp-ts-core)
|
|
5
5
|
|
|
6
6
|
> **Developer note:** Never assume. Read related files and docs before making changes. Read full file content for context. Never edit a file before reading it.
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
| Subpath | Key Exports | Purpose |
|
|
25
25
|
|:--------|:------------|:--------|
|
|
26
|
-
| `@cyanheads/mcp-ts-core` | `createApp`, `tool`, `resource`, `prompt`, `appTool`, `appResource`, `APP_RESOURCE_MIME_TYPE`, `Context`, `z` | Main entry point |
|
|
26
|
+
| `@cyanheads/mcp-ts-core` | `createApp`, `tool`, `resource`, `prompt`, `appTool`, `appResource`, `APP_RESOURCE_MIME_TYPE`, `Context`, `createFail`, `TypedFail`, `ReasonOf`, `HandlerContext`, `z` | Main entry point |
|
|
27
27
|
| `/worker` | `createWorkerHandler`, `CloudflareBindings` | Cloudflare Workers entry |
|
|
28
28
|
| `/tools` | `ToolDefinition`, `AnyToolDefinition`, `ToolAnnotations` | Tool definition types |
|
|
29
29
|
| `/resources` | `ResourceDefinition`, `AnyResourceDefinition` | Resource definition types |
|
|
@@ -345,11 +345,22 @@ See `api-context` skill for full details.
|
|
|
345
345
|
|
|
346
346
|
## Error Handling
|
|
347
347
|
|
|
348
|
-
**
|
|
348
|
+
**Recommended path: declare a typed error contract.** Add `errors: [{ reason, code, when, retryable? }]` to `tool()` / `resource()`. The handler then receives `ctx.fail(reason, msg?, data?)` typed against the reason union — `ctx.fail('typo')` is a TypeScript error. The runtime auto-populates `data.reason` for observability and the contract is published in `tools/list` under `_meta['mcp-ts-core/errors']` so clients can preview failure modes.
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
```ts
|
|
351
|
+
errors: [
|
|
352
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound, when: 'No PMID returned data' },
|
|
353
|
+
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited, when: 'Queue at capacity', retryable: true },
|
|
354
|
+
],
|
|
355
|
+
async handler(input, ctx) {
|
|
356
|
+
if (queue.full()) throw ctx.fail('queue_full');
|
|
357
|
+
// ...
|
|
358
|
+
}
|
|
359
|
+
```
|
|
351
360
|
|
|
352
|
-
**
|
|
361
|
+
The contract describes the **public failure surface** — declare domain-specific failures only. **Baseline codes** (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble from anywhere and are auto-allowed by the conformance lint, so you don't need to enumerate them per-tool. The conformance lint scans handler source text only — failures thrown from called services aren't visible to it (still reach the client correctly via the auto-classifier, just without lint enforcement).
|
|
362
|
+
|
|
363
|
+
**Fallback for ad-hoc throws** (no contract entry fits, prototype tools, service-layer code): use error factories.
|
|
353
364
|
|
|
354
365
|
```ts
|
|
355
366
|
import { notFound, validationError } from '@cyanheads/mcp-ts-core/errors';
|
|
@@ -357,9 +368,13 @@ throw notFound('Item not found', { itemId: '123' });
|
|
|
357
368
|
throw validationError('Missing required field: name', { field: 'name' });
|
|
358
369
|
```
|
|
359
370
|
|
|
360
|
-
Available factories: `invalidParams`, `invalidRequest`, `notFound`, `forbidden`, `unauthorized`, `validationError`, `conflict`, `rateLimited`, `timeout`, `serviceUnavailable`, `configurationError`. All accept `(message, data?, options?)` where `options` is `{ cause?: unknown }`.
|
|
371
|
+
Available factories: `invalidParams`, `invalidRequest`, `notFound`, `forbidden`, `unauthorized`, `validationError`, `conflict`, `rateLimited`, `timeout`, `serviceUnavailable`, `configurationError`, `internalError`, `serializationError`, `databaseError`. All accept `(message, data?, options?)` where `options` is `{ cause?: unknown }`.
|
|
372
|
+
|
|
373
|
+
For HTTP responses from upstream APIs, use `httpErrorFromResponse(response, { service, data })` from `/utils` — maps the full status table (401/403/408/422/429/5xx) and captures body + `Retry-After`.
|
|
374
|
+
|
|
375
|
+
**Auto-classification.** Plain `Error`, `ZodError`, and any other thrown value are caught and classified automatically. Resolution order: `McpError` code (preserved as-is) → JS constructor name (`TypeError` → `ValidationError`) → provider patterns (HTTP status codes, AWS errors, DB errors) → common message patterns → `AbortError` name → `InternalError` fallback.
|
|
361
376
|
|
|
362
|
-
|
|
377
|
+
The startup linter checks handler bodies for `prefer-mcp-error-in-handler`, `prefer-error-factory`, `preserve-cause-on-rethrow`, `no-stringify-upstream-error`, plus contract conformance (`error-contract-conformance` for undeclared non-baseline codes, `error-contract-prefer-fail` for declared codes thrown directly instead of via `ctx.fail`) — all warnings, surfaced in `bun run devcheck`.
|
|
363
378
|
|
|
364
379
|
See `api-errors` skill for the full pattern-matching table, error code reference, and detailed examples.
|
|
365
380
|
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
<div align="center">
|
|
7
7
|
|
|
8
|
-
[](./CHANGELOG.md) [](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [](https://modelcontextprotocol.io/) [](./LICENSE)
|
|
9
9
|
|
|
10
10
|
[](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
@@ -101,7 +101,7 @@ It also works on Cloudflare Workers with `createWorkerHandler()` — same defini
|
|
|
101
101
|
- **Inline auth** — `auth: ['scope']` on definitions. Framework checks scopes before dispatch — no wrapper code.
|
|
102
102
|
- **Task tools** — `task: true` for long-running ops; framework manages create/poll/progress/complete/cancel.
|
|
103
103
|
- **Definition linter** — validates names, schemas, auth scopes, annotation coherence, and format-parity at startup. Standalone CLI (`lint:mcp`) and devcheck step.
|
|
104
|
-
- **
|
|
104
|
+
- **Typed error contracts** — declare `errors: [{ reason, code, when, retryable? }]` on a tool/resource and the handler receives a typed `ctx.fail(reason, …)` keyed against the declared reasons. The contract publishes in `tools/list` so clients preview failure modes; the linter cross-checks the handler body. Error factories (`notFound()`, `httpErrorFromResponse()`, …) for ad-hoc throws; plain `Error` works too — framework auto-classifies.
|
|
105
105
|
- **Multi-backend storage** — `in-memory`, filesystem, Supabase, Cloudflare D1/KV/R2. Swap providers via env var; handlers don't change.
|
|
106
106
|
- **Pluggable auth** — `none`, `jwt`, or `oauth`. Local secret or JWKS verification.
|
|
107
107
|
- **Observability** — Pino logging, optional OpenTelemetry traces and metrics. Request correlation and tool metrics are automatic.
|
package/changelog/0.7.x/0.7.5.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
summary: init scaffold derives script list from package.json files: (closes #73); field-test and design-mcp-server skills audit descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing (closes #74)
|
|
2
|
+
summary: "init scaffold derives script list from package.json files: (closes #73); field-test and design-mcp-server skills audit descriptions for implementation leaks, meta-coaching, and consumer-aware phrasing (closes #74)"
|
|
3
3
|
breaking: false
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "maintenance skill Phase C enumerates package scripts/ instead of a hardcoded list (closes #69); skill git references made tool-agnostic; templates ship runner-friendly start script + bun engine"
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.7.6 — 2026-04-27
|
|
7
|
+
|
|
8
|
+
Patch release closing the symmetric drift fix from [#69](https://github.com/cyanheads/mcp-ts-core/issues/69) and tightening agent-facing skill prose. The `maintenance` skill's Phase C now enumerates the package's installed `scripts/` directory directly, mirroring how Phase A handles skills. Skill prose around git operations is reworded so agents pick whichever git tooling they have available rather than being pointed at literal `git <cmd>` invocations. Consumer templates pick up a runner-friendly `start` script and declare `bun` in `engines` alongside `node`.
|
|
9
|
+
|
|
10
|
+
## Fixed
|
|
11
|
+
|
|
12
|
+
- **`skills/maintenance/` Phase C enumerates the installed `scripts/` directory ([#69](https://github.com/cyanheads/mcp-ts-core/issues/69))** — replaced the hardcoded 8-name script list (`build-changelog.ts build.ts check-docs-sync.ts check-skills-sync.ts clean.ts devcheck.ts lint-mcp.ts tree.ts`) with a `for src in node_modules/@cyanheads/mcp-ts-core/scripts/*.ts` loop. The package's `files:` field gates what lands in `node_modules/.../scripts/`, so enumerating that directory IS the canonical "shipped scripts" set — newly-added scripts (like `check-framework-antipatterns.ts`, added in 0.7.2) are now picked up automatically. Loop also reports `added:` vs `updated:` for clearer signal during sync. Same drift class as [#73](https://github.com/cyanheads/mcp-ts-core/issues/73) — paired symmetric fix on the maintenance side. Deletion case (loop is one-way) was assessed and intentionally not pursued: framework script removals are rare, the `Removed` section of `CHANGELOG.md` is the existing human-in-the-loop signal, and the proposed mitigations (manifest file or `@framework-managed` marker) add permanent surface area for a problem that hasn't occurred.
|
|
13
|
+
- **YAML frontmatter quoting in `changelog/0.7.x/0.7.5.md`** — `summary:` value contained an unquoted `:` (colon-space) inside the string, which GitHub's strict YAML parser rejected with `mapping values are not allowed in this context`. Wrapped value in double quotes. Both `changelog/template.md` and `templates/changelog/template.md` gained a comment line warning future authors to keep the quotes.
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- **`skills/release-and-publish/`, `skills/setup/`, `skills/maintenance/` reworded git references to be tool-agnostic** — replaced literal `git <cmd>` invocations and `bash` fences with action-verb prose ("Use your git tools to push commits and tags to origin", "diff `bun.lock` to surface version deltas", "revert that file using your git tools"). Lets agents pick whichever git tooling they have — `mcp__git-mcp-server__*`, raw `git` via Bash, or other wrappers — instead of being pointed at a single CLI invocation. `release-and-publish` v2.1 → v2.2; `setup` v1.5 → v1.6; `maintenance` v1.6 → v1.7. Also covers `OWNER/REPO` derivation, working-tree verification, and post-sync diff/restore guidance.
|
|
18
|
+
- **Dependency updates** — patch and minor bumps with no API impact: `jose` 6.2.2 → 6.2.3, `@modelcontextprotocol/ext-apps` 1.7.0 → 1.7.1, `@supabase/supabase-js` 2.104.1 → 2.105.0 (peer + dev), `@cloudflare/workers-types` 4.20260424.1 → 4.20260426.1 (dev), `repomix` 1.13.1 → 1.14.0 (dev). Devcheck and full test suite (2558 passing) clean across all updates.
|
|
19
|
+
|
|
20
|
+
## Added
|
|
21
|
+
|
|
22
|
+
- **`templates/package.json` `start` script** — bare `"start": "node dist/index.js"` alongside the existing explicit `start:stdio` / `start:http` variants. External MCP runners and hosted environments that assume the npm-canonical `start` script now work out of the box. The new script is `.env`-respecting (no inline `MCP_TRANSPORT_TYPE` override) so user-configured transport selection still takes effect.
|
|
23
|
+
- **`templates/package.json` declares `bun` in `engines`** — `bun: >=1.2.0` added alongside the existing `node: >=22.0.0`. Documents that the scaffold works on Bun (it already did — Bun runs the template's `tsx` and `node` invocations transparently). Matches the framework's own `package.json` engines field.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Typed error contracts — declarative `errors[]` on tools/resources, typed `ctx.fail(reason)`, advertised in `tools/list`. New `httpErrorFromResponse` and `partialResult` utilities, three more error factories, handler-body + conformance lints"
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.8.0 — 2026-04-28
|
|
7
|
+
|
|
8
|
+
Minor release introducing **typed error contracts** for tools and resources. Definitions can now declare `errors: [{ reason, code, when, retryable? }]` to advertise their failure surface in `tools/list` (under `_meta['mcp-ts-core/errors']`) and receive a typed `ctx.fail(reason, …)` keyed against the declared reason union — TypeScript catches `ctx.fail('typo')` at compile time, the runtime auto-populates `data.reason` for observability, and a startup linter cross-checks the handler body against the contract. Fully backwards compatible: definitions without `errors[]` keep their existing `ctx: Context` signature and direct-throw behavior. Ships alongside two new utility modules (`httpErrorFromResponse`, `partialResult`) and three more error factories.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- **Typed error contracts on `tool()` / `resource()` / `appTool()` / `appResource()`** — new optional `errors: [{ code, reason, when, retryable? }]` field declares the public failure surface. The const-tuple shape preserves literal reasons through to the handler signature: `ctx.fail` is typed as `TypedFail<R>` where `R` is the union of declared `reason` strings, and `HandlerContext<ReasonOf<TErrors>>` collapses to plain `Context` when no contract is declared. Runtime `ctx.fail` constructs an `McpError` with the contract's code, the caller's message (or the `when` text as a fallback), and `data.reason` auto-populated from the contract — caller-supplied `data.reason` cannot override it, preserving `data.reason` as a stable observability identifier. New exports: `TypedFail`, `ReasonOf`, `HandlerContext`, `createFail`, `attachTypedFail` (internal) on `@cyanheads/mcp-ts-core`; `ErrorContract`, `ERROR_CONTRACT_META_KEY`, `buildMetaWithErrorContract` (internal) on `/errors`. Contracts surface in `tools/list` and `resources/list` under `_meta['mcp-ts-core/errors']`. The `appTool` / `appResource` builders forward the third type parameter so MCP App tools get the same compile-time guarantees as standard tools. The auto-task path in `tool-registration.ts` mirrors the standard handler factory's ctx construction so auto-task handlers calling `ctx.fail(...)` work — without `attachTypedFail` they would crash with `ctx.fail is not a function` when the contract is declared.
|
|
13
|
+
- **`httpErrorFromResponse(response, opts?)` and `httpStatusToErrorCode(status)` in `/utils`** — replaces hand-rolled status→code ladders that consumer servers tend to write (and get wrong, especially for 401/403/408/422). Maps the full 4xx/5xx range with specific handling for auth failures, conflicts, validation, rate limits, and timeouts — see the table in the file's JSDoc. Captures the response body (truncated to 500 bytes by default) and `Retry-After` header into `error.data`, supports `cause` chaining, accepts a `service` name for the message subject and a `codeOverride` for upstream-specific quirks. New exports: `httpErrorFromResponse`, `httpStatusToErrorCode`, `HttpErrorFromResponseOptions`.
|
|
14
|
+
- **`partialResult` / `partialResultSchema` / `failureEntrySchema` in `/utils`** — first-class helpers for the "partial success" tool-output pattern (a tool that processes N items and returns the ones that succeeded plus a structured list of the ones that failed, each with a stable `reason` enum). `failureEntrySchema` builds a `{ [idKey]: string; reason: TReason; detail?: string }` Zod object; `partialResultSchema` composes that with a typed succeeded array and totals; `partialResult` constructs the runtime object with the failed array conditionally omitted when empty so `structuredContent` stays clean. Generic over the success/failure key names so the surface mirrors the existing public API of any tool (no forced rename to `succeeded` / `failed`). New exports: `partialResult`, `partialResultSchema`, `failureEntrySchema`, `PartialResultObject`.
|
|
15
|
+
- **Three more error factories: `internalError`, `serializationError`, `databaseError`** — fills the gaps in the factory set so handlers don't fall back to `new McpError(JsonRpcErrorCode.X, …)` for these common codes. All accept the standard `(message, data?, options?)` signature with `cause` chaining support.
|
|
16
|
+
- **Handler-body lint rules** (`src/linter/rules/handler-body-rules.ts`) — heuristic source-text scan that flags four common error-handling anti-patterns in tool and resource handlers: `prefer-mcp-error-in-handler` (plain `throw new Error(...)` should use `McpError` or a factory), `prefer-error-factory` (`new McpError(JsonRpcErrorCode.NotFound, …)` should use `notFound(…)`), `preserve-cause-on-rethrow` (`catch (e) { throw notFound(...) }` without `{ cause: e }` loses the chain), `no-stringify-upstream-error` (throwing a message containing `JSON.stringify(...)` risks leaking raw upstream traces — sanitize first or attach to `data`). All warnings, all surfaced via `bun run devcheck`, all hit at most once per definition to avoid noisy reports.
|
|
17
|
+
- **Error-contract conformance lints** (`src/linter/rules/error-contract-rules.ts`) — when a definition declares `errors[]`, the linter validates structural invariants (`errors` is an array, each entry has `{ code, reason, when }`, `code` is a real `JsonRpcErrorCode`, `reason` is snake_case and unique) plus two cross-checks against the handler body: `error-contract-conformance` flags codes thrown from the handler that aren't declared (suggests adding them), `error-contract-prefer-fail` flags codes that ARE declared but get thrown via factory or `new McpError` instead of `ctx.fail(reason, …)`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble from anywhere and are auto-allowed by conformance, modeled after how OpenAPI-driven frameworks treat 5xx — implicit, not required to enumerate per-endpoint. Source-text scan only; codes thrown from called services are invisible (still classify correctly at runtime via the auto-classifier, just without lint enforcement).
|
|
18
|
+
- **`createMockContext({ errors })` test option** — pass the definition's own `errors` array (`createMockContext({ errors: myTool.errors })`) to attach a typed `ctx.fail` against the contract's reasons. Tests can then assert on `data.reason` without manually composing `createFail`. Mirrors the production handler factory's `attachTypedFail` wiring.
|
|
19
|
+
- **Tests** — `tests/unit/core/typed-fail.test.ts`, `tests/unit/linter/error-contract-rules.test.ts`, `tests/unit/linter/handler-body-rules.test.ts`, `tests/unit/mcp-server/tools/typed-error-contract.test.ts`, `tests/unit/utils/network/httpError.test.ts`, `tests/unit/utils/formatting/partialResult.test.ts`, plus expansion of `tests/unit/mcp-server/tools/tool-registration.lifecycle.test.ts` and `tests/unit/mcp-server/apps/appBuilders.test.ts` for typed-fail propagation through the auto-task and app-tool paths.
|
|
20
|
+
|
|
21
|
+
## Changed
|
|
22
|
+
|
|
23
|
+
- **`AGENTS.md` / `CLAUDE.md` / `templates/AGENTS.md` / `templates/CLAUDE.md` Error Handling sections rewritten** — leads with the typed error contract as the recommended path (with concrete `errors[]` + `ctx.fail` example), demotes plain-throw + factory usage to the fallback for ad-hoc cases, documents baseline-code auto-allow, references the new conformance and handler-body lint diagnostics, and links to `httpErrorFromResponse` for upstream API mapping. Exports table updated to include `createFail`, `TypedFail`, `ReasonOf`, `HandlerContext`. Available factory list expanded to include `internalError`, `serializationError`, `databaseError`.
|
|
24
|
+
- **`README.md` "Structured errors" feature bullet rewritten** to lead with typed contracts (the headline 0.8.0 feature) and demote factories + auto-classification to the fallback path. Mirrors the framing in `AGENTS.md` / `CLAUDE.md`.
|
|
25
|
+
- **Skills sync** — `add-tool`, `add-resource`, `add-service`, `add-test`, `add-app-tool`, `api-context`, `api-errors`, `api-linter`, `api-testing`, `api-utils`, `design-mcp-server`, `field-test` updated to cover the typed-contract API surface, the new utilities, the new lint rules, and the expanded factory set. `maintenance` v1.7 → v1.8 (Step 4 adoption-check row broadened from "new error factories" to "new `/errors` surface — factories, typed contracts, `httpErrorFromResponse`"). `security-pass` v1.1 → v1.2 (Axis 7 leakage check now greps `ctx.fail(` and `httpErrorFromResponse(` alongside `new McpError`, since all three flow through the same `data` payload). `report-issue-framework` v1.3 → v1.4 (`errors` scope row expanded to mention typed contracts, conformance lint, and `httpErrorFromResponse`).
|
|
26
|
+
- **`ToolDefinition` / `ResourceDefinition` gain a third type parameter** `TErrors extends readonly ErrorContract[] | undefined = undefined` — defaults to `undefined`, so existing `ToolDefinition<X, Y>` and `ResourceDefinition<X, Y, Z>` annotations continue to work and the handler signature collapses to plain `Context`. `AnyToolDefinition` and `AnyResourceDefinition` are widened to `readonly ErrorContract[] | undefined` for the new parameter so type-erased arrays passed to `createApp()` still accept mixed contracts.
|
|
27
|
+
- **`docs/tree.md`** regenerated to reflect new files (`error-contract-rules.ts`, `handler-body-rules.ts`, `source-text.ts`, `partialResult.ts`, `httpError.ts`, `check-framework-antipatterns.ts`) and corresponding test files.
|
|
28
|
+
|
|
29
|
+
## Fixed
|
|
30
|
+
|
|
31
|
+
- **Stale `@see docs/service-resilience.md` reference removed** from `src/utils/network/retry.ts` — the linked doc no longer exists in the repo, the JSDoc above already explains the retry boundary semantics.
|
package/changelog/template.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
# Required. One-line headline describing the release. Max 250 chars. No markdown.
|
|
10
10
|
# This line is what the CHANGELOG.md rollup shows — write it like a GitHub Release title.
|
|
11
|
+
# Keep the double quotes around the value — unquoted YAML treats `:` (colon-space)
|
|
12
|
+
# inside the string as a key separator, which fails GitHub's strict YAML parser.
|
|
11
13
|
summary: ""
|
|
12
14
|
|
|
13
15
|
# Set to `true` only if this release has breaking changes (API removals, signature
|
package/dist/core/context.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { RequestTaskStore } from '@modelcontextprotocol/sdk/shared/protocol
|
|
|
9
9
|
import type { CreateMessageResult, ElicitResult, ModelPreferences, SamplingMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
10
10
|
import type { ZodType, z } from 'zod';
|
|
11
11
|
import type { StorageService } from '../storage/core/StorageService.js';
|
|
12
|
+
import { type ErrorContract, McpError } from '../types-global/errors.js';
|
|
12
13
|
import type { Logger } from '../utils/internal/logger.js';
|
|
13
14
|
import type { AuthContext, RequestContext } from '../utils/internal/requestContext.js';
|
|
14
15
|
export type { AuthContext };
|
|
@@ -114,6 +115,72 @@ export interface Context {
|
|
|
114
115
|
/** The parsed resource URI. Only set in resource handler context. */
|
|
115
116
|
readonly uri?: URL | undefined;
|
|
116
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Builds an `McpError` keyed by a contract reason. The reason → code mapping
|
|
120
|
+
* comes from the definition's `errors[]` contract, so the resulting error
|
|
121
|
+
* always carries a code consistent with what was declared.
|
|
122
|
+
*
|
|
123
|
+
* `R` is the union of valid reason strings extracted from the contract.
|
|
124
|
+
* Tools/resources without a contract receive a context that does not include
|
|
125
|
+
* `fail` at all — direct `throw new McpError(...)` is still available.
|
|
126
|
+
*
|
|
127
|
+
* The thrown error's `data.reason` is auto-populated, so observability and the
|
|
128
|
+
* auto-classifier can branch on a stable identifier without parsing message text.
|
|
129
|
+
*/
|
|
130
|
+
export type TypedFail<R extends string> = (reason: R, message?: string, data?: Record<string, unknown>, options?: {
|
|
131
|
+
cause?: unknown;
|
|
132
|
+
}) => McpError;
|
|
133
|
+
/**
|
|
134
|
+
* Extracts the union of `reason` literal strings from a const tuple of
|
|
135
|
+
* `ErrorContract` entries. Returns `never` when the input is undefined, isn't
|
|
136
|
+
* shaped like a contract, or is the wide `ErrorContract[]` type without literal
|
|
137
|
+
* narrowing (the latter case represents the type-erased `AnyToolDefinition` —
|
|
138
|
+
* collapsing it to `never` keeps factory call sites assignable).
|
|
139
|
+
*
|
|
140
|
+
* Used by `tool()` / `resource()` builders to derive the typed-fail signature
|
|
141
|
+
* from the user's `errors: [...]` declaration. The `const` modifier on the
|
|
142
|
+
* builder's type parameter preserves literal types without requiring `as const`
|
|
143
|
+
* at the call site.
|
|
144
|
+
*/
|
|
145
|
+
export type ReasonOf<E> = E extends readonly {
|
|
146
|
+
reason: infer R extends string;
|
|
147
|
+
}[] ? string extends R ? never : R : never;
|
|
148
|
+
/**
|
|
149
|
+
* Handler context. When a definition declares `errors[]`, the handler receives
|
|
150
|
+
* `Context & { fail: TypedFail<R> }` where `R` is the declared reason union.
|
|
151
|
+
* When no contract is declared, the handler receives plain `Context` and must
|
|
152
|
+
* throw `McpError` directly.
|
|
153
|
+
*
|
|
154
|
+
* The conditional `[R] extends [never]` distinguishes "no contract declared"
|
|
155
|
+
* (R = never) from "contract declared with reasons" (R = literal union).
|
|
156
|
+
*/
|
|
157
|
+
export type HandlerContext<R extends string = never> = [R] extends [never] ? Context : Context & {
|
|
158
|
+
fail: TypedFail<R>;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* @internal
|
|
162
|
+
*
|
|
163
|
+
* Builds a runtime `fail` function for a given contract. Looks up the entry
|
|
164
|
+
* by `reason` and constructs an `McpError` with the declared code, the
|
|
165
|
+
* caller's message (or the contract's `when` text as a fallback), and
|
|
166
|
+
* `data.reason` auto-populated from the contract — *not* from caller-supplied
|
|
167
|
+
* data, which is spread first and then overwritten so the contract reason
|
|
168
|
+
* wins. This keeps `data.reason` a stable observability identifier.
|
|
169
|
+
*
|
|
170
|
+
* If the reason isn't in the contract — a JS caller or stale contract slipping
|
|
171
|
+
* past the `TypedFail` type-system guard — `createFail` returns an
|
|
172
|
+
* `McpError(InternalError)` with diagnostic data (`{ reason, declaredReasons }`)
|
|
173
|
+
* rather than throwing, so the call site can `throw` it like any other error.
|
|
174
|
+
*/
|
|
175
|
+
export declare function createFail(errors: readonly ErrorContract[]): TypedFail<string>;
|
|
176
|
+
/**
|
|
177
|
+
* Attaches a typed `fail` helper to `ctx` when the definition declares an
|
|
178
|
+
* error contract; otherwise returns `ctx` unchanged. Used by the tool and
|
|
179
|
+
* resource handler factories so all call sites stay identical.
|
|
180
|
+
*
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
export declare function attachTypedFail(ctx: Context, errors: readonly ErrorContract[] | undefined): Context;
|
|
117
184
|
/** @internal */
|
|
118
185
|
export interface ContextDeps {
|
|
119
186
|
appContext: RequestContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
|
package/dist/core/context.js
CHANGED
|
@@ -5,7 +5,52 @@
|
|
|
5
5
|
* and cancellation.
|
|
6
6
|
* @module src/core/context
|
|
7
7
|
*/
|
|
8
|
-
import { invalidRequest } from '../types-global/errors.js';
|
|
8
|
+
import { invalidRequest, JsonRpcErrorCode, McpError, } from '../types-global/errors.js';
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*
|
|
12
|
+
* Builds a runtime `fail` function for a given contract. Looks up the entry
|
|
13
|
+
* by `reason` and constructs an `McpError` with the declared code, the
|
|
14
|
+
* caller's message (or the contract's `when` text as a fallback), and
|
|
15
|
+
* `data.reason` auto-populated from the contract — *not* from caller-supplied
|
|
16
|
+
* data, which is spread first and then overwritten so the contract reason
|
|
17
|
+
* wins. This keeps `data.reason` a stable observability identifier.
|
|
18
|
+
*
|
|
19
|
+
* If the reason isn't in the contract — a JS caller or stale contract slipping
|
|
20
|
+
* past the `TypedFail` type-system guard — `createFail` returns an
|
|
21
|
+
* `McpError(InternalError)` with diagnostic data (`{ reason, declaredReasons }`)
|
|
22
|
+
* rather than throwing, so the call site can `throw` it like any other error.
|
|
23
|
+
*/
|
|
24
|
+
export function createFail(errors) {
|
|
25
|
+
const byReason = new Map();
|
|
26
|
+
for (const entry of errors)
|
|
27
|
+
byReason.set(entry.reason, entry);
|
|
28
|
+
return (reason, message, data, options) => {
|
|
29
|
+
const entry = byReason.get(reason);
|
|
30
|
+
if (!entry) {
|
|
31
|
+
// Reason isn't in the contract. The TypedFail type prevents this at
|
|
32
|
+
// compile time, but a JS caller (or a stale contract) can still hit it.
|
|
33
|
+
// Surface the bug clearly rather than silently picking a code.
|
|
34
|
+
return new McpError(JsonRpcErrorCode.InternalError, `ctx.fail() called with unknown reason '${reason}' — not declared in errors[].`, { reason, declaredReasons: [...byReason.keys()] }, options);
|
|
35
|
+
}
|
|
36
|
+
// `reason` is spread last so caller-supplied `data.reason` (accidental or
|
|
37
|
+
// adversarial) cannot override the contract reason — preserves the
|
|
38
|
+
// observability invariant that `data.reason` always matches the contract.
|
|
39
|
+
return new McpError(entry.code, message ?? entry.when, { ...data, reason }, options);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Attaches a typed `fail` helper to `ctx` when the definition declares an
|
|
44
|
+
* error contract; otherwise returns `ctx` unchanged. Used by the tool and
|
|
45
|
+
* resource handler factories so all call sites stay identical.
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
export function attachTypedFail(ctx, errors) {
|
|
50
|
+
if (!errors || errors.length === 0)
|
|
51
|
+
return ctx;
|
|
52
|
+
return Object.assign(ctx, { fail: createFail(errors) });
|
|
53
|
+
}
|
|
9
54
|
/**
|
|
10
55
|
* Constructs a Context from internal dependencies.
|
|
11
56
|
* Called by handler factories — not exposed to consumers.
|
package/dist/core/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,OAAO,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ export type { CoreServices, CreateAppOptions, ServerHandle } from '../core/app.j
|
|
|
9
9
|
export { createApp } from '../core/app.js';
|
|
10
10
|
export type { LandingConfig, LandingLink } from '../core/serverManifest.js';
|
|
11
11
|
export { z } from 'zod';
|
|
12
|
-
export type { AuthContext, Context, ContextLogger, ContextProgress, ContextState, SamplingOpts, } from '../core/context.js';
|
|
12
|
+
export type { AuthContext, Context, ContextLogger, ContextProgress, ContextState, HandlerContext, ReasonOf, SamplingOpts, TypedFail, } from '../core/context.js';
|
|
13
|
+
export { createFail } from '../core/context.js';
|
|
13
14
|
export { APP_RESOURCE_MIME_TYPE, appResource, appTool } from '../mcp-server/apps/appBuilders.js';
|
|
14
15
|
export type { AnyPromptDefinition, PromptDefinition, } from '../mcp-server/prompts/utils/promptDefinition.js';
|
|
15
16
|
export { prompt } from '../mcp-server/prompts/utils/promptDefinition.js';
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM1C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,YAAY,EACV,WAAW,EACX,OAAO,EACP,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM1C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM3E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,YAAY,EACV,WAAW,EACX,OAAO,EACP,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAChG,YAAY,EACV,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,gDAAgD,CAAC;AACxE,YAAY,EACV,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oDAAoD,CAAC;AAC9E,sEAAsE;AACtE,YAAY,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,4CAA4C,CAAC;AAMlE,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,UAAU,EACV,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAM3D,YAAY,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,eAAe,GAChB,MAAM,oCAAoC,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { createApp } from '../core/app.js';
|
|
|
10
10
|
// Zod re-export (consumers use the framework's copy, no separate zod dep)
|
|
11
11
|
// ---------------------------------------------------------------------------
|
|
12
12
|
export { z } from 'zod';
|
|
13
|
+
export { createFail } from '../core/context.js';
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// Definition builders & types
|
|
15
16
|
// ---------------------------------------------------------------------------
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ1C,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ1C,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAKhG,OAAO,EAAE,MAAM,EAAE,MAAM,gDAAgD,CAAC;AAKxE,OAAO,EAAE,QAAQ,EAAE,MAAM,oDAAoD,CAAC;AAQ9E,OAAO,EAAE,IAAI,EAAE,MAAM,4CAA4C,CAAC;AAalE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Lint rules for the declarative `errors[]` contract on tool and
|
|
3
|
+
* resource definitions. Validates structure (codes, reasons), uniqueness,
|
|
4
|
+
* and (when a contract is present) cross-checks handler bodies for thrown
|
|
5
|
+
* codes that aren't declared.
|
|
6
|
+
* @module src/linter/rules/error-contract-rules
|
|
7
|
+
*/
|
|
8
|
+
import type { LintDefinitionType, LintDiagnostic } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Validates the `errors[]` contract on a tool/resource definition.
|
|
11
|
+
* Checks:
|
|
12
|
+
* - `errors` is an array
|
|
13
|
+
* - each entry is an object with required `code`, `reason`, `when`
|
|
14
|
+
* - `code` is a real `JsonRpcErrorCode` value
|
|
15
|
+
* - `reason` is snake_case and unique within the contract
|
|
16
|
+
* - `retryable` (when present) is a boolean
|
|
17
|
+
*/
|
|
18
|
+
export declare function lintErrorContract(errors: unknown, definitionType: LintDefinitionType, definitionName: string): LintDiagnostic[];
|
|
19
|
+
/**
|
|
20
|
+
* Cross-checks a definition's declared `errors[]` contract against the codes
|
|
21
|
+
* that appear textually in its `handler` body. Fires only when a contract is
|
|
22
|
+
* present — definitions without an `errors[]` field are silently skipped.
|
|
23
|
+
*
|
|
24
|
+
* **Two distinct findings:**
|
|
25
|
+
*
|
|
26
|
+
* - `error-contract-conformance` — handler throws a non-baseline code that
|
|
27
|
+
* isn't in the contract. Suggests adding it to `errors[]`.
|
|
28
|
+
* - `error-contract-prefer-fail` — handler throws a code that IS in the
|
|
29
|
+
* contract directly (via factory or `new McpError`) instead of via
|
|
30
|
+
* `ctx.fail(reason, …)`. Encourages routing through the typed helper so
|
|
31
|
+
* observers see consistent `data.reason` values.
|
|
32
|
+
*
|
|
33
|
+
* **Baseline codes** (`InternalError`, `ServiceUnavailable`, `Timeout`,
|
|
34
|
+
* `ValidationError`, `SerializationError`) are skipped — they bubble from
|
|
35
|
+
* anywhere and don't need to be enumerated per-tool.
|
|
36
|
+
*
|
|
37
|
+
* Heuristic only: scans handler source text for `JsonRpcErrorCode.X` references
|
|
38
|
+
* and factory calls. Codes thrown from called services are invisible — so this
|
|
39
|
+
* is always a warning, never an error.
|
|
40
|
+
*/
|
|
41
|
+
export declare function lintErrorContractConformance(def: {
|
|
42
|
+
handler?: unknown;
|
|
43
|
+
errors?: unknown;
|
|
44
|
+
}, definitionType: LintDefinitionType, definitionName: string): LintDiagnostic[];
|
|
45
|
+
//# sourceMappingURL=error-contract-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-contract-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/error-contract-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAatE;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,EACf,cAAc,EAAE,kBAAkB,EAClC,cAAc,EAAE,MAAM,GACrB,cAAc,EAAE,CA8IlB;AAuDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5C,cAAc,EAAE,kBAAkB,EAClC,cAAc,EAAE,MAAM,GACrB,cAAc,EAAE,CA4FlB"}
|