@cyanheads/mcp-ts-core 0.12.0 → 0.12.2
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 +7 -3
- package/CLAUDE.md +7 -3
- package/README.md +1 -1
- package/changelog/0.12.x/0.12.1.md +26 -0
- package/changelog/0.12.x/0.12.2.md +29 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +21 -3
- package/dist/config/index.js.map +1 -1
- package/dist/core/app.d.ts +45 -1
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +18 -3
- package/dist/core/app.js.map +1 -1
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/serverManifest.d.ts +11 -2
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/serverManifest.js +30 -12
- package/dist/core/serverManifest.js.map +1 -1
- package/dist/core/worker.d.ts.map +1 -1
- package/dist/core/worker.js +2 -2
- package/dist/core/worker.js.map +1 -1
- package/dist/linter/rules/enrichment-rules.d.ts.map +1 -1
- package/dist/linter/rules/enrichment-rules.js +5 -2
- package/dist/linter/rules/enrichment-rules.js.map +1 -1
- package/dist/linter/rules/portability-rules.d.ts +4 -2
- package/dist/linter/rules/portability-rules.d.ts.map +1 -1
- package/dist/linter/rules/portability-rules.js +33 -4
- package/dist/linter/rules/portability-rules.js.map +1 -1
- package/dist/linter/rules/schema-rules.d.ts +28 -3
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +87 -25
- package/dist/linter/rules/schema-rules.js.map +1 -1
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +9 -3
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/linter/types.d.ts +2 -1
- package/dist/linter/types.d.ts.map +1 -1
- package/dist/logs/combined.log +10 -10
- package/dist/logs/error.log +6 -6
- package/dist/mcp-server/cacheHints.d.ts +35 -0
- package/dist/mcp-server/cacheHints.d.ts.map +1 -0
- package/dist/mcp-server/cacheHints.js +43 -0
- package/dist/mcp-server/cacheHints.js.map +1 -0
- package/dist/mcp-server/notifications.d.ts +68 -1
- package/dist/mcp-server/notifications.d.ts.map +1 -1
- package/dist/mcp-server/notifications.js +67 -0
- package/dist/mcp-server/notifications.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts +2 -2
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +6 -2
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +14 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +13 -5
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +28 -26
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts +16 -1
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +7 -2
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts +2 -2
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +2 -1
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/headerParam.d.ts +113 -0
- package/dist/mcp-server/tools/utils/headerParam.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/headerParam.js +280 -0
- package/dist/mcp-server/tools/utils/headerParam.js.map +1 -0
- package/dist/mcp-server/tools/utils/schemaShape.d.ts +27 -0
- package/dist/mcp-server/tools/utils/schemaShape.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/schemaShape.js +43 -0
- package/dist/mcp-server/tools/utils/schemaShape.js.map +1 -0
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +28 -5
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +22 -3
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +13 -5
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +35 -28
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/mcp-server/transports/http/eventStore.d.ts +57 -0
- package/dist/mcp-server/transports/http/eventStore.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/eventStore.js +114 -0
- package/dist/mcp-server/transports/http/eventStore.js.map +1 -0
- package/dist/mcp-server/transports/http/httpServer.d.ts +2 -1
- package/dist/mcp-server/transports/http/httpServer.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpServer.js +2 -2
- package/dist/mcp-server/transports/http/httpServer.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts +8 -3
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +30 -5
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/landing-page/sections/tools.js +22 -2
- package/dist/mcp-server/transports/http/landing-page/sections/tools.js.map +1 -1
- package/dist/mcp-server/transports/manager.d.ts +10 -1
- package/dist/mcp-server/transports/manager.d.ts.map +1 -1
- package/dist/mcp-server/transports/manager.js +6 -2
- package/dist/mcp-server/transports/manager.js.map +1 -1
- package/dist/mcp-server/types.d.ts +20 -1
- package/dist/mcp-server/types.d.ts.map +1 -1
- package/dist/mcp-server/types.js +14 -0
- package/dist/mcp-server/types.js.map +1 -1
- package/dist/testing/fuzz.d.ts +7 -4
- package/dist/testing/fuzz.d.ts.map +1 -1
- package/dist/testing/fuzz.js +13 -5
- package/dist/testing/fuzz.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +12 -4
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +23 -8
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +13 -0
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js +43 -8
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/package.json +2 -2
- package/skills/add-resource/SKILL.md +31 -1
- package/skills/add-tool/SKILL.md +70 -1
- package/skills/api-config/SKILL.md +30 -3
- package/skills/api-context/SKILL.md +47 -15
- package/skills/api-linter/SKILL.md +39 -3
- package/skills/api-telemetry/SKILL.md +3 -1
- package/skills/api-workers/SKILL.md +9 -1
- package/skills/tool-defs-analysis/SKILL.md +15 -5
- package/templates/.env.example +4 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cache hints for the cacheable results of protocol revision
|
|
3
|
+
* 2026-07-28 (SEP-2549) — the framework's view of the SDK's two hint seams:
|
|
4
|
+
* a per-operation map on the server, and a per-resource override carried on the
|
|
5
|
+
* resource definition.
|
|
6
|
+
*
|
|
7
|
+
* The hint rides a symbol-keyed property that is never serialized, and the
|
|
8
|
+
* 2025-era codec has no cache code path, so configuring one can never change
|
|
9
|
+
* what a 2025-era response looks like on the wire.
|
|
10
|
+
* @module src/mcp-server/cacheHints
|
|
11
|
+
*/
|
|
12
|
+
import { configurationError } from '../types-global/errors.js';
|
|
13
|
+
/**
|
|
14
|
+
* Rejects a `ttlMs` the SDK would reject at construction time, naming the
|
|
15
|
+
* option that carries it. `cacheScope` needs no runtime check — its union type
|
|
16
|
+
* makes an invalid value a compile error, whereas `ttlMs: number` admits
|
|
17
|
+
* negatives and fractions the spec does not.
|
|
18
|
+
*/
|
|
19
|
+
function assertValidTtl(hint, field) {
|
|
20
|
+
if (hint.ttlMs !== undefined && (!Number.isSafeInteger(hint.ttlMs) || hint.ttlMs < 0)) {
|
|
21
|
+
throw configurationError(`${field}.ttlMs must be a non-negative safe integer (received ${String(hint.ttlMs)}).`, { field: `${field}.ttlMs`, value: hint.ttlMs });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validates every cache hint an app declares, before any of them reaches the
|
|
26
|
+
* SDK constructor. Turns what would otherwise surface as a bare `RangeError`
|
|
27
|
+
* mid-startup into a configuration error naming the offending field.
|
|
28
|
+
*
|
|
29
|
+
* @throws {McpError} `ConfigurationError` when a `ttlMs` is not a non-negative
|
|
30
|
+
* safe integer.
|
|
31
|
+
*/
|
|
32
|
+
export function assertValidCacheHints(cacheHints, resources) {
|
|
33
|
+
for (const [method, hint] of Object.entries(cacheHints ?? {})) {
|
|
34
|
+
if (hint)
|
|
35
|
+
assertValidTtl(hint, `cacheHints['${method}']`);
|
|
36
|
+
}
|
|
37
|
+
for (const def of resources) {
|
|
38
|
+
if (def.cacheHint) {
|
|
39
|
+
assertValidTtl(def.cacheHint, `resource '${def.name ?? def.uriTemplate}' cacheHint`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=cacheHints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cacheHints.js","sourceRoot":"","sources":["../../src/mcp-server/cacheHints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAgB9D;;;;;GAKG;AACH,SAAS,cAAc,CAAC,IAAe,EAAE,KAAa;IACpD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACtF,MAAM,kBAAkB,CACtB,GAAG,KAAK,wDAAwD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EACtF,EAAE,KAAK,EAAE,GAAG,KAAK,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAkC,EAClC,SAA2C;IAE3C,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI;YAAE,cAAc,CAAC,IAAI,EAAE,eAAe,MAAM,IAAI,CAAC,CAAC;IAC5D,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAClB,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,WAAW,aAAa,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -12,9 +12,14 @@
|
|
|
12
12
|
* `notifications/resources/updated` is subscription-scoped: it is emitted only
|
|
13
13
|
* for URIs the client actually subscribed to via `resources/subscribe` (#354).
|
|
14
14
|
*
|
|
15
|
+
* That request-scoped path is the **2025-era** one. On 2026-07-28 delivery
|
|
16
|
+
* belongs to the client's `subscriptions/listen` stream, so a modern instance
|
|
17
|
+
* publishes to the handler's event bus instead — see {@link buildBusNotifiers}
|
|
18
|
+
* (#193).
|
|
19
|
+
*
|
|
15
20
|
* @module src/mcp-server/notifications
|
|
16
21
|
*/
|
|
17
|
-
import type { ServerNotification } from '@modelcontextprotocol/server';
|
|
22
|
+
import type { ServerEventBus, ServerNotification, ServerNotifier } from '@modelcontextprotocol/server';
|
|
18
23
|
/**
|
|
19
24
|
* The slice of `ctx.mcpReq` these notifiers need. Typed with an optional
|
|
20
25
|
* `notify` so the runtime presence check is type-meaningful — a background or
|
|
@@ -36,6 +41,68 @@ export interface ResourceSubscriptions {
|
|
|
36
41
|
/** True when the connected client subscribed to this exact URI. */
|
|
37
42
|
has: (uri: string) => boolean;
|
|
38
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* The same four closures, each optional — what a server-level notifier set
|
|
46
|
+
* offers and what {@link selectNotifiers} returns, since a fallback set may not
|
|
47
|
+
* carry all four.
|
|
48
|
+
*/
|
|
49
|
+
export interface OptionalNotifiers {
|
|
50
|
+
notifyPromptListChanged?: () => void;
|
|
51
|
+
notifyResourceListChanged?: () => void;
|
|
52
|
+
notifyResourceUpdated?: (uri: string) => void;
|
|
53
|
+
notifyToolListChanged?: () => void;
|
|
54
|
+
}
|
|
55
|
+
/** Every delivery path a handler factory can offer, in one bag. */
|
|
56
|
+
export interface NotifierSources extends OptionalNotifiers {
|
|
57
|
+
/** Modern-era publish facade. Present only on `modern` instances. */
|
|
58
|
+
bus?: ServerNotifier;
|
|
59
|
+
/** Legacy-era `resources/subscribe` registry. */
|
|
60
|
+
subscriptions?: ResourceSubscriptions;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Picks the delivery path a handler's `ctx.notify*` should take, era-ordered.
|
|
64
|
+
*
|
|
65
|
+
* A modern instance publishes to the listen bus, where the SDK applies the
|
|
66
|
+
* client's subscription filter and an out-of-request emit still reaches open
|
|
67
|
+
* streams (#193). A legacy instance sends through the request's own scope so
|
|
68
|
+
* the message carries `relatedRequestId` (#135). The server-level closures are
|
|
69
|
+
* the fallback for scopes with no sender at all — stdio and test harnesses.
|
|
70
|
+
*
|
|
71
|
+
* Both handler factories route through here so the ordering is one decision
|
|
72
|
+
* rather than two copies that can drift apart.
|
|
73
|
+
*/
|
|
74
|
+
export declare function selectNotifiers(sources: NotifierSources, mcpReq: NotificationSender | undefined): OptionalNotifiers;
|
|
75
|
+
/**
|
|
76
|
+
* A {@link ServerNotifier} over an arbitrary {@link ServerEventBus}.
|
|
77
|
+
*
|
|
78
|
+
* `createMcpHandler` returns one bound to its own bus, but the framework builds
|
|
79
|
+
* the bus first — before any transport exists — so `setup()` can capture a
|
|
80
|
+
* publish handle that stays valid once serving starts. The names mirror the
|
|
81
|
+
* wire methods.
|
|
82
|
+
*/
|
|
83
|
+
export declare function notifierFor(bus: ServerEventBus): ServerNotifier;
|
|
84
|
+
/**
|
|
85
|
+
* Builds notifier closures that publish onto the modern era's
|
|
86
|
+
* `subscriptions/listen` bus.
|
|
87
|
+
*
|
|
88
|
+
* On protocol revision 2026-07-28 a client opts into notification types by
|
|
89
|
+
* opening a `subscriptions/listen` stream, and the spec is explicit that a
|
|
90
|
+
* server MUST NOT send types the client has not requested. That filter lives in
|
|
91
|
+
* the SDK's listen router, which only sees what reaches the bus — so a modern
|
|
92
|
+
* handler firing through its own request scope bypasses it and delivers to
|
|
93
|
+
* clients that opened no stream at all.
|
|
94
|
+
*
|
|
95
|
+
* Publishing is also what makes *out-of-request* emission work: the bus is not
|
|
96
|
+
* request-scoped, so a background emitter reaches every open stream rather than
|
|
97
|
+
* dropping into a closed exchange.
|
|
98
|
+
*
|
|
99
|
+
* No subscription registry is consulted here — including for
|
|
100
|
+
* `resources/updated`. Per-URI routing is the listen filter's
|
|
101
|
+
* `resourceSubscriptions` field, which the SDK applies on publish; the
|
|
102
|
+
* `resources/subscribe` registry is the 2025-era mechanism and does not exist
|
|
103
|
+
* on this era.
|
|
104
|
+
*/
|
|
105
|
+
export declare function buildBusNotifiers(notify: ServerNotifier): RequestScopedNotifiers;
|
|
39
106
|
/**
|
|
40
107
|
* Builds notifier closures bound to a single request's `ctx.mcpReq.notify`.
|
|
41
108
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/mcp-server/notifications.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/mcp-server/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACf,MAAM,8BAA8B,CAAC;AAItC;;;;;GAKG;AACH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,qFAAqF;AACrF,MAAM,WAAW,sBAAsB;IACrC,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,qBAAqB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qBAAqB,EAAE,MAAM,IAAI,CAAC;CACnC;AAED,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IACrC,yBAAyB,CAAC,EAAE,MAAM,IAAI,CAAC;IACvC,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,qEAAqE;IACrE,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,iDAAiD;IACjD,aAAa,CAAC,EAAE,qBAAqB,CAAC;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,kBAAkB,GAAG,SAAS,GACrC,iBAAiB,CAMnB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,cAAc,CAO/D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,sBAAsB,CAOhF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,kBAAkB,EAC1B,aAAa,CAAC,EAAE,qBAAqB,GACpC,sBAAsB,GAAG,SAAS,CA2BpC"}
|
|
@@ -12,9 +12,76 @@
|
|
|
12
12
|
* `notifications/resources/updated` is subscription-scoped: it is emitted only
|
|
13
13
|
* for URIs the client actually subscribed to via `resources/subscribe` (#354).
|
|
14
14
|
*
|
|
15
|
+
* That request-scoped path is the **2025-era** one. On 2026-07-28 delivery
|
|
16
|
+
* belongs to the client's `subscriptions/listen` stream, so a modern instance
|
|
17
|
+
* publishes to the handler's event bus instead — see {@link buildBusNotifiers}
|
|
18
|
+
* (#193).
|
|
19
|
+
*
|
|
15
20
|
* @module src/mcp-server/notifications
|
|
16
21
|
*/
|
|
17
22
|
import { logger } from '../utils/internal/logger.js';
|
|
23
|
+
/**
|
|
24
|
+
* Picks the delivery path a handler's `ctx.notify*` should take, era-ordered.
|
|
25
|
+
*
|
|
26
|
+
* A modern instance publishes to the listen bus, where the SDK applies the
|
|
27
|
+
* client's subscription filter and an out-of-request emit still reaches open
|
|
28
|
+
* streams (#193). A legacy instance sends through the request's own scope so
|
|
29
|
+
* the message carries `relatedRequestId` (#135). The server-level closures are
|
|
30
|
+
* the fallback for scopes with no sender at all — stdio and test harnesses.
|
|
31
|
+
*
|
|
32
|
+
* Both handler factories route through here so the ordering is one decision
|
|
33
|
+
* rather than two copies that can drift apart.
|
|
34
|
+
*/
|
|
35
|
+
export function selectNotifiers(sources, mcpReq) {
|
|
36
|
+
return ((sources.bus ? buildBusNotifiers(sources.bus) : undefined) ??
|
|
37
|
+
buildRequestScopedNotifiers(mcpReq ?? {}, sources.subscriptions) ??
|
|
38
|
+
sources);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A {@link ServerNotifier} over an arbitrary {@link ServerEventBus}.
|
|
42
|
+
*
|
|
43
|
+
* `createMcpHandler` returns one bound to its own bus, but the framework builds
|
|
44
|
+
* the bus first — before any transport exists — so `setup()` can capture a
|
|
45
|
+
* publish handle that stays valid once serving starts. The names mirror the
|
|
46
|
+
* wire methods.
|
|
47
|
+
*/
|
|
48
|
+
export function notifierFor(bus) {
|
|
49
|
+
return {
|
|
50
|
+
toolsChanged: () => bus.publish({ kind: 'tools_list_changed' }),
|
|
51
|
+
promptsChanged: () => bus.publish({ kind: 'prompts_list_changed' }),
|
|
52
|
+
resourcesChanged: () => bus.publish({ kind: 'resources_list_changed' }),
|
|
53
|
+
resourceUpdated: (uri) => bus.publish({ kind: 'resource_updated', uri }),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builds notifier closures that publish onto the modern era's
|
|
58
|
+
* `subscriptions/listen` bus.
|
|
59
|
+
*
|
|
60
|
+
* On protocol revision 2026-07-28 a client opts into notification types by
|
|
61
|
+
* opening a `subscriptions/listen` stream, and the spec is explicit that a
|
|
62
|
+
* server MUST NOT send types the client has not requested. That filter lives in
|
|
63
|
+
* the SDK's listen router, which only sees what reaches the bus — so a modern
|
|
64
|
+
* handler firing through its own request scope bypasses it and delivers to
|
|
65
|
+
* clients that opened no stream at all.
|
|
66
|
+
*
|
|
67
|
+
* Publishing is also what makes *out-of-request* emission work: the bus is not
|
|
68
|
+
* request-scoped, so a background emitter reaches every open stream rather than
|
|
69
|
+
* dropping into a closed exchange.
|
|
70
|
+
*
|
|
71
|
+
* No subscription registry is consulted here — including for
|
|
72
|
+
* `resources/updated`. Per-URI routing is the listen filter's
|
|
73
|
+
* `resourceSubscriptions` field, which the SDK applies on publish; the
|
|
74
|
+
* `resources/subscribe` registry is the 2025-era mechanism and does not exist
|
|
75
|
+
* on this era.
|
|
76
|
+
*/
|
|
77
|
+
export function buildBusNotifiers(notify) {
|
|
78
|
+
return {
|
|
79
|
+
notifyToolListChanged: () => notify.toolsChanged(),
|
|
80
|
+
notifyResourceListChanged: () => notify.resourcesChanged(),
|
|
81
|
+
notifyPromptListChanged: () => notify.promptsChanged(),
|
|
82
|
+
notifyResourceUpdated: (uri) => notify.resourceUpdated(uri),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
18
85
|
/**
|
|
19
86
|
* Builds notifier closures bound to a single request's `ctx.mcpReq.notify`.
|
|
20
87
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/mcp-server/notifications.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/mcp-server/notifications.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Encapsulates the registration of all resource definitions with an McpServer.
|
|
3
3
|
* @module src/mcp-server/resources/resource-registration
|
|
4
4
|
*/
|
|
5
|
-
import { type McpServer } from '@modelcontextprotocol/server';
|
|
5
|
+
import { type McpServer, type ServerNotifier } from '@modelcontextprotocol/server';
|
|
6
6
|
import type { ResourceSubscriptions } from '../../mcp-server/notifications.js';
|
|
7
7
|
import type { AnyResourceDefinition } from '../../mcp-server/resources/utils/resourceDefinition.js';
|
|
8
8
|
import { type ResourceHandlerFactoryServices } from '../../mcp-server/resources/utils/resourceHandlerFactory.js';
|
|
@@ -15,7 +15,7 @@ export declare class ResourceRegistry {
|
|
|
15
15
|
/**
|
|
16
16
|
* Registers all resolved resource definitions with the provided McpServer instance.
|
|
17
17
|
*/
|
|
18
|
-
registerAll(server: McpServer, subscriptions?: ResourceSubscriptions): Promise<void>;
|
|
18
|
+
registerAll(server: McpServer, subscriptions?: ResourceSubscriptions, bus?: ServerNotifier): Promise<void>;
|
|
19
19
|
/** Throws at startup if a resource with the same name was already registered. */
|
|
20
20
|
private assertUniqueName;
|
|
21
21
|
private registerResource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-registration.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/resources/resource-registration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"resource-registration.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/resources/resource-registration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,EAEL,KAAK,8BAA8B,EAEpC,MAAM,wDAAwD,CAAC;AAUhE,qBAAa,gBAAgB;IAKzB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ;IALlB,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErD,YACU,YAAY,EAAE,qBAAqB,EAAE,EACrC,QAAQ,EAAE,8BAA8B,EAC9C;IAEJ;;OAEG;IACU,WAAW,CACtB,MAAM,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,qBAAqB,EACrC,GAAG,CAAC,EAAE,cAAc,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Bf;IAED,iFAAiF;IACjF,OAAO,CAAC,gBAAgB;YAUV,gBAAgB;CAwD/B"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Encapsulates the registration of all resource definitions with an McpServer.
|
|
3
3
|
* @module src/mcp-server/resources/resource-registration
|
|
4
4
|
*/
|
|
5
|
-
import { ResourceTemplate } from '@modelcontextprotocol/server';
|
|
5
|
+
import { ResourceTemplate, } from '@modelcontextprotocol/server';
|
|
6
6
|
import { createResourceHandler, } from '../../mcp-server/resources/utils/resourceHandlerFactory.js';
|
|
7
7
|
import { JsonRpcErrorCode } from '../../types-global/errors.js';
|
|
8
8
|
import { ErrorHandler } from '../../utils/internal/error-handler/errorHandler.js';
|
|
@@ -23,7 +23,7 @@ export class ResourceRegistry {
|
|
|
23
23
|
/**
|
|
24
24
|
* Registers all resolved resource definitions with the provided McpServer instance.
|
|
25
25
|
*/
|
|
26
|
-
async registerAll(server, subscriptions) {
|
|
26
|
+
async registerAll(server, subscriptions, bus) {
|
|
27
27
|
this.registeredNames.clear();
|
|
28
28
|
// Per-server notifier closures targeting `server.send*ListChanged()`. Bound
|
|
29
29
|
// once per registerAll() call — never mutated on a shared services object
|
|
@@ -35,6 +35,7 @@ export class ResourceRegistry {
|
|
|
35
35
|
notifyResourceListChanged: () => server.sendResourceListChanged(),
|
|
36
36
|
notifyToolListChanged: () => server.sendToolListChanged(),
|
|
37
37
|
...(subscriptions && { subscriptions }),
|
|
38
|
+
...(bus && { bus }),
|
|
38
39
|
};
|
|
39
40
|
const context = requestContextService.createRequestContext({
|
|
40
41
|
operation: 'ResourceRegistry.registerAll',
|
|
@@ -72,6 +73,9 @@ export class ResourceRegistry {
|
|
|
72
73
|
description: def.description,
|
|
73
74
|
mimeType,
|
|
74
75
|
...(def.size != null && { size: def.size }),
|
|
76
|
+
// 2026-07-28 cache hint. The SDK strips it from the advertised
|
|
77
|
+
// metadata and merges it over the server-level per-operation hint.
|
|
78
|
+
...(def.cacheHint && { cacheHint: def.cacheHint }),
|
|
75
79
|
...(def.examples && { examples: def.examples }),
|
|
76
80
|
...(def.annotations && { annotations: def.annotations }),
|
|
77
81
|
...(def._meta && { _meta: def._meta }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-registration.js","sourceRoot":"","sources":["../../../src/mcp-server/resources/resource-registration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"resource-registration.js","sourceRoot":"","sources":["../../../src/mcp-server/resources/resource-registration.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @see {@link https://modelcontextprotocol.io/specification/2026-07-28/server/resources | MCP Resources}
|
|
7
7
|
* @module src/mcp-server/resources/utils/resourceDefinition
|
|
8
8
|
*/
|
|
9
|
-
import type { CompleteResourceTemplateCallback, ListResourcesResult, ReadResourceResult, ServerContext } from '@modelcontextprotocol/server';
|
|
9
|
+
import type { CacheHint, CompleteResourceTemplateCallback, ListResourcesResult, ReadResourceResult, ServerContext } from '@modelcontextprotocol/server';
|
|
10
10
|
import type { ZodObject, ZodRawShape, z } from 'zod';
|
|
11
11
|
import type { HandlerContext, ReasonOf } from '../../../core/context.js';
|
|
12
12
|
import type { ErrorContract } from '../../../types-global/errors.js';
|
|
@@ -53,6 +53,19 @@ export interface ResourceDefinition<TParams extends ZodObject<ZodRawShape> = Zod
|
|
|
53
53
|
annotations?: ResourceAnnotations;
|
|
54
54
|
/** Required auth scopes. */
|
|
55
55
|
auth?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* Cache hint applied to this resource's `resources/read` results on protocol
|
|
58
|
+
* revision 2026-07-28. Overrides the `resources/read` entry of
|
|
59
|
+
* `createApp({ cacheHints })` field by field — a field left unset here still
|
|
60
|
+
* falls back to that per-operation hint, and then to the SDK's conservative
|
|
61
|
+
* defaults (`ttlMs: 0`, `cacheScope: 'private'`).
|
|
62
|
+
*
|
|
63
|
+
* `ttlMs` must be a non-negative safe integer. 2025-era responses are
|
|
64
|
+
* unaffected either way.
|
|
65
|
+
*
|
|
66
|
+
* @example `cacheHint: { ttlMs: 300_000, cacheScope: 'public' }`
|
|
67
|
+
*/
|
|
68
|
+
cacheHint?: CacheHint;
|
|
56
69
|
/**
|
|
57
70
|
* Per-variable completion callbacks for URI template variables. Forwarded to
|
|
58
71
|
* the SDK's `ResourceTemplate` constructor so the SDK auto-installs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceDefinition.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resourceDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceDefinition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"resourceDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqJH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,QAAQ,CAKtB,WAAmB,EACnB,OAA2E;IAE3E,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Constructs Context (with `uri`), checks inline auth, validates params, formats response.
|
|
4
4
|
* @module src/mcp-server/resources/utils/resourceHandlerFactory
|
|
5
5
|
*/
|
|
6
|
-
import type { InputRequiredResult, ReadResourceResult, ServerContext, Variables } from '@modelcontextprotocol/server';
|
|
6
|
+
import type { InputRequiredResult, ReadResourceResult, ServerContext, ServerNotifier, Variables } from '@modelcontextprotocol/server';
|
|
7
7
|
import { type ResourceSubscriptions } from '../../../mcp-server/notifications.js';
|
|
8
8
|
import type { AnyResourceDefinition } from '../../../mcp-server/resources/utils/resourceDefinition.js';
|
|
9
9
|
import type { StorageService } from '../../../storage/core/StorageService.js';
|
|
@@ -28,16 +28,24 @@ export interface ResourceHandlerFactoryServices {
|
|
|
28
28
|
* McpServer gets its own notifier closures — preventing a concurrent
|
|
29
29
|
* registerAll() from overwriting an in-flight handler's notifier target.
|
|
30
30
|
*
|
|
31
|
-
* The resource handler factory
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* The resource handler factory picks a delivery path per era via
|
|
32
|
+
* {@link selectNotifiers}, and uses these closures only as a fallback for
|
|
33
|
+
* scopes with neither a bus nor a request sender (stdio, test harnesses).
|
|
34
34
|
*/
|
|
35
35
|
export interface ResourceHandlerNotifiers {
|
|
36
|
+
/**
|
|
37
|
+
* Publish facade for the modern era's `subscriptions/listen` bus, supplied
|
|
38
|
+
* only for `modern` instances. Takes precedence over the request-scoped path:
|
|
39
|
+
* on 2026-07-28 the client opts into notification types through its listen
|
|
40
|
+
* stream, and only what reaches the bus is filtered against that opt-in
|
|
41
|
+
* (#193).
|
|
42
|
+
*/
|
|
43
|
+
bus?: ServerNotifier;
|
|
36
44
|
notifyPromptListChanged?: () => void;
|
|
37
45
|
notifyResourceListChanged?: () => void;
|
|
38
46
|
notifyResourceUpdated?: (uri: string) => void;
|
|
39
47
|
notifyToolListChanged?: () => void;
|
|
40
|
-
/** Per-connection `resources/subscribe` registry (#354). */
|
|
48
|
+
/** Per-connection `resources/subscribe` registry (#354). Legacy era only. */
|
|
41
49
|
subscriptions?: ResourceSubscriptions;
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceHandlerFactory.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceHandlerFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,8BAA8B,CAAC;AAStC,OAAO,
|
|
1
|
+
{"version":3,"file":"resourceHandlerFactory.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceHandlerFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,SAAS,EACV,MAAM,8BAA8B,CAAC;AAStC,OAAO,EAAE,KAAK,qBAAqB,EAAmB,MAAM,+BAA+B,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;AAGhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAQzD,qEAAqE;AACrE,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IACrC,yBAAyB,CAAC,EAAE,MAAM,IAAI,CAAC;IACvC,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,qBAAqB,CAAC;CACvC;AA+CD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,8BAA8B,EACxC,SAAS,EAAE,wBAAwB,GAClC,CACD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CA8GrD"}
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
import { config } from '../../../config/index.js';
|
|
7
7
|
import { attachTypedFail, createContext } from '../../../core/context.js';
|
|
8
8
|
import { createContextInputs, createRequestInput, isInputRequiredSignal, } from '../../../mcp-server/inputRequired.js';
|
|
9
|
-
import {
|
|
9
|
+
import { selectNotifiers } from '../../../mcp-server/notifications.js';
|
|
10
10
|
import { withRequiredScopes } from '../../../mcp-server/transports/auth/lib/authUtils.js';
|
|
11
|
+
import { resolveSessionMode } from '../../../mcp-server/types.js';
|
|
11
12
|
import { McpError } from '../../../types-global/errors.js';
|
|
12
13
|
import { ErrorHandler } from '../../../utils/internal/error-handler/errorHandler.js';
|
|
13
14
|
import { measureResourceExecution } from '../../../utils/internal/performance.js';
|
|
@@ -67,11 +68,7 @@ export function createResourceHandler(def, services, notifiers) {
|
|
|
67
68
|
return async (uri, variables, serverContext) => {
|
|
68
69
|
const mcpReq = serverContext?.mcpReq;
|
|
69
70
|
const signal = mcpReq?.signal ?? new AbortController().signal;
|
|
70
|
-
|
|
71
|
-
// this request's `ctx.mcpReq.notify` so they carry `relatedRequestId` and
|
|
72
|
-
// reach the client under per-request serving (#135). Fall back to the
|
|
73
|
-
// server-level notifiers when the scope exposes no sender.
|
|
74
|
-
const effectiveNotifiers = buildRequestScopedNotifiers(mcpReq ?? {}, notifiers.subscriptions) ?? notifiers;
|
|
71
|
+
const effectiveNotifiers = selectNotifiers(notifiers, mcpReq);
|
|
75
72
|
const sdkSessionId = typeof serverContext?.sessionId === 'string' ? serverContext.sessionId : undefined;
|
|
76
73
|
// Surface sessionId on `Context` only when it has request-spanning
|
|
77
74
|
// lifetime — stateful HTTP (or `auto`, which resolves to stateful for
|
|
@@ -79,7 +76,7 @@ export function createResourceHandler(def, services, notifiers) {
|
|
|
79
76
|
// pass it through only when the consumer opted in via
|
|
80
77
|
// `createApp({ context: { exposeStatelessSessionId: true } })`. Stdio
|
|
81
78
|
// gives no sessionId at the SDK layer, so the gate is moot there.
|
|
82
|
-
const isStatefulMode = config.mcpSessionMode === 'stateful'
|
|
79
|
+
const isStatefulMode = resolveSessionMode(config.mcpSessionMode) === 'stateful';
|
|
83
80
|
const handlerSessionId = sdkSessionId && (isStatefulMode || services.exposeStatelessSessionId === true)
|
|
84
81
|
? sdkSessionId
|
|
85
82
|
: undefined;
|
|
@@ -110,25 +107,30 @@ export function createResourceHandler(def, services, notifiers) {
|
|
|
110
107
|
}
|
|
111
108
|
// Validate params via schema if defined
|
|
112
109
|
const validatedParams = def.params ? def.params.parse(variables) : variables;
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
110
|
+
// Execute handler with performance measurement. The context is built
|
|
111
|
+
// from inside the execution span so `ctx.traceId` / `ctx.spanId` — and
|
|
112
|
+
// the child logger built from them — name the `resource_read:*` span the
|
|
113
|
+
// handler runs in rather than the enclosing request span (#296).
|
|
114
|
+
// `attachTypedFail` adds `ctx.fail` when the definition declares an error
|
|
115
|
+
// contract; otherwise no-op.
|
|
116
|
+
const handlerResult = await measureResourceExecution((spanContext) => {
|
|
117
|
+
const ctx = attachTypedFail(createContext({
|
|
118
|
+
appContext: spanContext,
|
|
119
|
+
logger: services.logger,
|
|
120
|
+
storage: services.storage,
|
|
121
|
+
signal,
|
|
122
|
+
sessionId: handlerSessionId,
|
|
123
|
+
inputs: createContextInputs(mcpReq),
|
|
124
|
+
requestInput: createRequestInput(),
|
|
125
|
+
...(mcpReq?.log && { wireLog: mcpReq.log }),
|
|
126
|
+
notifyPromptListChanged: effectiveNotifiers.notifyPromptListChanged,
|
|
127
|
+
notifyResourceListChanged: effectiveNotifiers.notifyResourceListChanged,
|
|
128
|
+
notifyResourceUpdated: effectiveNotifiers.notifyResourceUpdated,
|
|
129
|
+
notifyToolListChanged: effectiveNotifiers.notifyToolListChanged,
|
|
130
|
+
uri,
|
|
131
|
+
}), def.errors);
|
|
132
|
+
return Promise.resolve(def.handler(validatedParams, ctx));
|
|
133
|
+
}, { ...appContext, resourceName }, { uri: resourceUri, mimeType });
|
|
132
134
|
// Validate output against schema when defined
|
|
133
135
|
const validatedResult = def.output ? def.output.parse(handlerResult) : handlerResult;
|
|
134
136
|
const contents = formatter(validatedResult, { uri, mimeType });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceHandlerFactory.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceHandlerFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"resourceHandlerFactory.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/utils/resourceHandlerFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,13 +9,20 @@
|
|
|
9
9
|
* - Transports: https://modelcontextprotocol.io/specification/2026-07-28/basic/transports
|
|
10
10
|
* @module src/mcp-server/server
|
|
11
11
|
*/
|
|
12
|
-
import { type Implementation, McpServer } from '@modelcontextprotocol/server';
|
|
12
|
+
import { type Implementation, McpServer, type ServerNotifier } from '@modelcontextprotocol/server';
|
|
13
13
|
import type { AppConfig } from '../config/index.js';
|
|
14
|
+
import type { CacheHints } from '../mcp-server/cacheHints.js';
|
|
14
15
|
import type { PromptRegistry } from '../mcp-server/prompts/prompt-registration.js';
|
|
15
16
|
import type { ResourceRegistry } from '../mcp-server/resources/resource-registration.js';
|
|
16
17
|
import type { ToolRegistry } from '../mcp-server/tools/tool-registration.js';
|
|
17
18
|
/** Dependencies required to create an MCP server instance. */
|
|
18
19
|
export interface McpServerDeps {
|
|
20
|
+
/**
|
|
21
|
+
* Per-operation cache hints for the 2026-07-28 cacheable results. A resource
|
|
22
|
+
* declaring its own `cacheHint` overrides the `resources/read` entry here
|
|
23
|
+
* for that resource, field by field.
|
|
24
|
+
*/
|
|
25
|
+
cacheHints?: CacheHints;
|
|
19
26
|
config: AppConfig;
|
|
20
27
|
/**
|
|
21
28
|
* One-line description forwarded to `new McpServer({ serverInfo })`.
|
|
@@ -41,6 +48,14 @@ export interface McpServerDeps {
|
|
|
41
48
|
* leaking that text into every tool description.
|
|
42
49
|
*/
|
|
43
50
|
instructions?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Publish facade for the `subscriptions/listen` bus. Supplied for `modern`
|
|
53
|
+
* instances only, where it is how `ctx.notify*` reaches a client: the SDK's
|
|
54
|
+
* listen router filters what the client opted into, and an out-of-request
|
|
55
|
+
* emit still finds open streams (#193). Legacy instances and stdio deliver
|
|
56
|
+
* over the live connection instead.
|
|
57
|
+
*/
|
|
58
|
+
notifier?: ServerNotifier;
|
|
44
59
|
promptRegistry: PromptRegistry;
|
|
45
60
|
resourceRegistry: ResourceRegistry;
|
|
46
61
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,KAAK,cAAc,EACnB,SAAS,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,KAAK,cAAc,EACnB,SAAS,EAET,KAAK,cAAc,EACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iDAAiD,CAAC;AAExF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAI5E,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,mEAAmE;IACnE,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CA6ErF"}
|
|
@@ -50,6 +50,7 @@ export async function createMcpServerInstance(deps) {
|
|
|
50
50
|
extensions: deps.extensions,
|
|
51
51
|
}),
|
|
52
52
|
},
|
|
53
|
+
...(deps.cacheHints && { cacheHints: deps.cacheHints }),
|
|
53
54
|
...(deps.instructions && { instructions: deps.instructions }),
|
|
54
55
|
// Multi-round-trip serving: `ctx.requestInput(...)` returns are fulfilled
|
|
55
56
|
// by the client on 2026-era requests and by the SDK's legacy shim (real
|
|
@@ -66,9 +67,13 @@ export async function createMcpServerInstance(deps) {
|
|
|
66
67
|
const subscriptions = (deps.era ?? 'legacy') === 'legacy' ? installResourceSubscriptions(server) : undefined;
|
|
67
68
|
try {
|
|
68
69
|
logger.debug('Registering all MCP capabilities via registries...', context);
|
|
70
|
+
// The bus reaches a modern instance only. Passing it to a legacy one would
|
|
71
|
+
// route `ctx.notify*` away from the live session that can actually deliver
|
|
72
|
+
// it — the 2025 era has no `subscriptions/listen` stream to publish to.
|
|
73
|
+
const bus = (deps.era ?? 'legacy') === 'modern' ? deps.notifier : undefined;
|
|
69
74
|
await Promise.all([
|
|
70
|
-
deps.toolRegistry.registerAll(server, subscriptions),
|
|
71
|
-
deps.resourceRegistry.registerAll(server, subscriptions),
|
|
75
|
+
deps.toolRegistry.registerAll(server, subscriptions, bus),
|
|
76
|
+
deps.resourceRegistry.registerAll(server, subscriptions, bus),
|
|
72
77
|
deps.promptRegistry.registerAll(server),
|
|
73
78
|
]);
|
|
74
79
|
logger.debug('All MCP capabilities registered successfully', context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAEL,SAAS,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"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"}
|