@cyanheads/mcp-ts-core 0.8.3 → 0.8.4
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 +8 -4
- package/README.md +1 -1
- package/changelog/0.8.x/0.8.4.md +60 -0
- package/dist/linter/rules/error-contract-rules.d.ts +3 -1
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -1
- package/dist/linter/rules/error-contract-rules.js +40 -2
- package/dist/linter/rules/error-contract-rules.js.map +1 -1
- package/dist/logs/combined.log +4 -12
- package/dist/logs/error.log +4 -12
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +5 -2
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +5 -2
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/types-global/errors.d.ts +24 -3
- package/dist/types-global/errors.d.ts.map +1 -1
- package/package.json +11 -11
- package/skills/add-tool/SKILL.md +32 -10
- package/skills/api-errors/SKILL.md +19 -7
- package/skills/design-mcp-server/SKILL.md +10 -3
- package/templates/AGENTS.md +4 -2
- package/templates/CLAUDE.md +4 -2
- package/templates/src/mcp-server/tools/definitions/echo.tool.ts +1 -0
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
|
-
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.
|
|
3
|
+
**Package:** `@cyanheads/mcp-ts-core` · **Version:** 0.8.4
|
|
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.
|
|
@@ -345,12 +345,16 @@ See `api-context` skill for full details.
|
|
|
345
345
|
|
|
346
346
|
## Error Handling
|
|
347
347
|
|
|
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 linter enforces conformance against the handler body.
|
|
348
|
+
**Recommended path: declare a typed error contract.** Add `errors: [{ reason, code, when, recovery, 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 linter enforces conformance against the handler body. The `recovery` field is required, descriptive metadata for the agent's next move; for the wire payload's `data.recovery.hint` (which the framework mirrors into `content[]` text), pass it explicitly at the throw site when dynamic context matters: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`.
|
|
349
349
|
|
|
350
350
|
```ts
|
|
351
351
|
errors: [
|
|
352
|
-
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
353
|
-
|
|
352
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
353
|
+
when: 'No PMID returned data',
|
|
354
|
+
recovery: 'Try pubmed_search_articles to discover valid PMIDs first.' },
|
|
355
|
+
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited,
|
|
356
|
+
when: 'Queue at capacity', retryable: true,
|
|
357
|
+
recovery: 'Wait 30 seconds before retrying or reduce batch size.' },
|
|
354
358
|
],
|
|
355
359
|
async handler(input, ctx) {
|
|
356
360
|
if (queue.full()) throw ctx.fail('queue_full');
|
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
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "ErrorContract.recovery is now required (≥ 5 words, lint-validated). Decoupled from runtime data.recovery.hint — no auto-population, just a forcing function for thoughtful authoring."
|
|
3
|
+
breaking: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.8.4 — 2026-04-29
|
|
7
|
+
|
|
8
|
+
`recovery: string` joins `code`, `reason`, and `when` as a required field on every `ErrorContract` entry. Closes [#85](https://github.com/cyanheads/mcp-ts-core/issues/85).
|
|
9
|
+
|
|
10
|
+
The contract `recovery` and the throw-site `data.recovery.hint` are **decoupled by design**. The contract field is descriptive metadata read by the linter and scaffolding skills (a forcing function for thoughtful authoring). The wire payload's `data.recovery.hint` — which 0.8.3's error-path parity invariant mirrors into `content[]` text — is populated separately at the throw site by the author when dynamic context matters. No magic, no hidden transformation.
|
|
11
|
+
|
|
12
|
+
## Changed
|
|
13
|
+
|
|
14
|
+
- **`ErrorContract.recovery: string`** (`src/types-global/errors.ts`) — required at the TypeScript type level. Existing tools that declare `errors[]` won't compile without a `recovery` string per entry.
|
|
15
|
+
|
|
16
|
+
## Added
|
|
17
|
+
|
|
18
|
+
- **Three lint rules** (`src/linter/rules/error-contract-rules.ts`):
|
|
19
|
+
- `error-contract-recovery-required` — error when `recovery` is missing or non-string
|
|
20
|
+
- `error-contract-recovery-empty` — error when `recovery` is empty or whitespace-only
|
|
21
|
+
- `error-contract-recovery-min-words` — warning when `recovery` has fewer than 5 words (forcing function against placeholders like "Try again.")
|
|
22
|
+
|
|
23
|
+
## Docs
|
|
24
|
+
|
|
25
|
+
- `CLAUDE.md` / `AGENTS.md` (root + `templates/`) — Error Handling sections updated with the required `recovery` field and the decoupling principle for `data.recovery.hint`.
|
|
26
|
+
- `skills/add-tool/SKILL.md` v2.1 → v2.2 — template scaffolds `recovery` in `errors[]`.
|
|
27
|
+
- `skills/api-errors/SKILL.md` v1.1 → v1.2 — documents the field, lint rules, and decoupling principle.
|
|
28
|
+
- `skills/design-mcp-server/SKILL.md` v2.7 → v2.8 — recovery-hint shape corrected to canonical nested `recovery: { hint: ... }`. Closes [#82](https://github.com/cyanheads/mcp-ts-core/issues/82).
|
|
29
|
+
- `templates/src/mcp-server/tools/definitions/echo.tool.ts` — `empty_message` entry gains a `recovery` string.
|
|
30
|
+
|
|
31
|
+
## Migration
|
|
32
|
+
|
|
33
|
+
Every existing `errors[]` entry needs a `recovery` string. TypeScript will flag missing entries on upgrade — fix in place.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// Before
|
|
37
|
+
errors: [
|
|
38
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
39
|
+
when: 'No item matched.' },
|
|
40
|
+
],
|
|
41
|
+
|
|
42
|
+
// After
|
|
43
|
+
errors: [
|
|
44
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
45
|
+
when: 'No item matched.',
|
|
46
|
+
recovery: 'Broaden the query or check the spelling and try again.' },
|
|
47
|
+
],
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `recovery` string is contract metadata, not the wire-payload hint. To surface dynamic recovery guidance at the call site (mirrored into `content[]` text by 0.8.3's parity invariant), pass it explicitly:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
throw ctx.fail('no_match', `No item ${id}`, {
|
|
54
|
+
recovery: { hint: `No item ${id}; try a different ID.` },
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Maintenance
|
|
59
|
+
|
|
60
|
+
- Dependencies refreshed via `bun update --latest`. All minor/patch — `@opentelemetry/*` (0.215.0 → 0.216.0, 2.7.0 → 2.7.1), `@cloudflare/workers-types` (4.20260426.1 → 4.20260429.1), `unpdf` (1.6.1 → 1.6.2), and others.
|
|
@@ -10,9 +10,11 @@ import type { LintDefinitionType, LintDiagnostic } from '../types.js';
|
|
|
10
10
|
* Validates the `errors[]` contract on a tool/resource definition.
|
|
11
11
|
* Checks:
|
|
12
12
|
* - `errors` is an array
|
|
13
|
-
* - each entry is an object with required `code`, `reason`, `when`
|
|
13
|
+
* - each entry is an object with required `code`, `reason`, `when`, `recovery`
|
|
14
14
|
* - `code` is a real `JsonRpcErrorCode` value
|
|
15
15
|
* - `reason` is snake_case and unique within the contract
|
|
16
|
+
* - `recovery` is non-empty and ≥ 5 words (forcing function for thoughtful
|
|
17
|
+
* agent guidance — placeholders like "Try again." get flagged)
|
|
16
18
|
* - `retryable` (when present) is a boolean
|
|
17
19
|
*/
|
|
18
20
|
export declare function lintErrorContract(errors: unknown, definitionType: LintDefinitionType, definitionName: string): LintDiagnostic[];
|
|
@@ -1 +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;
|
|
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;AAetE;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,EACf,cAAc,EAAE,kBAAkB,EAClC,cAAc,EAAE,MAAM,GACrB,cAAc,EAAE,CAmLlB;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"}
|
|
@@ -13,13 +13,16 @@ import { stripCommentsAndStrings } from './source-text.js';
|
|
|
13
13
|
*/
|
|
14
14
|
const VALID_CODES = new Set(Object.values(JsonRpcErrorCode).filter((v) => typeof v === 'number'));
|
|
15
15
|
const REASON_RE = /^[a-z][a-z0-9_]*$/;
|
|
16
|
+
const RECOVERY_MIN_WORDS = 5;
|
|
16
17
|
/**
|
|
17
18
|
* Validates the `errors[]` contract on a tool/resource definition.
|
|
18
19
|
* Checks:
|
|
19
20
|
* - `errors` is an array
|
|
20
|
-
* - each entry is an object with required `code`, `reason`, `when`
|
|
21
|
+
* - each entry is an object with required `code`, `reason`, `when`, `recovery`
|
|
21
22
|
* - `code` is a real `JsonRpcErrorCode` value
|
|
22
23
|
* - `reason` is snake_case and unique within the contract
|
|
24
|
+
* - `recovery` is non-empty and ≥ 5 words (forcing function for thoughtful
|
|
25
|
+
* agent guidance — placeholders like "Try again." get flagged)
|
|
23
26
|
* - `retryable` (when present) is a boolean
|
|
24
27
|
*/
|
|
25
28
|
export function lintErrorContract(errors, definitionType, definitionName) {
|
|
@@ -56,7 +59,7 @@ export function lintErrorContract(errors, definitionType, definitionName) {
|
|
|
56
59
|
diagnostics.push({
|
|
57
60
|
rule: 'error-contract-entry-type',
|
|
58
61
|
severity: 'error',
|
|
59
|
-
message: `${definitionType} '${definitionName}' ${path} must be an object with { code, reason, when }.`,
|
|
62
|
+
message: `${definitionType} '${definitionName}' ${path} must be an object with { code, reason, when, recovery }.`,
|
|
60
63
|
definitionType,
|
|
61
64
|
definitionName,
|
|
62
65
|
});
|
|
@@ -140,6 +143,41 @@ export function lintErrorContract(errors, definitionType, definitionName) {
|
|
|
140
143
|
definitionName,
|
|
141
144
|
});
|
|
142
145
|
}
|
|
146
|
+
// recovery
|
|
147
|
+
if (typeof e.recovery !== 'string') {
|
|
148
|
+
diagnostics.push({
|
|
149
|
+
rule: 'error-contract-recovery-required',
|
|
150
|
+
severity: 'error',
|
|
151
|
+
message: `${definitionType} '${definitionName}' ${path}.recovery must be a non-empty string ` +
|
|
152
|
+
'describing what the agent should do when this failure occurs.',
|
|
153
|
+
definitionType,
|
|
154
|
+
definitionName,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else if (e.recovery.trim().length === 0) {
|
|
158
|
+
diagnostics.push({
|
|
159
|
+
rule: 'error-contract-recovery-empty',
|
|
160
|
+
severity: 'error',
|
|
161
|
+
message: `${definitionType} '${definitionName}' ${path}.recovery is empty. ` +
|
|
162
|
+
'Provide actionable guidance for the agent.',
|
|
163
|
+
definitionType,
|
|
164
|
+
definitionName,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const wordCount = e.recovery.trim().split(/\s+/).filter(Boolean).length;
|
|
169
|
+
if (wordCount < RECOVERY_MIN_WORDS) {
|
|
170
|
+
diagnostics.push({
|
|
171
|
+
rule: 'error-contract-recovery-min-words',
|
|
172
|
+
severity: 'warning',
|
|
173
|
+
message: `${definitionType} '${definitionName}' ${path}.recovery has ${wordCount} word(s); ` +
|
|
174
|
+
`minimum is ${RECOVERY_MIN_WORDS}. Specific guidance ("Try X with Y") beats ` +
|
|
175
|
+
'placeholders ("Try again.", "Check input.").',
|
|
176
|
+
definitionType,
|
|
177
|
+
definitionName,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
143
181
|
// retryable (optional)
|
|
144
182
|
if (e.retryable !== undefined && typeof e.retryable !== 'boolean') {
|
|
145
183
|
diagnostics.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-contract-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/error-contract-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAsB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAGhF,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,GAAwB,IAAI,GAAG,CAC9C,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAClF,CAAC;AAEF,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAEtC
|
|
1
|
+
{"version":3,"file":"error-contract-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/error-contract-rules.ts"],"names":[],"mappings":"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"}
|
package/dist/logs/combined.log
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
{"level":50,"time":
|
|
2
|
-
{"level":50,"time":
|
|
3
|
-
{"level":50,"time":
|
|
4
|
-
{"level":50,"time":
|
|
5
|
-
{"level":50,"time":1777483974673,"env":"testing","version":"0.0.0-test","pid":34200,"requestId":"MVYCJ-TLNBI","timestamp":"2026-04-29T17:32:54.672Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"6f568a08ab1119ae00ca7f4cd97bfe5b893670d6f9d7a88a860f4573fc3ee041","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"6f568a08ab1119ae00ca7f4cd97bfe5b893670d6f9d7a88a860f4573fc3ee041","toolName":"scoped_echo","requestId":"MVYCJ-TLNBI","timestamp":"2026-04-29T17:32:54.672Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
6
|
-
{"level":50,"time":1777483978488,"env":"testing","version":"0.8.3","pid":34272,"requestId":"O7VS0-DA4A5","timestamp":"2026-04-29T17:32:58.488Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"O7VS0-DA4A5","timestamp":"2026-04-29T17:32:58.488Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
7
|
-
{"level":50,"time":1777483978502,"env":"testing","version":"0.8.3","pid":34272,"requestId":"Y8DXV-SZBT7","timestamp":"2026-04-29T17:32:58.502Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"Y8DXV-SZBT7","timestamp":"2026-04-29T17:32:58.502Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
8
|
-
{"level":50,"time":1777483978505,"env":"testing","version":"0.8.3","pid":34272,"requestId":"5UFOY-T296P","timestamp":"2026-04-29T17:32:58.505Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"5UFOY-T296P","timestamp":"2026-04-29T17:32:58.505Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
9
|
-
{"level":50,"time":1777484002448,"env":"testing","version":"0.0.0-test","pid":34814,"requestId":"XQX2K-P36XG","timestamp":"2026-04-29T17:33:22.447Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"7cd3b418e0988221fbf317aa2fa5726f9522507e2b0804ea29747a63164dc809","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"7cd3b418e0988221fbf317aa2fa5726f9522507e2b0804ea29747a63164dc809","toolName":"scoped_echo","requestId":"XQX2K-P36XG","timestamp":"2026-04-29T17:33:22.447Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
10
|
-
{"level":50,"time":1777484003483,"env":"testing","version":"0.8.3","pid":34851,"requestId":"C5616-WOZJO","timestamp":"2026-04-29T17:33:23.482Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"C5616-WOZJO","timestamp":"2026-04-29T17:33:23.482Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
11
|
-
{"level":50,"time":1777484003499,"env":"testing","version":"0.8.3","pid":34851,"requestId":"QZGO6-FWPV3","timestamp":"2026-04-29T17:33:23.499Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"QZGO6-FWPV3","timestamp":"2026-04-29T17:33:23.499Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
12
|
-
{"level":50,"time":1777484003502,"env":"testing","version":"0.8.3","pid":34851,"requestId":"YQZC9-4ZMV3","timestamp":"2026-04-29T17:33:23.502Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"YQZC9-4ZMV3","timestamp":"2026-04-29T17:33:23.502Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
1
|
+
{"level":50,"time":1777494206031,"env":"testing","version":"0.0.0-test","pid":62030,"requestId":"2DXYH-6OXOG","timestamp":"2026-04-29T20:23:26.030Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"5ab0ea1c5b4e8d62e734a3ffd5bd6a3f01332ecc57a6395af28d53fec5ab98d6","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"5ab0ea1c5b4e8d62e734a3ffd5bd6a3f01332ecc57a6395af28d53fec5ab98d6","toolName":"scoped_echo","requestId":"2DXYH-6OXOG","timestamp":"2026-04-29T20:23:26.030Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
2
|
+
{"level":50,"time":1777494206349,"env":"testing","version":"0.8.4","pid":62034,"requestId":"XIJQG-DQNFH","timestamp":"2026-04-29T20:23:26.348Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"XIJQG-DQNFH","timestamp":"2026-04-29T20:23:26.348Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
3
|
+
{"level":50,"time":1777494206364,"env":"testing","version":"0.8.4","pid":62034,"requestId":"8G1K9-6UPKW","timestamp":"2026-04-29T20:23:26.364Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"8G1K9-6UPKW","timestamp":"2026-04-29T20:23:26.364Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
4
|
+
{"level":50,"time":1777494206368,"env":"testing","version":"0.8.4","pid":62034,"requestId":"IXG6T-KFPFJ","timestamp":"2026-04-29T20:23:26.368Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"IXG6T-KFPFJ","timestamp":"2026-04-29T20:23:26.368Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
package/dist/logs/error.log
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
{"level":50,"time":
|
|
2
|
-
{"level":50,"time":
|
|
3
|
-
{"level":50,"time":
|
|
4
|
-
{"level":50,"time":
|
|
5
|
-
{"level":50,"time":1777483974673,"env":"testing","version":"0.0.0-test","pid":34200,"requestId":"MVYCJ-TLNBI","timestamp":"2026-04-29T17:32:54.672Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"6f568a08ab1119ae00ca7f4cd97bfe5b893670d6f9d7a88a860f4573fc3ee041","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"6f568a08ab1119ae00ca7f4cd97bfe5b893670d6f9d7a88a860f4573fc3ee041","toolName":"scoped_echo","requestId":"MVYCJ-TLNBI","timestamp":"2026-04-29T17:32:54.672Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
6
|
-
{"level":50,"time":1777483978488,"env":"testing","version":"0.8.3","pid":34272,"requestId":"O7VS0-DA4A5","timestamp":"2026-04-29T17:32:58.488Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"O7VS0-DA4A5","timestamp":"2026-04-29T17:32:58.488Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
7
|
-
{"level":50,"time":1777483978502,"env":"testing","version":"0.8.3","pid":34272,"requestId":"Y8DXV-SZBT7","timestamp":"2026-04-29T17:32:58.502Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"Y8DXV-SZBT7","timestamp":"2026-04-29T17:32:58.502Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
8
|
-
{"level":50,"time":1777483978505,"env":"testing","version":"0.8.3","pid":34272,"requestId":"5UFOY-T296P","timestamp":"2026-04-29T17:32:58.505Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"5UFOY-T296P","timestamp":"2026-04-29T17:32:58.505Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
9
|
-
{"level":50,"time":1777484002448,"env":"testing","version":"0.0.0-test","pid":34814,"requestId":"XQX2K-P36XG","timestamp":"2026-04-29T17:33:22.447Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"7cd3b418e0988221fbf317aa2fa5726f9522507e2b0804ea29747a63164dc809","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"7cd3b418e0988221fbf317aa2fa5726f9522507e2b0804ea29747a63164dc809","toolName":"scoped_echo","requestId":"XQX2K-P36XG","timestamp":"2026-04-29T17:33:22.447Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
10
|
-
{"level":50,"time":1777484003483,"env":"testing","version":"0.8.3","pid":34851,"requestId":"C5616-WOZJO","timestamp":"2026-04-29T17:33:23.482Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"C5616-WOZJO","timestamp":"2026-04-29T17:33:23.482Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
11
|
-
{"level":50,"time":1777484003499,"env":"testing","version":"0.8.3","pid":34851,"requestId":"QZGO6-FWPV3","timestamp":"2026-04-29T17:33:23.499Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"QZGO6-FWPV3","timestamp":"2026-04-29T17:33:23.499Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
12
|
-
{"level":50,"time":1777484003502,"env":"testing","version":"0.8.3","pid":34851,"requestId":"YQZC9-4ZMV3","timestamp":"2026-04-29T17:33:23.502Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"YQZC9-4ZMV3","timestamp":"2026-04-29T17:33:23.502Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
1
|
+
{"level":50,"time":1777494206031,"env":"testing","version":"0.0.0-test","pid":62030,"requestId":"2DXYH-6OXOG","timestamp":"2026-04-29T20:23:26.030Z","operation":"HandleToolRequest","critical":false,"errorCode":-32005,"originalErrorType":"McpError","finalErrorType":"McpError","sessionId":"5ab0ea1c5b4e8d62e734a3ffd5bd6a3f01332ecc57a6395af28d53fec5ab98d6","toolName":"scoped_echo","tenantId":"authz-tenant","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"errorData":{"sessionId":"5ab0ea1c5b4e8d62e734a3ffd5bd6a3f01332ecc57a6395af28d53fec5ab98d6","toolName":"scoped_echo","requestId":"2DXYH-6OXOG","timestamp":"2026-04-29T20:23:26.030Z","tenantId":"authz-tenant","operation":"HandleToolRequest","auth":{"sub":"authz-user","scopes":["tool:other:read"],"clientId":"authz-client","tenantId":"authz-tenant"},"originalErrorName":"McpError","originalMessage":"Insufficient permissions.","originalStack":"McpError: Insufficient permissions.\n at forbidden (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:84:58)\n at withRequiredScopes (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/authUtils.js:61:15)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:133:17)\n at executeToolHandler (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:231:34)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:126:43)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Insufficient permissions.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/tools/utils/toolHandlerFactory.js:168: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."}
|
|
2
|
+
{"level":50,"time":1777494206349,"env":"testing","version":"0.8.4","pid":62034,"requestId":"XIJQG-DQNFH","timestamp":"2026-04-29T20:23:26.348Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"XIJQG-DQNFH","timestamp":"2026-04-29T20:23:26.348Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
3
|
+
{"level":50,"time":1777494206364,"env":"testing","version":"0.8.4","pid":62034,"requestId":"8G1K9-6UPKW","timestamp":"2026-04-29T20:23:26.364Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"POST","errorData":{"path":"/mcp","method":"POST","requestId":"8G1K9-6UPKW","timestamp":"2026-04-29T20:23:26.364Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Token has expired.","originalStack":"McpError: Token has expired.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at handleJoseVerifyError (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/lib/claimParser.js:56:11)\n at verify (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/strategies/jwtStrategy.js:91:13)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Token has expired.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Token has expired."}
|
|
4
|
+
{"level":50,"time":1777494206368,"env":"testing","version":"0.8.4","pid":62034,"requestId":"IXG6T-KFPFJ","timestamp":"2026-04-29T20:23:26.368Z","operation":"httpErrorHandler","critical":false,"errorCode":-32006,"originalErrorType":"McpError","finalErrorType":"McpError","path":"/mcp","method":"GET","errorData":{"path":"/mcp","method":"GET","requestId":"IXG6T-KFPFJ","timestamp":"2026-04-29T20:23:26.368Z","operation":"httpErrorHandler","originalErrorName":"McpError","originalMessage":"Missing or invalid Authorization header. Bearer scheme required.","originalStack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at unauthorized (/Users/casey/Developer/github/mcp-ts-core/dist/types-global/errors.js:86:61)\n at authMiddleware (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/auth/authMiddleware.js:64:19)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpTransport.js:232:22)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:22:23)\n at cors2 (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/middleware/cors/index.js:82:11)\n at processTicksAndRejections (native:7:39)"},"stack":"McpError: Missing or invalid Authorization header. Bearer scheme required.\n at handleError (/Users/casey/Developer/github/mcp-ts-core/dist/utils/internal/error-handler/errorHandler.js:169:23)\n at <anonymous> (/Users/casey/Developer/github/mcp-ts-core/dist/mcp-server/transports/http/httpErrorHandler.js:59:39)\n at dispatch (/Users/casey/Developer/github/mcp-ts-core/node_modules/hono/dist/compose.js:26:25)\n at processTicksAndRejections (native:7:39)","msg":"Error in httpTransport: Missing or invalid Authorization header. Bearer scheme required."}
|
|
@@ -156,9 +156,12 @@ export type AnyToolDefinition = ToolDefinition<ZodObject<ZodRawShape>, ZodObject
|
|
|
156
156
|
* ```ts
|
|
157
157
|
* const myTool = tool('my_tool', {
|
|
158
158
|
* errors: [
|
|
159
|
-
* { reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
159
|
+
* { reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
160
|
+
* when: 'No items match the query',
|
|
161
|
+
* recovery: 'Broaden the query or check the spelling and try again.' },
|
|
160
162
|
* { reason: 'rate_limited', code: JsonRpcErrorCode.RateLimited,
|
|
161
|
-
* when: 'Upstream rate limit hit', retryable: true
|
|
163
|
+
* when: 'Upstream rate limit hit', retryable: true,
|
|
164
|
+
* recovery: 'Wait a few seconds before retrying or reduce request frequency.' },
|
|
162
165
|
* ],
|
|
163
166
|
* input: z.object({ query: z.string().describe('Search query') }),
|
|
164
167
|
* output: z.object({ items: z.array(z.string()).describe('Matched items') }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc,CAC7B,MAAM,SAAS,SAAS,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,EAC9D,OAAO,SAAS,SAAS,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,EAC/D,OAAO,SAAS,SAAS,aAAa,EAAE,GAAG,SAAS,GAAG,SAAS;IAEhE,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,qCAAqC;IACrC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,YAAY,EAAE,CAAC;IACtD;;;;;;;;;;;OAWG;IACH,OAAO,CACL,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EACtB,GAAG,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GACrC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChD,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAC5C,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,aAAa,EAAE,GAAG,SAAS,CACrC,CAAC;AAMF
|
|
1
|
+
{"version":3,"file":"toolDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,9 +36,12 @@
|
|
|
36
36
|
* ```ts
|
|
37
37
|
* const myTool = tool('my_tool', {
|
|
38
38
|
* errors: [
|
|
39
|
-
* { reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
39
|
+
* { reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
40
|
+
* when: 'No items match the query',
|
|
41
|
+
* recovery: 'Broaden the query or check the spelling and try again.' },
|
|
40
42
|
* { reason: 'rate_limited', code: JsonRpcErrorCode.RateLimited,
|
|
41
|
-
* when: 'Upstream rate limit hit', retryable: true
|
|
43
|
+
* when: 'Upstream rate limit hit', retryable: true,
|
|
44
|
+
* recovery: 'Wait a few seconds before retrying or reduce request frequency.' },
|
|
42
45
|
* ],
|
|
43
46
|
* input: z.object({ query: z.string().describe('Search query') }),
|
|
44
47
|
* output: z.object({ items: z.array(z.string()).describe('Matched items') }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6IH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E
|
|
1
|
+
{"version":3,"file":"toolDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6IH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,UAAU,IAAI,CAKlB,IAAY,EACZ,OAA+D;IAE/D,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -136,11 +136,14 @@ export type ErrorResponse = z.infer<typeof ErrorSchema>;
|
|
|
136
136
|
* // ...
|
|
137
137
|
* errors: [
|
|
138
138
|
* { code: JsonRpcErrorCode.NotFound, reason: 'no_pmid_match',
|
|
139
|
-
* when: 'None of the requested PMIDs returned data.'
|
|
139
|
+
* when: 'None of the requested PMIDs returned data.',
|
|
140
|
+
* recovery: 'Try pubmed_search_articles to discover valid PMIDs first.' },
|
|
140
141
|
* { code: JsonRpcErrorCode.RateLimited, reason: 'queue_full',
|
|
141
|
-
* when: 'Local request queue is at capacity.', retryable: true
|
|
142
|
+
* when: 'Local request queue is at capacity.', retryable: true,
|
|
143
|
+
* recovery: 'Wait 30 seconds and retry, or reduce batch size.' },
|
|
142
144
|
* { code: JsonRpcErrorCode.ServiceUnavailable, reason: 'ncbi_down',
|
|
143
|
-
* when: 'NCBI E-utilities is unreachable after 6 retries.', retryable: true
|
|
145
|
+
* when: 'NCBI E-utilities is unreachable after 6 retries.', retryable: true,
|
|
146
|
+
* recovery: 'NCBI is degraded; retry in a few minutes.' },
|
|
144
147
|
* ],
|
|
145
148
|
* // ...
|
|
146
149
|
* });
|
|
@@ -155,6 +158,24 @@ export interface ErrorContract {
|
|
|
155
158
|
* and treated as part of the public API — clients may switch on it.
|
|
156
159
|
*/
|
|
157
160
|
reason: string;
|
|
161
|
+
/**
|
|
162
|
+
* Human-readable description of what the agent should do when this failure
|
|
163
|
+
* occurs. Forcing function for the author: declaring a failure mode without
|
|
164
|
+
* articulating recovery leaves the agent without a next move.
|
|
165
|
+
*
|
|
166
|
+
* **Type-level only — not auto-injected at runtime.** The contract `recovery`
|
|
167
|
+
* is descriptive metadata read by the linter, scaffolding skills, and dev
|
|
168
|
+
* tools. The wire payload's `data.recovery.hint` (which the framework mirrors
|
|
169
|
+
* into `content[]` text per the error-path parity invariant) is populated
|
|
170
|
+
* separately at the throw site, where dynamic context (input values, attempted
|
|
171
|
+
* IDs, queue state) is available. Authors who want recovery on the wire pass
|
|
172
|
+
* it explicitly: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`.
|
|
173
|
+
*
|
|
174
|
+
* **Validation.** Required, non-empty, minimum 5 words (lint warning under
|
|
175
|
+
* that floor). Specific, actionable guidance beats placeholders like
|
|
176
|
+
* "Try again." or "Check input."
|
|
177
|
+
*/
|
|
178
|
+
recovery: string;
|
|
158
179
|
/**
|
|
159
180
|
* Whether the failure is transient (eligible for retry). Optional hint for
|
|
160
181
|
* clients; when omitted, callers fall back to inferring from the code.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types-global/errors.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types-global/errors.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.8.
|
|
3
|
+
"version": "0.8.4",
|
|
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
|
"main": "dist/core/index.js",
|
|
@@ -163,16 +163,16 @@
|
|
|
163
163
|
},
|
|
164
164
|
"devDependencies": {
|
|
165
165
|
"@biomejs/biome": "2.4.13",
|
|
166
|
-
"@cloudflare/workers-types": "^4.
|
|
166
|
+
"@cloudflare/workers-types": "^4.20260429.1",
|
|
167
167
|
"@hono/otel": "^1.1.1",
|
|
168
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
169
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
170
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
171
|
-
"@opentelemetry/instrumentation-pino": "^0.
|
|
172
|
-
"@opentelemetry/resources": "^2.7.
|
|
173
|
-
"@opentelemetry/sdk-metrics": "^2.7.
|
|
174
|
-
"@opentelemetry/sdk-node": "^0.
|
|
175
|
-
"@opentelemetry/sdk-trace-node": "^2.7.
|
|
168
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.216.0",
|
|
169
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.216.0",
|
|
170
|
+
"@opentelemetry/instrumentation-http": "^0.216.0",
|
|
171
|
+
"@opentelemetry/instrumentation-pino": "^0.62.0",
|
|
172
|
+
"@opentelemetry/resources": "^2.7.1",
|
|
173
|
+
"@opentelemetry/sdk-metrics": "^2.7.1",
|
|
174
|
+
"@opentelemetry/sdk-node": "^0.216.0",
|
|
175
|
+
"@opentelemetry/sdk-trace-node": "^2.7.1",
|
|
176
176
|
"@opentelemetry/semantic-conventions": "^1.40.0",
|
|
177
177
|
"@supabase/supabase-js": "^2.105.1",
|
|
178
178
|
"@types/bun": "^1.3.13",
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
"tsc-alias": "^1.8.16",
|
|
206
206
|
"typedoc": "^0.28.19",
|
|
207
207
|
"typescript": "^6.0.3",
|
|
208
|
-
"unpdf": "^1.6.
|
|
208
|
+
"unpdf": "^1.6.2",
|
|
209
209
|
"validator": "^13.15.35",
|
|
210
210
|
"vite": "8.0.10",
|
|
211
211
|
"vitest": "^4.1.5"
|
package/skills/add-tool/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new MCP tool definition. Use when the user asks to add a tool, create a new tool, or implement a new capability for the server.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -65,9 +65,20 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
|
65
65
|
// (InternalError, ServiceUnavailable, Timeout, ValidationError,
|
|
66
66
|
// SerializationError) bubble freely — only declare domain-specific reasons.
|
|
67
67
|
// Delete this block if no domain failures apply.
|
|
68
|
+
//
|
|
69
|
+
// `recovery` is required (≥ 5 words) — it's the agent's next move when this
|
|
70
|
+
// failure fires. Forcing function for thoughtful guidance: placeholders like
|
|
71
|
+
// "Try again." get flagged by the linter. Contract-level `recovery` is
|
|
72
|
+
// descriptive metadata; for the wire payload's `data.recovery.hint` (which
|
|
73
|
+
// the framework mirrors into content[] text), pass it explicitly at the
|
|
74
|
+
// throw site when dynamic context matters.
|
|
68
75
|
errors: [
|
|
69
|
-
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
70
|
-
|
|
76
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
77
|
+
when: 'No items matched the query.',
|
|
78
|
+
recovery: 'Broaden the query or check the spelling and try again.' },
|
|
79
|
+
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited,
|
|
80
|
+
when: 'Local queue at capacity.', retryable: true,
|
|
81
|
+
recovery: 'Wait a few seconds before retrying or reduce batch size.' },
|
|
71
82
|
],
|
|
72
83
|
|
|
73
84
|
async handler(input, ctx) {
|
|
@@ -277,9 +288,11 @@ export const fetchArticles = tool('fetch_articles', {
|
|
|
277
288
|
description: 'Fetch articles by PMID.',
|
|
278
289
|
errors: [
|
|
279
290
|
{ reason: 'no_pmid_match', code: JsonRpcErrorCode.NotFound,
|
|
280
|
-
when: 'None of the requested PMIDs returned data.'
|
|
291
|
+
when: 'None of the requested PMIDs returned data.',
|
|
292
|
+
recovery: 'Try pubmed_search_articles to discover valid PMIDs first.' },
|
|
281
293
|
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited,
|
|
282
|
-
when: 'Local request queue at capacity.', retryable: true
|
|
294
|
+
when: 'Local request queue at capacity.', retryable: true,
|
|
295
|
+
recovery: 'Wait 30 seconds and retry, or reduce batch size.' },
|
|
283
296
|
],
|
|
284
297
|
input: z.object({ pmids: z.array(z.string()).describe('PMIDs to fetch') }),
|
|
285
298
|
output: z.object({ articles: z.array(ArticleSchema).describe('Resolved articles') }),
|
|
@@ -326,7 +339,8 @@ export class NcbiService {
|
|
|
326
339
|
export const fetchArticles = tool('fetch_articles', {
|
|
327
340
|
errors: [
|
|
328
341
|
{ reason: 'ncbi_unreachable', code: JsonRpcErrorCode.ServiceUnavailable,
|
|
329
|
-
when: 'NCBI E-utilities is unreachable.', retryable: true
|
|
342
|
+
when: 'NCBI E-utilities is unreachable.', retryable: true,
|
|
343
|
+
recovery: 'NCBI is degraded; retry in a few minutes.' },
|
|
330
344
|
],
|
|
331
345
|
async handler(input, ctx) {
|
|
332
346
|
return { articles: await ncbi.fetch(input.pmids) }; // throws bubble unchanged
|
|
@@ -354,15 +368,23 @@ throw notFound(
|
|
|
354
368
|
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
355
369
|
throw serviceUnavailable(`arXiv API returned HTTP ${status}. Retry in a few seconds.`);
|
|
356
370
|
|
|
357
|
-
//
|
|
371
|
+
// Recovery hint via the canonical `data.recovery.hint` shape — the framework
|
|
372
|
+
// auto-mirrors it into the content[] text as `Recovery: <hint>`, so format()-only
|
|
373
|
+
// clients (Claude Desktop) see the same guidance that structuredContent clients
|
|
374
|
+
// (Claude Code) read from `error.data.recovery.hint`. Other `data` keys reach
|
|
375
|
+
// structuredContent only.
|
|
358
376
|
import { invalidParams } from '@cyanheads/mcp-ts-core/errors';
|
|
359
377
|
throw invalidParams(
|
|
360
|
-
`Date range exceeds 90-day API limit
|
|
361
|
-
{
|
|
378
|
+
`Date range exceeds 90-day API limit.`,
|
|
379
|
+
{
|
|
380
|
+
maxDays: 90,
|
|
381
|
+
requestedDays: daysBetween,
|
|
382
|
+
recovery: { hint: 'Narrow the range or split into multiple queries.' },
|
|
383
|
+
},
|
|
362
384
|
);
|
|
363
385
|
```
|
|
364
386
|
|
|
365
|
-
**Error messages are recovery instructions.** Name what went wrong, why, and what action to take. The message is the agent's only signal — a bare "Not found" is a dead end. See `skills/api-errors/SKILL.md` for the full contract pattern, factories list,
|
|
387
|
+
**Error messages are recovery instructions.** Name what went wrong, why, and what action to take. The message is the agent's only signal — a bare "Not found" is a dead end. See `skills/api-errors/SKILL.md` for the full contract pattern, factories list, auto-classification table, and error-path parity (how `data.recovery.hint` reaches both client surfaces).
|
|
366
388
|
|
|
367
389
|
### Include operational metadata
|
|
368
390
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
McpError constructor, JsonRpcErrorCode reference, and error handling patterns for `@cyanheads/mcp-ts-core`. Use when looking up error codes, understanding where errors should be thrown vs. caught, or using ErrorHandler.tryCatch in services.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.2"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -37,11 +37,14 @@ export const fetchTool = tool('fetch_articles', {
|
|
|
37
37
|
|
|
38
38
|
errors: [
|
|
39
39
|
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
40
|
-
when: 'No requested PMID returned data'
|
|
40
|
+
when: 'No requested PMID returned data',
|
|
41
|
+
recovery: 'Try pubmed_search_articles to discover valid PMIDs first.' },
|
|
41
42
|
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited,
|
|
42
|
-
when: 'Local request queue is at capacity', retryable: true
|
|
43
|
+
when: 'Local request queue is at capacity', retryable: true,
|
|
44
|
+
recovery: 'Wait 30 seconds and retry, or reduce batch size.' },
|
|
43
45
|
{ reason: 'ncbi_down', code: JsonRpcErrorCode.ServiceUnavailable,
|
|
44
|
-
when: 'NCBI E-utilities unreachable after retries', retryable: true
|
|
46
|
+
when: 'NCBI E-utilities unreachable after retries', retryable: true,
|
|
47
|
+
recovery: 'NCBI is degraded; retry in a few minutes.' },
|
|
45
48
|
],
|
|
46
49
|
|
|
47
50
|
async handler(input, ctx) {
|
|
@@ -61,9 +64,11 @@ export const fetchTool = tool('fetch_articles', {
|
|
|
61
64
|
|:--------|:---------|
|
|
62
65
|
| Compile time | `ctx.fail('typo')` is a TS error. Auto-completes declared reasons. |
|
|
63
66
|
| Runtime | `ctx.fail(reason, msg?, data?, options?)` builds an `McpError(contract.code, msg, { ...data, reason }, options)` — `data.reason` is auto-populated from the contract and cannot be overridden by caller-supplied data (spread first, then `reason` written last), so observers see a stable identifier. `options` accepts `{ cause }` for ES2022 error chaining. |
|
|
64
|
-
| Lint (startup) | Each `code` validated against `JsonRpcErrorCode`. Reasons validated as snake_case + unique within contract. |
|
|
67
|
+
| Lint (startup) | Each `code` validated against `JsonRpcErrorCode`. Reasons validated as snake_case + unique within contract. `recovery` validated as non-empty and ≥ 5 words. |
|
|
65
68
|
| Lint (conformance) | If the handler `throw new McpError(JsonRpcErrorCode.X)` outside `ctx.fail`, conformance check warns when X isn't declared. |
|
|
66
69
|
|
|
70
|
+
> **`recovery` is descriptive, not auto-injected.** The contract `recovery` is required metadata documenting the agent's next move when this failure mode fires (a forcing function for thoughtful guidance — placeholders like "Try again." get flagged by the linter). It is **not** auto-populated into runtime `data.recovery.hint`. The wire payload's recovery hint — which the framework mirrors into `content[]` text per the [error-path parity](#error-path-parity) invariant — is populated separately at the throw site, where dynamic context (input values, attempted IDs, queue state) is available: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`. The two fields can carry the same string when no dynamic context is needed; they're decoupled by design — what the author writes at the throw site is what flows to the wire, with no hidden transformation.
|
|
71
|
+
|
|
67
72
|
**Skip the contract** for one-off internal tools or quick prototypes — `ctx` is plain `Context` (no `fail`) and you throw via [factories](#error-factories-fallback) directly. Behavior is identical at the wire; the contract just adds compile-time safety.
|
|
68
73
|
|
|
69
74
|
> **Limits of the conformance lint.** The conformance and prefer-fail rules scan the handler's source text for `throw` statements. Errors thrown from called services (e.g. `await myService.fetch()` raising `RateLimited` internally) are invisible — the lint only sees what's lexically in the handler. Treat the contract as the *advertised* failure surface; bubbled-up codes still reach the client correctly via the auto-classifier, just without lint enforcement.
|
|
@@ -81,8 +86,12 @@ throw serviceUnavailable('Upstream timeout', { reason: 'evaluation_time
|
|
|
81
86
|
```ts
|
|
82
87
|
// my-tool.tool.ts
|
|
83
88
|
errors: [
|
|
84
|
-
{ reason: 'empty_expression', code: JsonRpcErrorCode.ValidationError,
|
|
85
|
-
|
|
89
|
+
{ reason: 'empty_expression', code: JsonRpcErrorCode.ValidationError,
|
|
90
|
+
when: 'Input is empty.',
|
|
91
|
+
recovery: 'Provide a non-empty expression to evaluate.' },
|
|
92
|
+
{ reason: 'evaluation_timeout', code: JsonRpcErrorCode.ServiceUnavailable,
|
|
93
|
+
when: 'Upstream exceeded the configured timeout.',
|
|
94
|
+
recovery: 'Simplify the expression or retry the request after a brief delay.' },
|
|
86
95
|
]
|
|
87
96
|
```
|
|
88
97
|
|
|
@@ -416,6 +425,9 @@ The linter validates the structure of `errors[]` and (when present) cross-checks
|
|
|
416
425
|
| `error-contract-reason-format` | warning | `reason` not snake_case |
|
|
417
426
|
| `error-contract-reason-unique` | error | Duplicate `reason` within one contract |
|
|
418
427
|
| `error-contract-when-required` | error | `when` missing or empty |
|
|
428
|
+
| `error-contract-recovery-required` | error | `recovery` missing or not a string |
|
|
429
|
+
| `error-contract-recovery-empty` | error | `recovery` is empty/whitespace-only |
|
|
430
|
+
| `error-contract-recovery-min-words` | warning | `recovery` has fewer than 5 words — placeholders like "Try again." or "Check input." get flagged in favor of specific guidance |
|
|
419
431
|
| `error-contract-retryable-type` | warning | `retryable` is present but not a boolean |
|
|
420
432
|
|
|
421
433
|
### Conformance rules
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Design the tool surface, resources, and service layer for a new MCP server. Use when starting a new server, planning a major feature expansion, or when the user describes a domain/API they want to expose via MCP. Produces a design doc at docs/design.md that drives implementation.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "2.
|
|
7
|
+
version: "2.8"
|
|
8
8
|
audience: external
|
|
9
9
|
type: workflow
|
|
10
10
|
---
|
|
@@ -346,10 +346,17 @@ throw new Error('Not found');
|
|
|
346
346
|
// Good — names both resolution options
|
|
347
347
|
"No session working directory set. Please specify a 'path' or use 'git_set_working_dir' first."
|
|
348
348
|
|
|
349
|
-
// Good — structured hint in error data
|
|
349
|
+
// Good — structured hint in error data using the canonical `data.recovery.hint` shape.
|
|
350
|
+
// The framework auto-mirrors `data.recovery.hint` into the content[] text as
|
|
351
|
+
// `Recovery: <hint>` so format()-only clients (Claude Desktop) see the same
|
|
352
|
+
// guidance structuredContent clients (Claude Code) read from `error.data.recovery.hint`.
|
|
350
353
|
throw forbidden(
|
|
351
354
|
"Cannot perform 'reset --hard' on protected branch 'main' without explicit confirmation.",
|
|
352
|
-
{
|
|
355
|
+
{
|
|
356
|
+
branch: 'main',
|
|
357
|
+
operation: 'reset --hard',
|
|
358
|
+
recovery: { hint: 'Set the confirmed parameter to true to proceed.' },
|
|
359
|
+
},
|
|
353
360
|
);
|
|
354
361
|
|
|
355
362
|
// Good — upstream error with actionable context
|
package/templates/AGENTS.md
CHANGED
|
@@ -168,11 +168,13 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
168
168
|
|
|
169
169
|
Handlers throw — the framework catches, classifies, and formats.
|
|
170
170
|
|
|
171
|
-
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, retryable? }]` on `tool()` / `resource()` to receive a typed `ctx.fail(reason, …)` keyed by the declared reason union. TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated for observability, and the linter enforces conformance against the handler body. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
171
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive a typed `ctx.fail(reason, …)` keyed by the declared reason union. TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated for observability, and the linter enforces conformance against the handler body. The `recovery` field is required descriptive metadata for the agent's next move (≥ 5 words, lint-validated); for the wire payload's `data.recovery.hint` (which the framework mirrors into `content[]` text), pass it explicitly at the throw site when dynamic context matters: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
172
172
|
|
|
173
173
|
```ts
|
|
174
174
|
errors: [
|
|
175
|
-
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
175
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
176
|
+
when: 'No item matched the query',
|
|
177
|
+
recovery: 'Broaden the query or check the spelling and try again.' },
|
|
176
178
|
],
|
|
177
179
|
async handler(input, ctx) {
|
|
178
180
|
const item = await db.find(input.id);
|
package/templates/CLAUDE.md
CHANGED
|
@@ -168,11 +168,13 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
168
168
|
|
|
169
169
|
Handlers throw — the framework catches, classifies, and formats.
|
|
170
170
|
|
|
171
|
-
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, retryable? }]` on `tool()` / `resource()` to receive a typed `ctx.fail(reason, …)` keyed by the declared reason union. TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated for observability, and the linter enforces conformance against the handler body. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
171
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()` to receive a typed `ctx.fail(reason, …)` keyed by the declared reason union. TypeScript catches `ctx.fail('typo')` at compile time, `data.reason` is auto-populated for observability, and the linter enforces conformance against the handler body. The `recovery` field is required descriptive metadata for the agent's next move (≥ 5 words, lint-validated); for the wire payload's `data.recovery.hint` (which the framework mirrors into `content[]` text), pass it explicitly at the throw site when dynamic context matters: `ctx.fail('reason', msg, { recovery: { hint: '...' } })`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring.
|
|
172
172
|
|
|
173
173
|
```ts
|
|
174
174
|
errors: [
|
|
175
|
-
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
175
|
+
{ reason: 'no_match', code: JsonRpcErrorCode.NotFound,
|
|
176
|
+
when: 'No item matched the query',
|
|
177
|
+
recovery: 'Broaden the query or check the spelling and try again.' },
|
|
176
178
|
],
|
|
177
179
|
async handler(input, ctx) {
|
|
178
180
|
const item = await db.find(input.id);
|
|
@@ -28,6 +28,7 @@ export const echoTool = tool('template_echo_message', {
|
|
|
28
28
|
reason: 'empty_message',
|
|
29
29
|
code: JsonRpcErrorCode.InvalidParams,
|
|
30
30
|
when: 'Message contained only whitespace.',
|
|
31
|
+
recovery: 'Provide a message with at least one non-whitespace character.',
|
|
31
32
|
},
|
|
32
33
|
],
|
|
33
34
|
|