@cyanheads/mcp-ts-core 0.13.9 → 0.13.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +36 -13
- package/CLAUDE.md +36 -13
- package/README.md +9 -9
- package/changelog/0.13.x/0.13.10.md +118 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +15 -1
- package/dist/core/app.js.map +1 -1
- package/dist/core/context.d.ts +89 -20
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +40 -0
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/worker.d.ts +6 -0
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +1 -0
- package/dist/core/worker.js.map +1 -1
- package/dist/linter/rules/error-contract-rules.d.ts +3 -44
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -1
- package/dist/linter/rules/error-contract-rules.js +8 -144
- package/dist/linter/rules/error-contract-rules.js.map +1 -1
- package/dist/linter/rules/index.d.ts +1 -1
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +1 -1
- 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 +1 -2
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +1 -2
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/mcp-server/handlerContext.d.ts +26 -13
- package/dist/mcp-server/handlerContext.d.ts.map +1 -1
- package/dist/mcp-server/handlerContext.js +32 -17
- package/dist/mcp-server/handlerContext.js.map +1 -1
- package/dist/mcp-server/inputRequired.d.ts +120 -8
- package/dist/mcp-server/inputRequired.d.ts.map +1 -1
- package/dist/mcp-server/inputRequired.js +177 -12
- package/dist/mcp-server/inputRequired.js.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.d.ts +10 -2
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -1
- package/dist/mcp-server/prompts/prompt-registration.js +49 -11
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +4 -2
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +6 -4
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +4 -3
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +42 -14
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts +9 -0
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +14 -13
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +7 -3
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +9 -5
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +17 -9
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +91 -50
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +7 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/testing/index.d.ts +17 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +21 -7
- package/dist/testing/index.js.map +1 -1
- package/dist/types-global/errors.d.ts +18 -15
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.d.ts +5 -4
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/error-handler/errorHandler.js +9 -7
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -1
- package/dist/utils/internal/error-handler/types.d.ts +3 -1
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -1
- package/dist/utils/internal/performance.d.ts +4 -2
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +8 -6
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/telemetryMessages.d.ts +0 -1
- package/dist/utils/internal/telemetryMessages.d.ts.map +1 -1
- package/dist/utils/internal/telemetryMessages.js +0 -1
- package/dist/utils/internal/telemetryMessages.js.map +1 -1
- package/dist/utils/telemetry/attributes.d.ts +5 -4
- package/dist/utils/telemetry/attributes.d.ts.map +1 -1
- package/dist/utils/telemetry/attributes.js +5 -4
- package/dist/utils/telemetry/attributes.js.map +1 -1
- package/framework-skills/add-service/SKILL.md +3 -12
- package/framework-skills/add-test/SKILL.md +6 -3
- package/framework-skills/add-tool/SKILL.md +29 -33
- package/framework-skills/api-config/SKILL.md +2 -1
- package/framework-skills/api-context/SKILL.md +155 -40
- package/framework-skills/api-errors/SKILL.md +43 -47
- package/framework-skills/api-linter/SKILL.md +5 -29
- package/framework-skills/api-telemetry/SKILL.md +11 -7
- package/framework-skills/api-testing/SKILL.md +43 -11
- package/framework-skills/api-workers/SKILL.md +3 -1
- package/framework-skills/design-mcp-server/SKILL.md +5 -5
- package/framework-skills/field-test/SKILL.md +2 -2
- package/framework-skills/polish-docs-meta/SKILL.md +2 -2
- package/framework-skills/release-and-publish/SKILL.md +3 -3
- package/framework-skills/release-pr-review/SKILL.md +2 -2
- package/framework-skills/security-pass/SKILL.md +8 -7
- package/package.json +4 -3
- package/scripts/install-otel.ts +84 -0
- package/scripts/lint-packaging.ts +188 -27
- package/templates/.env.example +2 -0
- package/templates/AGENTS.md +5 -4
- package/templates/CLAUDE.md +5 -4
- package/templates/Dockerfile +67 -50
- package/templates/src/mcp-server/tools/definitions/echo.tool.ts +3 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../../../src/utils/telemetry/attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a new service integration. Use when the user asks to add a service, integrate an external API, or create a reusable domain module with its own initialization and state.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.12"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -231,7 +231,7 @@ Services don't declare `errors: [...]` contracts and don't have `ctx.fail` — t
|
|
|
231
231
|
```
|
|
232
232
|
|
|
233
233
|
- **Tool/resource handlers bubble service errors unchanged** — the contract advertises the *advertised* failure surface, and any code thrown from a service still reaches the client correctly via the auto-classifier. The conformance lint scans handler source text only, so service-thrown codes aren't flagged.
|
|
234
|
-
- **Carry contract `reason` via `data: { reason }`** when the calling tool declares an `errors[]` contract entry for this failure mode. Services can't call `ctx.fail`, but passing the reason in `data` flows through the auto-classifier untouched, so clients see the same `error.data.reason` they'd see from `ctx.fail` —
|
|
234
|
+
- **Carry contract `reason` via `data: { reason }`** when the calling tool declares an `errors[]` contract entry for this failure mode. Services can't call `ctx.fail`, but passing the reason in `data` flows through the auto-classifier untouched, so clients see the same `error.data.reason` they'd see from `ctx.fail` — and the framework fills that entry's `recovery` as `data.recovery.hint` when the throw carries none. No handler-side catch-and-rethrow needed:
|
|
235
235
|
|
|
236
236
|
```ts
|
|
237
237
|
// tool declares: errors: [{ reason: 'empty_expression', code: JsonRpcErrorCode.ValidationError,
|
|
@@ -241,16 +241,7 @@ Services don't declare `errors: [...]` contracts and don't have `ctx.fail` — t
|
|
|
241
241
|
|
|
242
242
|
The tool's entry carries `thrownBy: 'service'` so `error-contract-unthrown` — which reads the handler body and cannot see this throw — skips it while still checking whatever the handler throws itself. Lint-only metadata; nothing at runtime reads it.
|
|
243
243
|
|
|
244
|
-
- **
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
throw validationError('Parse failed: ' + err.message, {
|
|
248
|
-
reason: 'parse_failed',
|
|
249
|
-
...ctx.recoveryFor('parse_failed'), // resolves from caller's contract
|
|
250
|
-
});
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
The contract `recovery` (validated ≥5 words at lint time) is the single source of truth. Services that opt in via the resolver carry the same hint to the wire that handler-level `ctx.fail` callers do — no drift, no auto-population. For dynamic recovery (interpolating runtime values into the hint), pass an explicit `{ recovery: { hint: '…' } }` instead.
|
|
244
|
+
- **The contract `recovery` follows the reason.** The calling tool's declared `recovery` (validated ≥5 words at lint time) is the single source of truth, and the handler factory puts it on the wire for any failure carrying that reason — matched on the reason alone, whatever factory the service picked — so a service throw needs nothing beyond `{ reason }`. For dynamic recovery (interpolating runtime values into the hint), pass an explicit `{ recovery: { hint: '…' } }`, which always wins.
|
|
254
245
|
|
|
255
246
|
## API Efficiency
|
|
256
247
|
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Scaffold a test file for an existing tool, resource, or service. Use when the user asks to add tests, improve coverage, or when a definition exists without a matching test file.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.8"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -36,7 +36,8 @@ Read the handler and identify:
|
|
|
36
36
|
| **Input variations** | Optional fields omitted, defaults applied, boundary values |
|
|
37
37
|
| **Error paths** | Invalid state, missing resources, service failures → correct error thrown |
|
|
38
38
|
| **`ctx.state` usage** | Available on any mock context (tenant `'default'` unless `{ tenantId }` says otherwise). It runs the production storage path, so use storage-legal keys (`cache/v1/abc`, never `cache:v1:abc`) and assert TTL expiry with fake timers. |
|
|
39
|
-
| **`ctx.requestInput` / `ctx.inputs`** | Two rounds. First round: assert the handler throws the input-required signal (`.rejects.toSatisfy(isInputRequiredSignal)`), or catch it and assert on `error.result.inputRequests`. Second round: seed `createMockContext({ inputResponses })` and assert the handler completes. Cover the decline/cancel branch too. |
|
|
39
|
+
| **`ctx.requestInput` / `ctx.inputs`** | Two rounds. First round: assert the handler throws the input-required signal (`.rejects.toSatisfy(isInputRequiredSignal)`), or catch it and assert on `error.result.inputRequests`. Second round: seed `createMockContext({ inputResponses })` and assert the handler completes. Cover the decline/cancel branch too. A consent gate that redeems a `ctx.state` record also needs that record written into the second round's context, and a replay case showing the spent record asks again (see `api-testing` § Mock inputs). |
|
|
40
|
+
| **`ctx.clientCapabilities`** | When the handler asks only if the client declared a capability, seed `createMockContext({ clientCapabilities })` with and without it and assert it asks in one case and falls through in the other. Seeding it also filters `inputResponses` to the declared kinds, as production does. |
|
|
40
41
|
| **`ctx.signal`** | Pass `createMockContext({ signal: controller.signal })` and assert a long loop stops early rather than running to completion. |
|
|
41
42
|
| **`ctx.fail` (typed contract)** | Definitions with `errors[]` need `fail` attached to the mock ctx — `createMockContext({ errors: myTool.errors })` does it for you. Assert on `data.reason` (stable per-contract entry), not just `code`. |
|
|
42
43
|
| **`format` function** | Test separately if defined — it's pure, no ctx needed. Verify it renders the IDs and fields the model needs, not just a count or title. For projection-style tools, test non-default field selections. |
|
|
@@ -222,6 +223,8 @@ it('does not re-ask after a decline', async () => {
|
|
|
222
223
|
});
|
|
223
224
|
```
|
|
224
225
|
|
|
226
|
+
For a destructive consent gate, the second round completes only when the context holds the single-use record the first round stored, keyed by the `requestState` it returned — each mock context has its own `ctx.state`, so write the record into the second context before calling the handler. `api-testing` § Mock inputs has the full pattern, including the replay case.
|
|
227
|
+
|
|
225
228
|
### Cancellation test
|
|
226
229
|
|
|
227
230
|
```typescript
|
|
@@ -308,7 +311,7 @@ When scaffolding tests for an existing handler, use the Zod schemas to generate
|
|
|
308
311
|
- [ ] Happy path tested with valid input → expected output
|
|
309
312
|
- [ ] Error paths tested (at least one `.rejects.toThrow()`)
|
|
310
313
|
- [ ] `format` function tested if defined
|
|
311
|
-
- [ ] `createMockContext` options match handler's ctx usage (`tenantId`, `inputResponses`, `requestState`, `errors`, `signal`)
|
|
314
|
+
- [ ] `createMockContext` options match handler's ctx usage (`tenantId`, `inputResponses`, `requestState`, `clientCapabilities`, `errors`, `signal`)
|
|
312
315
|
- [ ] Service re-initialized in `beforeEach` if handler depends on a service singleton
|
|
313
316
|
- [ ] If handler has optional fields: tested with empty-string inner values (form-client simulation)
|
|
314
317
|
- [ ] If wrapping external API: sparse-payload case tested — fixture omits at least one optional upstream field; output still validates and `format()` renders uncertainty honestly instead of inventing values
|
|
@@ -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.32"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -80,8 +80,8 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
|
80
80
|
// `recovery` is required (≥ 5 words) — it's the agent's next move when this
|
|
81
81
|
// failure fires. Forcing function for thoughtful guidance: placeholders like
|
|
82
82
|
// "Try again." get flagged by the linter. The contract `recovery` is the
|
|
83
|
-
// single source of truth for what flows to the wire —
|
|
84
|
-
//
|
|
83
|
+
// single source of truth for what flows to the wire — the framework sends it
|
|
84
|
+
// with any failure carrying the reason and no hint of its own.
|
|
85
85
|
errors: [
|
|
86
86
|
{ reason: 'queue_full', code: JsonRpcErrorCode.RateLimited,
|
|
87
87
|
when: 'Local queue at capacity.', retryable: true,
|
|
@@ -95,10 +95,9 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
|
95
95
|
// Without: throw via factories (`notFound`, `validationError`, …) or plain `Error`.
|
|
96
96
|
const items = await search(input);
|
|
97
97
|
if (queue.full()) {
|
|
98
|
-
// Static recovery —
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
throw ctx.fail('queue_full', undefined, { ...ctx.recoveryFor('queue_full') });
|
|
98
|
+
// Static recovery — the string lives in errors[] above, and the framework
|
|
99
|
+
// puts it on both client surfaces as `data.recovery.hint`.
|
|
100
|
+
throw ctx.fail('queue_full');
|
|
102
101
|
}
|
|
103
102
|
// Surface what the agent reasons with — echoed query, true total — on BOTH
|
|
104
103
|
// client surfaces, with no format() plumbing. An empty result is a notice,
|
|
@@ -137,29 +136,25 @@ A handler that needs something the caller didn't supply returns `ctx.requestInpu
|
|
|
137
136
|
import { inputRequired, tool, z } from '@cyanheads/mcp-ts-core';
|
|
138
137
|
import { validationError } from '@cyanheads/mcp-ts-core/errors';
|
|
139
138
|
|
|
140
|
-
const
|
|
139
|
+
const Choice = z.object({ region: z.enum(['us', 'eu']).describe('Region to deploy to.') });
|
|
141
140
|
|
|
142
141
|
export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
143
142
|
description: '{{TOOL_DESCRIPTION}}',
|
|
144
143
|
input: z.object({ /* ... */ }),
|
|
145
144
|
output: z.object({ /* ... */ }),
|
|
146
|
-
annotations: { destructiveHint: true },
|
|
147
145
|
|
|
148
146
|
handler(input, ctx) {
|
|
147
|
+
// A declined or cancelled prompt is a dead end — don't re-ask it.
|
|
148
|
+
const view = ctx.inputs.view('region');
|
|
149
|
+
if (view.kind === 'elicit' && view.action !== 'accept') {
|
|
150
|
+
throw validationError(`User ${view.action} the region prompt.`);
|
|
151
|
+
}
|
|
149
152
|
// Read what a prior round collected before asking for anything.
|
|
150
|
-
const answer = ctx.inputs.accepted('
|
|
153
|
+
const answer = ctx.inputs.accepted('region', Choice);
|
|
151
154
|
if (!answer) {
|
|
152
|
-
// A declined or cancelled prompt is a dead end — don't re-ask it.
|
|
153
|
-
const view = ctx.inputs.view('confirm');
|
|
154
|
-
if (view.kind === 'elicit' && view.action !== 'accept') {
|
|
155
|
-
throw validationError(`User ${view.action} the confirmation.`);
|
|
156
|
-
}
|
|
157
155
|
return ctx.requestInput({
|
|
158
156
|
inputRequests: {
|
|
159
|
-
|
|
160
|
-
message: `Proceed with ${input.target}?`,
|
|
161
|
-
requestedSchema: Confirm,
|
|
162
|
-
}),
|
|
157
|
+
region: inputRequired.elicit({ message: 'Which region?', requestedSchema: Choice }),
|
|
163
158
|
},
|
|
164
159
|
});
|
|
165
160
|
}
|
|
@@ -169,6 +164,8 @@ export const {{TOOL_EXPORT}} = tool('{{tool_name}}', {
|
|
|
169
164
|
});
|
|
170
165
|
```
|
|
171
166
|
|
|
167
|
+
**A confirmation before a destructive step is different.** `ctx.inputs` only carries response kinds the client declared, but a client that declared `elicitation` can still send an "accepted" answer on a call nothing asked, and any `requestState` replays within its lifetime. A consent gate stores `{ operation, clientId, subject, target, contentHash }` in `ctx.state` under a random id, sends only that id as `requestState`, redeems the record before anything else in the handler, and asks again on an unknown, used, or expired id or on any field that differs from this call — the full handler, and the concurrency limit an action that must not repeat has to design around, are in `api-context` § *Consent gates*. Pair it with `MCP_REQUEST_STATE_KEY` so a retry can only carry state this server minted.
|
|
168
|
+
|
|
172
169
|
Write it as `return ctx.requestInput(...)` — the `never` return type makes it valid in return position for any output, and it is what lets TypeScript narrow the line below. Full reference (`inputRequired.elicitUrl` / `.createMessage` / `.listRoots`, `requestState`, decline handling): `framework-skills/api-context`.
|
|
173
170
|
|
|
174
171
|
### Registration
|
|
@@ -657,10 +654,9 @@ export const fetchArticles = tool('fetch_articles', {
|
|
|
657
654
|
input: z.object({ pmids: z.array(z.string()).describe('PMIDs to fetch') }),
|
|
658
655
|
output: z.object({ articles: z.array(ArticleSchema).describe('Resolved articles') }),
|
|
659
656
|
async handler(input, ctx) {
|
|
660
|
-
// Static recovery —
|
|
661
|
-
//
|
|
662
|
-
|
|
663
|
-
if (queue.full()) throw ctx.fail('queue_full', undefined, { ...ctx.recoveryFor('queue_full') });
|
|
657
|
+
// Static recovery — the framework fills the contract recovery onto the wire,
|
|
658
|
+
// mirrored into content[] text for format()-only clients.
|
|
659
|
+
if (queue.full()) throw ctx.fail('queue_full');
|
|
664
660
|
|
|
665
661
|
const articles = await fetch(input.pmids);
|
|
666
662
|
if (articles.length === 0) {
|
|
@@ -675,7 +671,7 @@ export const fetchArticles = tool('fetch_articles', {
|
|
|
675
671
|
});
|
|
676
672
|
```
|
|
677
673
|
|
|
678
|
-
|
|
674
|
+
**The declared `recovery` reaches the wire on its own.** When a failure whose `data.reason` names a contract entry leaves the handler without `data.recovery`, the framework sets `data.recovery.hint` to that entry's `recovery` — both client surfaces, the error log record, and `runToolContract` alike — whatever code it was thrown with. Pass `{ recovery: { hint: \`…${dynamic}…\` } }` when you need runtime context; a throw-site hint always wins. `ctx.recoveryFor(reason)` still resolves the entry into `{ recovery: { hint } }` for a hint that must ride the thrown error itself. The contract is the single source of truth — write the recovery once, lint validates it ≥5 words, the framework carries it to every failure with that reason.
|
|
679
675
|
|
|
680
676
|
**Baseline codes** (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely and don't need declaring. Wire-level behavior is identical when the contract is omitted, but you lose the type-checked `ctx.fail`, the `tools/list` advertisement, and conformance lint coverage — declare a contract whenever the tool has a domain-specific failure mode.
|
|
681
677
|
|
|
@@ -683,12 +679,12 @@ export const fetchArticles = tool('fetch_articles', {
|
|
|
683
679
|
|
|
684
680
|
#### Service-layer throws
|
|
685
681
|
|
|
686
|
-
API-wrapping tools usually delegate to a service: `await ncbi.fetch(input, ctx)`. The throw lives in the service, not the handler. Services accept `ctx` (the unified Context) so they can call `ctx.log`, `ctx.
|
|
682
|
+
API-wrapping tools usually delegate to a service: `await ncbi.fetch(input, ctx)`. The throw lives in the service, not the handler. Services accept `ctx` (the unified Context) so they can call `ctx.log`, `ctx.state`, etc. The handler doesn't catch — it just bubbles, and the framework's auto-classifier preserves `data` on the wire.
|
|
687
683
|
|
|
688
|
-
The contract entry on the tool and the `data: { reason }` on the service throw need to use the **same reason string** so the two sides line up.
|
|
684
|
+
The contract entry on the tool and the `data: { reason }` on the service throw need to use the **same reason string** so the two sides line up. That reason is all it takes: the framework fills the calling tool's declared `recovery` onto the failure as it leaves the handler.
|
|
689
685
|
|
|
690
686
|
```typescript
|
|
691
|
-
// service — receives ctx; passes data.reason
|
|
687
|
+
// service — receives ctx; passes data.reason
|
|
692
688
|
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
693
689
|
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
694
690
|
|
|
@@ -697,9 +693,8 @@ export class NcbiService {
|
|
|
697
693
|
const response = await fetchWithRetry(...);
|
|
698
694
|
if (!response.ok) {
|
|
699
695
|
throw serviceUnavailable(`NCBI returned HTTP ${response.status}`, {
|
|
700
|
-
reason: 'ncbi_unreachable',
|
|
696
|
+
reason: 'ncbi_unreachable', // the caller's declared recovery is filled from this
|
|
701
697
|
status: response.status,
|
|
702
|
-
...ctx.recoveryFor('ncbi_unreachable'), // resolves from caller's contract
|
|
703
698
|
});
|
|
704
699
|
}
|
|
705
700
|
return response.json();
|
|
@@ -719,7 +714,7 @@ export const fetchArticles = tool('fetch_articles', {
|
|
|
719
714
|
});
|
|
720
715
|
```
|
|
721
716
|
|
|
722
|
-
|
|
717
|
+
A tool that declares no matching entry gets no hint — the service doesn't have to know which tool called it.
|
|
723
718
|
|
|
724
719
|
Add `thrownBy: 'service'` to a contract entry the service produces once the handler also throws one of its own. `error-contract-unthrown` reads the handler body alone: as soon as one literal `ctx.fail(` appears there, every declared reason the body does not name is flagged, and the marker is what tells the rule this one is thrown a layer down. Lint-only metadata — the entry stays typed, advertised, and thrown exactly as an unmarked one.
|
|
725
720
|
|
|
@@ -748,8 +743,9 @@ throw serviceUnavailable(`arXiv API returned HTTP ${status}. Retry in a few seco
|
|
|
748
743
|
// clients (Claude Desktop) see the same guidance that structuredContent clients
|
|
749
744
|
// (Claude Code) read from `error.data.recovery.hint`. A hint the message already
|
|
750
745
|
// contains verbatim is dropped from the text rather than stated twice; it stays
|
|
751
|
-
// on structuredContent regardless. `data.reason
|
|
752
|
-
//
|
|
746
|
+
// on structuredContent regardless. `data.reason`, `data.retryable`, and the
|
|
747
|
+
// framework's own `data.requestId` render as a closing
|
|
748
|
+
// `(reason … · not retryable · request <id>)` line; other `data` keys reach
|
|
753
749
|
// structuredContent only.
|
|
754
750
|
import { invalidParams } from '@cyanheads/mcp-ts-core/errors';
|
|
755
751
|
throw invalidParams(
|
|
@@ -886,7 +882,7 @@ return { items: hits };
|
|
|
886
882
|
- [ ] `errors: [...]` contract declared for the tool's domain-specific failure modes — or block deleted if no domain failures apply (baseline codes bubble freely)
|
|
887
883
|
- [ ] Error contract declared inline on this tool — not imported from a shared module, even when other tools have near-identical entries
|
|
888
884
|
- [ ] Long loops check `ctx.signal.aborted` so a cancelled request (or a closed transport) stops the work
|
|
889
|
-
- [ ] If the tool needs caller input it may not have been given: reads `ctx.inputs` first, requests only what is missing via `return ctx.requestInput(...)`, and treats a declined/cancelled response as terminal rather than re-asking
|
|
885
|
+
- [ ] If the tool needs caller input it may not have been given: reads `ctx.inputs` first, requests only what is missing via `return ctx.requestInput(...)`, and treats a declined/cancelled response as terminal rather than re-asking. A destructive confirmation redeems a `ctx.state` consent record bound to the operation, caller, and target (`api-context` § *Consent gates*) rather than trusting the answer alone
|
|
890
886
|
- [ ] If tool returns unbounded arrays: pagination with total count, or `spillover()` / DataCanvas for *analytical* working sets (an agent would SQL them — not a discovery/search surface). If any tool emits a `canvas_id`, a `dataframe_query` tool is registered in the same server — a token with no query tool is dead output
|
|
891
887
|
- [ ] If tool returns one large *document* (not a row set) that can overflow context: `outlineOnOverflow()` returns a `full | outline` union so the agent re-calls with `sections: [...]` — not one-sided truncation
|
|
892
888
|
- [ ] If tool is feature-gated: evaluated whether `disabledTool()` wrapper is appropriate (present in manifest but uncallable)
|
|
@@ -4,7 +4,7 @@ description: >
|
|
|
4
4
|
Reference for core and server configuration in `@cyanheads/mcp-ts-core`. Covers env var tables with defaults, priority order, server-specific Zod schema pattern, and Workers lazy-parsing requirement.
|
|
5
5
|
metadata:
|
|
6
6
|
author: cyanheads
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.23"
|
|
8
8
|
audience: external
|
|
9
9
|
type: reference
|
|
10
10
|
---
|
|
@@ -137,6 +137,7 @@ await createApp({ sessionMode: { default: 'stateful', require: 'stateful' } });
|
|
|
137
137
|
| `MCP_AUTH_MODE` | `mcpAuthMode` | `none` | `none` \| `jwt` \| `oauth` |
|
|
138
138
|
| `MCP_AUTH_SECRET_KEY` | `mcpAuthSecretKey` | — | Required for `jwt` mode; min 32 chars |
|
|
139
139
|
| `MCP_AUTH_DISABLE_SCOPE_CHECKS` | `mcpAuthDisableScopeChecks` | `false` | When `true`, bypasses both `withRequiredScopes` (declared `auth: [...]`) and `checkScopes` (runtime/tenant scopes). Token validation (sig/aud/iss/exp) intact. Logs a `WARNING` at startup. See `api-auth` skill. |
|
|
140
|
+
| `MCP_REQUEST_STATE_KEY` | `mcpRequestStateKey` | — | Opt-in, any auth mode. When set, the framework seals the `requestState` a handler returns with `ctx.requestInput` (bound to the request's `clientId` / `subject` / `tenantId`, valid 900 s) and every server instance rejects any other state as `-32602` `invalid_request_state` before the handler runs; `ctx.inputs.state()` still returns the handler's string. Must be ≥ 32 UTF-8 bytes — shorter fails startup with a `ConfigurationError` naming the variable — and identical on every instance a retry can reach (stateless replicas, Worker isolates, restarts). Unset or empty: no verifier, state round-trips raw. See `api-context` § `requestState` |
|
|
140
141
|
| `OAUTH_ISSUER_URL` | `oauthIssuerUrl` | — | Required for `oauth` mode |
|
|
141
142
|
| `OAUTH_AUDIENCE` | `oauthAudience` | — | Required for `oauth` mode |
|
|
142
143
|
| `OAUTH_JWKS_URI` | `oauthJwksUri` | — | Override JWKS endpoint (otherwise derived from issuer) |
|