@cyanheads/mcp-ts-core 0.7.6 → 0.8.1
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.8.x/0.8.0.md +33 -0
- package/changelog/0.8.x/0.8.1.md +17 -0
- package/changelog/template.md +13 -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 +5 -4
- 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 +54 -1
- package/skills/add-test/SKILL.md +39 -0
- package/skills/add-tool/SKILL.md +42 -5
- package/skills/api-context/SKILL.md +75 -1
- package/skills/api-errors/SKILL.md +183 -5
- 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 +81 -15
- package/skills/maintenance/SKILL.md +5 -2
- package/skills/report-issue-framework/SKILL.md +2 -2
- package/skills/security-pass/SKILL.md +6 -5
- package/templates/AGENTS.md +23 -8
- package/templates/CLAUDE.md +23 -8
- package/templates/changelog/template.md +18 -5
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
|
-
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.
|
|
3
|
+
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.1
|
|
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.
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
Typed error contracts for tools and resources. Backwards compatible — definitions without `errors[]` keep the existing `Context` signature.
|
|
9
|
+
|
|
10
|
+
## Added
|
|
11
|
+
|
|
12
|
+
- **`errors: [{ reason, code, when, retryable? }]`** on `tool()` / `resource()` / `appTool()` / `appResource()`. Surfaces in `tools/list` and `resources/list` under `_meta['mcp-ts-core/errors']`. Const-tuple inference flows the reason union into the handler's `ctx.fail`.
|
|
13
|
+
- **`ctx.fail(reason, msg?, data?, opts?)`** — typed `TypedFail<R>` keyed against the contract's reasons. `ctx.fail('typo')` is a TS error. Constructs an `McpError` with the contract's code, message (defaults to `when`), and `data.reason` auto-populated from the contract — caller-supplied `data.reason` cannot override it.
|
|
14
|
+
- **New core exports:** `TypedFail`, `ReasonOf`, `HandlerContext`, `createFail`. **New `/errors` exports:** `ErrorContract`, `ERROR_CONTRACT_META_KEY`, `buildMetaWithErrorContract`.
|
|
15
|
+
- **`httpErrorFromResponse(response, opts?)` and `httpStatusToErrorCode(status)` in `/utils`** — full 4xx/5xx → `JsonRpcErrorCode` table (401/403/408/422/429/5xx). Captures truncated body and `Retry-After` into `error.data`. Supports `service`, `cause`, `codeOverride`. Exports `HttpErrorFromResponseOptions`.
|
|
16
|
+
- **`partialResult` / `partialResultSchema` / `failureEntrySchema` in `/utils`** — typed succeeded/failed pattern with stable reason enums. Generic over key names. `failed[]` is omitted when empty. Exports `PartialResultObject`.
|
|
17
|
+
- **Three more factories on `/errors`:** `internalError`, `serializationError`, `databaseError`. Same `(message, data?, options?)` signature as the rest.
|
|
18
|
+
- **Handler-body lints** (warnings, surfaced in devcheck): `prefer-mcp-error-in-handler`, `prefer-error-factory`, `preserve-cause-on-rethrow`, `no-stringify-upstream-error`.
|
|
19
|
+
- **Contract lints** (warnings): structural validation (`error-contract-{type,empty,entry-type,code-type,code-unknown,reason-required,reason-format,reason-unique,when-required,retryable-type}`); conformance — `error-contract-conformance` flags undeclared codes thrown from the handler, `error-contract-prefer-fail` flags declared codes thrown directly instead of via `ctx.fail`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) auto-allowed.
|
|
20
|
+
- **`createMockContext({ errors })`** — attaches `ctx.fail` against a contract for tests.
|
|
21
|
+
- **Tests** for typed-fail propagation, the two new lint families, `httpErrorFromResponse`, `partialResult`, and the auto-task / app-tool integration paths.
|
|
22
|
+
|
|
23
|
+
## Changed
|
|
24
|
+
|
|
25
|
+
- **`ToolDefinition` / `ResourceDefinition`** gain a third type parameter `TErrors extends readonly ErrorContract[] | undefined = undefined`. Existing `ToolDefinition<X, Y>` annotations keep working; handler signature collapses to plain `Context` when no contract is declared. `AnyToolDefinition` / `AnyResourceDefinition` widened accordingly.
|
|
26
|
+
- **`AGENTS.md` / `CLAUDE.md` / `templates/AGENTS.md` / `templates/CLAUDE.md`** — Error Handling sections rewritten to lead with the contract path, factories demoted to fallback. Exports table and factory list updated.
|
|
27
|
+
- **`README.md`** — "Structured errors" feature bullet rewritten as "Typed error contracts".
|
|
28
|
+
- **Skills sync** — `add-tool`, `add-resource`, `add-service`, `add-test`, `add-app-tool`, `api-context`, `api-errors`, `api-linter`, `api-testing`, `api-utils`, `design-mcp-server`, `field-test` updated for the new surface. `maintenance` v1.7 → v1.8, `security-pass` v1.1 → v1.2, `report-issue-framework` v1.3 → v1.4.
|
|
29
|
+
- **`docs/tree.md`** regenerated.
|
|
30
|
+
|
|
31
|
+
## Fixed
|
|
32
|
+
|
|
33
|
+
- Stale `@see docs/service-resilience.md` reference removed from `src/utils/network/retry.ts`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Skills sync — service-thrown contract reasons (pass `data: { reason }` from factories), field-test helper hardening, maintenance skill-version paradox check, factory-choice semantic audit"
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.8.1 — 2026-04-28
|
|
7
|
+
|
|
8
|
+
Skill-only follow-up to 0.8.0. Documents the missing pattern for carrying contract `reason` from service-layer throws (services don't have `ctx.fail`), hardens the field-test helper, and teaches `maintenance` to self-detect a skill-version paradox.
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
|
|
12
|
+
- **`api-errors` v1.0 → v1.1** — adds "Carrying contract `reason` from services" section. Services pass `data: { reason: 'X' }` to error factories; the auto-classifier preserves `data` on the wire so clients see the same `error.data.reason` they'd see from `ctx.fail`. Trade-off noted: lint-time conformance enforcement is lost; compensate with one wire-shape test per reason.
|
|
13
|
+
- **`add-service` v1.3 → v1.4** — same pattern surfaced as a "Carry contract `reason` via `data: { reason }`" bullet under the "Services don't declare contracts" rule.
|
|
14
|
+
- **`add-tool` v1.8 → v1.9** — cross-references the service-thrown reason path in the `ctx.fail` section, so handler authors see it where they're already reading.
|
|
15
|
+
- **`field-test` v2.0 → v2.1** — `/tmp/mcp-field-test.sh` helper hardened: build/start failures auto-tail their logs; `mcp_init` captures HTTP status + body on failure; `mcp_call` surfaces 4xx/5xx with body + falls through to raw body when SSE framing is absent (so plain-JSON errors aren't swallowed); new `mcp_log [N]` tails server log for surprising responses; `mcp_stop` waits for SIGTERM, escalates to SIGKILL, reports residual processes.
|
|
16
|
+
- **`maintenance` v1.8 → v1.9** — adds skill-version paradox check: if `node_modules/@cyanheads/mcp-ts-core/skills/maintenance/SKILL.md` version exceeds the running one, run Phase A first and re-invoke. Also adds factory-choice semantic audit row: `invalidParams` is for malformed JSON-RPC params (rare post-Zod); semantic post-shape validation should use `validationError`. Wrong codes degrade `mcp_error_classified_code` observability and break client retry logic.
|
|
17
|
+
- **`templates/changelog/template.md`** — example issue/PR numbers updated from placeholder `#12`/`#17` to concrete `#38`/`#42` against `cyanheads/mcp-ts-core` so the linking guidance reads correctly when copied.
|
package/changelog/template.md
CHANGED
|
@@ -27,6 +27,19 @@ breaking: false
|
|
|
27
27
|
|
|
28
28
|
Optional narrative intro — 1-3 sentences framing the release theme. Delete if not needed.
|
|
29
29
|
|
|
30
|
+
TONE: terse and fact-dense. 1-2 sentence(s) per bullet where possible —
|
|
31
|
+
name the symbol, state what changed, stop. Drop "explains how it works" prose;
|
|
32
|
+
that belongs in JSDoc, AGENTS.md, or the relevant skill. Drop ceremonial
|
|
33
|
+
framings ("This release introduces…", "fully backwards compatible:" with a
|
|
34
|
+
paragraph of justification). Prefer code/symbol names over English
|
|
35
|
+
re-explanations. If a bullet runs more than ~2 lines, split it or cut it.
|
|
36
|
+
|
|
37
|
+
WHAT TO INCLUDE: every distinct fact a reader needs to adopt or audit the
|
|
38
|
+
release — new exports, signatures, lint rule IDs, env vars, breaking
|
|
39
|
+
changes, version bumps on shipped skills. WHAT TO CUT: mechanism walkthroughs,
|
|
40
|
+
duplicate prose between Added and Changed, file-by-file test enumerations,
|
|
41
|
+
internal implementation notes. Trust the reader to read the code or the docs.
|
|
42
|
+
|
|
30
43
|
Linking issues/PRs: use full URLs so the link works everywhere (GitHub web UI,
|
|
31
44
|
npm/node_modules reads, local editors). GitHub's bare `#NN` auto-link only
|
|
32
45
|
resolves inside its own UI.
|
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"}
|