@cyanheads/mcp-ts-core 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +1 -1
- package/changelog/0.12.x/0.12.1.md +26 -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 +23 -1
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +12 -3
- package/dist/core/app.js.map +1 -1
- package/dist/core/serverManifest.d.ts +5 -1
- package/dist/core/serverManifest.d.ts.map +1 -1
- package/dist/core/serverManifest.js +28 -10
- 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 +10 -3
- package/dist/linter/rules/schema-rules.d.ts.map +1 -1
- package/dist/linter/rules/schema-rules.js +52 -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 +5 -2
- 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/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 +3 -2
- package/dist/mcp-server/resources/resource-registration.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 +26 -25
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/server.d.ts +9 -1
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +6 -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/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 +27 -5
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +17 -2
- 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 +33 -27
- 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 +7 -2
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +25 -2
- 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/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 +1 -1
- package/skills/add-tool/SKILL.md +36 -1
- package/skills/api-config/SKILL.md +4 -1
- package/skills/api-context/SKILL.md +47 -15
- package/skills/api-linter/SKILL.md +15 -2
- 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
|
@@ -6,7 +6,7 @@
|
|
|
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
11
|
import { McpError } from '../../../types-global/errors.js';
|
|
12
12
|
import { ErrorHandler } from '../../../utils/internal/error-handler/errorHandler.js';
|
|
@@ -67,11 +67,7 @@ export function createResourceHandler(def, services, notifiers) {
|
|
|
67
67
|
return async (uri, variables, serverContext) => {
|
|
68
68
|
const mcpReq = serverContext?.mcpReq;
|
|
69
69
|
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;
|
|
70
|
+
const effectiveNotifiers = selectNotifiers(notifiers, mcpReq);
|
|
75
71
|
const sdkSessionId = typeof serverContext?.sessionId === 'string' ? serverContext.sessionId : undefined;
|
|
76
72
|
// Surface sessionId on `Context` only when it has request-spanning
|
|
77
73
|
// lifetime — stateful HTTP (or `auto`, which resolves to stateful for
|
|
@@ -110,25 +106,30 @@ export function createResourceHandler(def, services, notifiers) {
|
|
|
110
106
|
}
|
|
111
107
|
// Validate params via schema if defined
|
|
112
108
|
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
|
-
|
|
109
|
+
// Execute handler with performance measurement. The context is built
|
|
110
|
+
// from inside the execution span so `ctx.traceId` / `ctx.spanId` — and
|
|
111
|
+
// the child logger built from them — name the `resource_read:*` span the
|
|
112
|
+
// handler runs in rather than the enclosing request span (#296).
|
|
113
|
+
// `attachTypedFail` adds `ctx.fail` when the definition declares an error
|
|
114
|
+
// contract; otherwise no-op.
|
|
115
|
+
const handlerResult = await measureResourceExecution((spanContext) => {
|
|
116
|
+
const ctx = attachTypedFail(createContext({
|
|
117
|
+
appContext: spanContext,
|
|
118
|
+
logger: services.logger,
|
|
119
|
+
storage: services.storage,
|
|
120
|
+
signal,
|
|
121
|
+
sessionId: handlerSessionId,
|
|
122
|
+
inputs: createContextInputs(mcpReq),
|
|
123
|
+
requestInput: createRequestInput(),
|
|
124
|
+
...(mcpReq?.log && { wireLog: mcpReq.log }),
|
|
125
|
+
notifyPromptListChanged: effectiveNotifiers.notifyPromptListChanged,
|
|
126
|
+
notifyResourceListChanged: effectiveNotifiers.notifyResourceListChanged,
|
|
127
|
+
notifyResourceUpdated: effectiveNotifiers.notifyResourceUpdated,
|
|
128
|
+
notifyToolListChanged: effectiveNotifiers.notifyToolListChanged,
|
|
129
|
+
uri,
|
|
130
|
+
}), def.errors);
|
|
131
|
+
return Promise.resolve(def.handler(validatedParams, ctx));
|
|
132
|
+
}, { ...appContext, resourceName }, { uri: resourceUri, mimeType });
|
|
132
133
|
// Validate output against schema when defined
|
|
133
134
|
const validatedResult = def.output ? def.output.parse(handlerResult) : handlerResult;
|
|
134
135
|
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,7 +9,7 @@
|
|
|
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
14
|
import type { PromptRegistry } from '../mcp-server/prompts/prompt-registration.js';
|
|
15
15
|
import type { ResourceRegistry } from '../mcp-server/resources/resource-registration.js';
|
|
@@ -41,6 +41,14 @@ export interface McpServerDeps {
|
|
|
41
41
|
* leaking that text into every tool description.
|
|
42
42
|
*/
|
|
43
43
|
instructions?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Publish facade for the `subscriptions/listen` bus. Supplied for `modern`
|
|
46
|
+
* instances only, where it is how `ctx.notify*` reaches a client: the SDK's
|
|
47
|
+
* listen router filters what the client opted into, and an out-of-request
|
|
48
|
+
* emit still finds open streams (#193). Legacy instances and stdio deliver
|
|
49
|
+
* over the live connection instead.
|
|
50
|
+
*/
|
|
51
|
+
notifier?: ServerNotifier;
|
|
44
52
|
promptRegistry: PromptRegistry;
|
|
45
53
|
resourceRegistry: ResourceRegistry;
|
|
46
54
|
/**
|
|
@@ -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,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,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,CA4ErF"}
|
|
@@ -66,9 +66,13 @@ export async function createMcpServerInstance(deps) {
|
|
|
66
66
|
const subscriptions = (deps.era ?? 'legacy') === 'legacy' ? installResourceSubscriptions(server) : undefined;
|
|
67
67
|
try {
|
|
68
68
|
logger.debug('Registering all MCP capabilities via registries...', context);
|
|
69
|
+
// The bus reaches a modern instance only. Passing it to a legacy one would
|
|
70
|
+
// route `ctx.notify*` away from the live session that can actually deliver
|
|
71
|
+
// it — the 2025 era has no `subscriptions/listen` stream to publish to.
|
|
72
|
+
const bus = (deps.era ?? 'legacy') === 'modern' ? deps.notifier : undefined;
|
|
69
73
|
await Promise.all([
|
|
70
|
-
deps.toolRegistry.registerAll(server, subscriptions),
|
|
71
|
-
deps.resourceRegistry.registerAll(server, subscriptions),
|
|
74
|
+
deps.toolRegistry.registerAll(server, subscriptions, bus),
|
|
75
|
+
deps.resourceRegistry.registerAll(server, subscriptions, bus),
|
|
72
76
|
deps.promptRegistry.registerAll(server),
|
|
73
77
|
]);
|
|
74
78
|
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":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAEL,SAAS,GAGV,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAE/F,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAqD3E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAmB;IAC/D,MAAM,OAAO,GAAG,qBAAqB,CAAC,oBAAoB,CAAC;QACzD,SAAS,EAAE,yBAAyB;KACrC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;QAC/B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB;QACrC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QACxC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;KACzC,EACD;QACE,YAAY,EAAE;YACZ,wEAAwE;YACxE,wEAAwE;YACxE,4BAA4B;YAC5B,OAAO,EAAE,EAAE;YACX,oEAAoE;YACpE,qDAAqD;YACrD,gEAAgE;YAChE,qEAAqE;YACrE,4BAA4B;YAC5B,SAAS,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;YACjD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;YAC5B,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;YAC9B,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI;gBACrB,UAAU,EAAE,IAAI,CAAC,UAA8C;aAChE,CAAC;SACH;QACD,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QAC7D,0EAA0E;QAC1E,wEAAwE;QACxE,sEAAsE;QACtE,sCAAsC;QACtC,aAAa,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE;KACpC,CACF,CAAC;IAEF,yEAAyE;IACzE,iEAAiE;IACjE,0EAA0E;IAC1E,0EAA0E;IAC1E,+EAA+E;IAC/E,6EAA6E;IAC7E,MAAM,aAAa,GACjB,CAAC,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEzF,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,oDAAoD,EAAE,OAAO,CAAC,CAAC;QAE5E,2EAA2E;QAC3E,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAE5E,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC;YACzD,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC;YAC7D,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC;SACxC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CACV,qCAAqC,EACrC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EACnD,OAAO,CACR,CAAC;QACF,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Encapsulates the registration of all tool definitions with an McpServer.
|
|
3
3
|
* @module src/mcp-server/tools/tool-registration
|
|
4
4
|
*/
|
|
5
|
-
import type { McpServer } from '@modelcontextprotocol/server';
|
|
5
|
+
import type { McpServer, ServerNotifier } from '@modelcontextprotocol/server';
|
|
6
6
|
import type { ResourceSubscriptions } from '../../mcp-server/notifications.js';
|
|
7
7
|
import type { AnyToolDefinition } from '../../mcp-server/tools/utils/toolDefinition.js';
|
|
8
8
|
import { type HandlerFactoryServices } from '../../mcp-server/tools/utils/toolHandlerFactory.js';
|
|
@@ -20,7 +20,7 @@ export declare class ToolRegistry {
|
|
|
20
20
|
private readonly registeredNames;
|
|
21
21
|
constructor(toolDefs: AnyToolDef[], services?: HandlerFactoryServices | undefined);
|
|
22
22
|
/** Registers all tool definitions with the provided McpServer instance. */
|
|
23
|
-
registerAll(server: McpServer, subscriptions?: ResourceSubscriptions): Promise<void>;
|
|
23
|
+
registerAll(server: McpServer, subscriptions?: ResourceSubscriptions, bus?: ServerNotifier): Promise<void>;
|
|
24
24
|
/** Throws at startup if a tool with the same name was already registered. */
|
|
25
25
|
private assertUniqueName;
|
|
26
26
|
private deriveTitleFromName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/tool-registration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-registration.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/tool-registration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAgB,MAAM,8BAA8B,CAAC;AAE5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AACpF,OAAO,EAGL,KAAK,sBAAsB,EAE5B,MAAM,gDAAgD,CAAC;AAMxD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAE3C,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ,CAAC;IALnB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErD,YACU,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,CAAC,EAAE,sBAAsB,YAAA,EACvC;IAEJ,2EAA2E;IAC9D,WAAW,CACtB,MAAM,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,qBAAqB,EACrC,GAAG,CAAC,EAAE,cAAc,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Cf;IAED,6EAA6E;IAC7E,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,mBAAmB;IAI3B;;;OAGG;YACW,YAAY;CAiD3B"}
|
|
@@ -14,7 +14,7 @@ export class ToolRegistry {
|
|
|
14
14
|
this.services = services;
|
|
15
15
|
}
|
|
16
16
|
/** Registers all tool definitions with the provided McpServer instance. */
|
|
17
|
-
async registerAll(server, subscriptions) {
|
|
17
|
+
async registerAll(server, subscriptions, bus) {
|
|
18
18
|
// Reset per-server uniqueness tracking — registries are shared across
|
|
19
19
|
// per-request McpServer instances under HTTP serving.
|
|
20
20
|
this.registeredNames.clear();
|
|
@@ -27,6 +27,7 @@ export class ToolRegistry {
|
|
|
27
27
|
notifyResourceListChanged: () => server.sendResourceListChanged(),
|
|
28
28
|
notifyToolListChanged: () => server.sendToolListChanged(),
|
|
29
29
|
...(subscriptions && { subscriptions }),
|
|
30
|
+
...(bus && { bus }),
|
|
30
31
|
};
|
|
31
32
|
const context = requestContextService.createRequestContext({
|
|
32
33
|
operation: 'ToolRegistry.registerAll',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-registration.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/tool-registration.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAEhF,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAGlB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gDAAgD,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAU3E,MAAM,OAAO,YAAY;IAKb,QAAQ;IACR,QAAQ;IALlB,oEAAoE;IACnD,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAErD,YACU,QAAsB,EACtB,QAAiC;wBADjC,QAAQ;wBACR,QAAQ;IACf,CAAC;IAEJ,2EAA2E;IACpE,KAAK,CAAC,WAAW,CACtB,MAAiB,EACjB,aAAqC;
|
|
1
|
+
{"version":3,"file":"tool-registration.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/tool-registration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runtime shape checks for the Zod roots a tool definition may
|
|
3
|
+
* declare. Zod 4 tags every schema with `_zod.def.type`, and a discriminated
|
|
4
|
+
* union tags as `'union'` like any other — the discriminator on its `def` is
|
|
5
|
+
* what separates the two. Kept in one place so the definition builder, the
|
|
6
|
+
* server manifest, and the linter agree on what a union root is.
|
|
7
|
+
* @module src/mcp-server/tools/utils/schemaShape
|
|
8
|
+
*/
|
|
9
|
+
import type { ZodDiscriminatedUnion, ZodObject, ZodRawShape } from 'zod';
|
|
10
|
+
/** True when `value` is a `z.object()`. */
|
|
11
|
+
export declare function isZodObjectSchema(value: unknown): value is ZodObject<ZodRawShape>;
|
|
12
|
+
/**
|
|
13
|
+
* True when `value` is a `z.discriminatedUnion()`.
|
|
14
|
+
*
|
|
15
|
+
* A plain `z.union()` also tags as `'union'` but carries no `discriminator`, so
|
|
16
|
+
* the discriminator string is the distinguishing field. Only the discriminated
|
|
17
|
+
* form is accepted as a tool input root: a bare union gives the model no key to
|
|
18
|
+
* choose a branch by, and every variant's `required` list would apply at once.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isDiscriminatedUnionSchema(value: unknown): value is ZodDiscriminatedUnion<readonly ZodObject<ZodRawShape>[]>;
|
|
21
|
+
/**
|
|
22
|
+
* The object variants of a tool input root: the union's options, or the single
|
|
23
|
+
* object itself. Empty when the schema is neither — callers that lint or read
|
|
24
|
+
* shapes then have nothing to walk rather than a partial view.
|
|
25
|
+
*/
|
|
26
|
+
export declare function inputVariants(schema: unknown): readonly ZodObject<ZodRawShape>[];
|
|
27
|
+
//# sourceMappingURL=schemaShape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaShape.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/schemaShape.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAOzE,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAAC,WAAW,CAAC,CAGjF;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,qBAAqB,CAAC,SAAS,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAInE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,SAAS,CAAC,WAAW,CAAC,EAAE,CAQhF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runtime shape checks for the Zod roots a tool definition may
|
|
3
|
+
* declare. Zod 4 tags every schema with `_zod.def.type`, and a discriminated
|
|
4
|
+
* union tags as `'union'` like any other — the discriminator on its `def` is
|
|
5
|
+
* what separates the two. Kept in one place so the definition builder, the
|
|
6
|
+
* server manifest, and the linter agree on what a union root is.
|
|
7
|
+
* @module src/mcp-server/tools/utils/schemaShape
|
|
8
|
+
*/
|
|
9
|
+
/** True when `value` is a `z.object()`. */
|
|
10
|
+
export function isZodObjectSchema(value) {
|
|
11
|
+
if (!value || typeof value !== 'object')
|
|
12
|
+
return false;
|
|
13
|
+
return value._zod?.def?.type === 'object';
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* True when `value` is a `z.discriminatedUnion()`.
|
|
17
|
+
*
|
|
18
|
+
* A plain `z.union()` also tags as `'union'` but carries no `discriminator`, so
|
|
19
|
+
* the discriminator string is the distinguishing field. Only the discriminated
|
|
20
|
+
* form is accepted as a tool input root: a bare union gives the model no key to
|
|
21
|
+
* choose a branch by, and every variant's `required` list would apply at once.
|
|
22
|
+
*/
|
|
23
|
+
export function isDiscriminatedUnionSchema(value) {
|
|
24
|
+
if (!value || typeof value !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
const def = value._zod?.def;
|
|
27
|
+
return def?.type === 'union' && typeof def.discriminator === 'string';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The object variants of a tool input root: the union's options, or the single
|
|
31
|
+
* object itself. Empty when the schema is neither — callers that lint or read
|
|
32
|
+
* shapes then have nothing to walk rather than a partial view.
|
|
33
|
+
*/
|
|
34
|
+
export function inputVariants(schema) {
|
|
35
|
+
if (isDiscriminatedUnionSchema(schema)) {
|
|
36
|
+
const options = schema.options;
|
|
37
|
+
return Array.isArray(options)
|
|
38
|
+
? options.filter(isZodObjectSchema)
|
|
39
|
+
: [];
|
|
40
|
+
}
|
|
41
|
+
return isZodObjectSchema(schema) ? [schema] : [];
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=schemaShape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaShape.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/schemaShape.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,2CAA2C;AAC3C,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,OAAQ,KAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,QAAQ,CAAC;AAC9D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAc;IAEd,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAI,KAAsB,CAAC,IAAI,EAAE,GAAG,CAAC;IAC9C,OAAO,GAAG,EAAE,IAAI,KAAK,OAAO,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,IAAI,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAI,MAAgC,CAAC,OAAO,CAAC;QAC1D,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAC3B,CAAC,CAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA8B;YACjE,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module src/mcp-server/tools/utils/toolDefinition
|
|
9
9
|
*/
|
|
10
10
|
import type { ContentBlock } from '@modelcontextprotocol/server';
|
|
11
|
-
import type
|
|
11
|
+
import { type ZodDiscriminatedUnion, type ZodObject, type ZodRawShape, z } from 'zod';
|
|
12
12
|
import type { HandlerContext, ReasonOf } from '../../../core/context.js';
|
|
13
13
|
import type { ErrorContract } from '../../../types-global/errors.js';
|
|
14
14
|
export { type DisabledMetadata, disabledTool } from './disabled-tool.js';
|
|
@@ -82,6 +82,23 @@ export type EnrichmentTrailerConfig<TEnrich extends ZodRawShape | undefined> = T
|
|
|
82
82
|
render?(value: z.infer<TEnrich[K]>): string;
|
|
83
83
|
};
|
|
84
84
|
} : never;
|
|
85
|
+
/**
|
|
86
|
+
* What a tool may declare as its `input` root.
|
|
87
|
+
*
|
|
88
|
+
* A `z.object()` is the common shape. A `z.discriminatedUnion()` is the
|
|
89
|
+
* multi-mode shape: mutually exclusive argument sets with a literal
|
|
90
|
+
* discriminator and per-variant required fields. It advertises as
|
|
91
|
+
* `{"type":"object","oneOf":[<branch>, …]}` — branches intact, each carrying
|
|
92
|
+
* its own `required` and `const`-tagged discriminator — with identical bytes on
|
|
93
|
+
* a 2025-11-25 and a 2026-07-28 connection, since the legacy projection
|
|
94
|
+
* inspects `outputSchema` alone.
|
|
95
|
+
*
|
|
96
|
+
* Input roots may be unions; **output roots may not**. The 2025-era projection
|
|
97
|
+
* rewrites a non-object output root to `{ result: <natural> }` and wraps
|
|
98
|
+
* `structuredContent` to match, which would break the success path for every
|
|
99
|
+
* current client. `output` and `enrichment` stay `ZodObject`-only.
|
|
100
|
+
*/
|
|
101
|
+
export type ToolInputSchema = ZodDiscriminatedUnion<readonly ZodObject<ZodRawShape>[]> | ZodObject<ZodRawShape>;
|
|
85
102
|
/**
|
|
86
103
|
* Represents the complete, self-contained definition of an MCP tool.
|
|
87
104
|
*
|
|
@@ -94,7 +111,7 @@ export type EnrichmentTrailerConfig<TEnrich extends ZodRawShape | undefined> = T
|
|
|
94
111
|
* none is declared). Its inferred fields type `ctx.enrich(...)` and are advertised
|
|
95
112
|
* to clients as part of `outputSchema`.
|
|
96
113
|
*/
|
|
97
|
-
export interface ToolDefinition<TInput extends
|
|
114
|
+
export interface ToolDefinition<TInput extends ToolInputSchema = ZodObject<ZodRawShape>, TOutput extends ZodObject<ZodRawShape> = ZodObject<ZodRawShape>, TErrors extends readonly ErrorContract[] | undefined = undefined, TEnrich extends ZodRawShape | undefined = undefined> {
|
|
98
115
|
/** Protocol-level metadata (e.g., MCP Apps extension). */
|
|
99
116
|
_meta?: Record<string, unknown>;
|
|
100
117
|
/** UI/behavior hints for clients. */
|
|
@@ -193,7 +210,12 @@ export interface ToolDefinition<TInput extends ZodObject<ZodRawShape> = ZodObjec
|
|
|
193
210
|
* types remain assignable to the type-erased `AnyToolDefinition` array.
|
|
194
211
|
*/
|
|
195
212
|
handler(input: z.infer<TInput>, ctx: HandlerContext<ReasonOf<TErrors>, TEnrich>): Promise<z.infer<TOutput>> | z.infer<TOutput>;
|
|
196
|
-
/**
|
|
213
|
+
/**
|
|
214
|
+
* Zod schema for input validation. All fields need `.describe()`.
|
|
215
|
+
*
|
|
216
|
+
* A `z.object()` root, or a `z.discriminatedUnion()` of object variants for a
|
|
217
|
+
* multi-mode tool — see {@link ToolInputSchema}.
|
|
218
|
+
*/
|
|
197
219
|
input: TInput;
|
|
198
220
|
/** Programmatic unique name (snake_case). */
|
|
199
221
|
name: string;
|
|
@@ -211,7 +233,7 @@ export interface ToolDefinition<TInput extends ZodObject<ZodRawShape> = ZodObjec
|
|
|
211
233
|
title?: string;
|
|
212
234
|
}
|
|
213
235
|
/** Type-erased union for mixed arrays passed to createApp(). */
|
|
214
|
-
export type AnyToolDefinition = ToolDefinition<
|
|
236
|
+
export type AnyToolDefinition = ToolDefinition<ToolInputSchema, ZodObject<ZodRawShape>, readonly ErrorContract[] | undefined, ZodRawShape | undefined>;
|
|
215
237
|
/**
|
|
216
238
|
* Creates a tool definition with full type inference from Zod schemas.
|
|
217
239
|
*
|
|
@@ -259,5 +281,5 @@ export type AnyToolDefinition = ToolDefinition<ZodObject<ZodRawShape>, ZodObject
|
|
|
259
281
|
* });
|
|
260
282
|
* ```
|
|
261
283
|
*/
|
|
262
|
-
export declare function tool<TInput extends
|
|
284
|
+
export declare function tool<TInput extends ToolInputSchema, TOutput extends ZodObject<ZodRawShape>, const TErrors extends readonly ErrorContract[] | undefined = undefined, const TEnrich extends ZodRawShape | undefined = undefined>(name: string, options: Omit<ToolDefinition<TInput, TOutput, TErrors, TEnrich>, 'name'>): ToolDefinition<TInput, TOutput, TErrors, TEnrich>;
|
|
263
285
|
//# sourceMappingURL=toolDefinition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"toolDefinition.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* import the wrapper from the same `/tools` subpath as the builder.
|
|
8
8
|
* @module src/mcp-server/tools/utils/toolDefinition
|
|
9
9
|
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { isDiscriminatedUnionSchema } from './schemaShape.js';
|
|
10
12
|
export { disabledTool } from './disabled-tool.js';
|
|
11
13
|
// ---------------------------------------------------------------------------
|
|
12
14
|
// Builder
|
|
@@ -98,13 +100,26 @@ function assertErrorKeyUnreserved(name, output, enrichment) {
|
|
|
98
100
|
*
|
|
99
101
|
* Only the default (strip) mode is upgraded. A definition that explicitly
|
|
100
102
|
* declared `.passthrough()` or `.catchall(...)` asked for an open object, and
|
|
101
|
-
* that intent wins — Zod records it as a catchall type
|
|
102
|
-
* checks for.
|
|
103
|
+
* that intent wins — Zod records it as a catchall type (a `ZodNever` catchall
|
|
104
|
+
* for `.strict()` itself), which is what this checks for.
|
|
105
|
+
*
|
|
106
|
+
* A discriminated-union root is strictened per variant, since the branch is
|
|
107
|
+
* where the properties live and `additionalProperties` is emitted. The union is
|
|
108
|
+
* rebuilt from the strictened options rather than mutated: Zod indexes variants
|
|
109
|
+
* by discriminator value at construction time, so replacing the options on a
|
|
110
|
+
* built union would leave the index pointing at the loose ones.
|
|
103
111
|
*
|
|
104
112
|
* Root-level only, matching `.strict()` itself: a nested `z.object()` inside
|
|
105
113
|
* the input still strips unless it is strict in its own right.
|
|
106
114
|
*/
|
|
107
115
|
function strictenInput(input) {
|
|
116
|
+
if (isDiscriminatedUnionSchema(input)) {
|
|
117
|
+
const options = input.options;
|
|
118
|
+
const strictened = options.map((option) => option.def.catchall === undefined ? option.strict() : option);
|
|
119
|
+
if (strictened.every((option, i) => option === options[i]))
|
|
120
|
+
return input;
|
|
121
|
+
return z.discriminatedUnion(input.def.discriminator, strictened);
|
|
122
|
+
}
|
|
108
123
|
const declaresCatchall = input.def.catchall !== undefined;
|
|
109
124
|
return declaresCatchall ? input : input.strict();
|
|
110
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"toolDefinition.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolDefinition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAgE,CAAC,EAAE,MAAM,KAAK,CAAC;AAItF,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAyB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAwPzE,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,UAAU,IAAI,CAMlB,IAAY,EACZ,OAAwE;IAExE,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACnE,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,wBAAwB,CAC/B,IAAY,EACZ,MAA8B,EAC9B,UAAmC;IAEnC,MAAM,MAAM,GACV,OAAO,IAAI,MAAM,CAAC,KAAK;QACrB,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,UAAU,IAAI,OAAO,IAAI,UAAU;YACnC,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,SAAS,CAAC;IAClB,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,sCAAsC,MAAM,uBAAuB;QAC9E,8EAA8E;QAC9E,8EAA8E;QAC9E,uDAAuD,CAC1D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAS,aAAa,CAAiC,KAAa;IAClE,IAAI,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,OAA4C,CAAC;QACnE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACxC,MAAM,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAC7D,CAAC;QACF,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACzE,OAAO,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,UAAmB,CAAsB,CAAC;IACjG,CAAC;IACD,MAAM,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC;IAC1D,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,MAAM,EAAa,CAAC;AAC/D,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Constructs Context, checks inline auth, measures execution, formats response.
|
|
4
4
|
* @module src/mcp-server/tools/utils/toolHandlerFactory
|
|
5
5
|
*/
|
|
6
|
-
import type { CallToolResult, ContentBlock, InputRequiredResult, ServerContext } from '@modelcontextprotocol/server';
|
|
6
|
+
import type { CallToolResult, ContentBlock, InputRequiredResult, ServerContext, ServerNotifier } from '@modelcontextprotocol/server';
|
|
7
7
|
import { type ZodObject, type ZodRawShape } from 'zod';
|
|
8
8
|
import type { Context } from '../../../core/context.js';
|
|
9
9
|
import { type ResourceSubscriptions } from '../../../mcp-server/notifications.js';
|
|
@@ -32,16 +32,24 @@ export interface HandlerFactoryServices {
|
|
|
32
32
|
* overwriting an in-flight handler's notifier target (and potentially
|
|
33
33
|
* notifying the wrong server).
|
|
34
34
|
*
|
|
35
|
-
* The handler factory
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* The handler factory picks a delivery path per era via
|
|
36
|
+
* {@link selectNotifiers}, and uses these closures only as a fallback for
|
|
37
|
+
* scopes with neither a bus nor a request sender (stdio, test harnesses).
|
|
38
38
|
*/
|
|
39
39
|
export interface HandlerNotifiers {
|
|
40
|
+
/**
|
|
41
|
+
* Publish facade for the modern era's `subscriptions/listen` bus, supplied
|
|
42
|
+
* only for `modern` instances. Takes precedence over the request-scoped path:
|
|
43
|
+
* on 2026-07-28 the client opts into notification types through its listen
|
|
44
|
+
* stream, and only what reaches the bus is filtered against that opt-in
|
|
45
|
+
* (#193).
|
|
46
|
+
*/
|
|
47
|
+
bus?: ServerNotifier;
|
|
40
48
|
notifyPromptListChanged?: () => void;
|
|
41
49
|
notifyResourceListChanged?: () => void;
|
|
42
50
|
notifyResourceUpdated?: (uri: string) => void;
|
|
43
51
|
notifyToolListChanged?: () => void;
|
|
44
|
-
/** Per-connection `resources/subscribe` registry (#354). */
|
|
52
|
+
/** Per-connection `resources/subscribe` registry (#354). Legacy era only. */
|
|
45
53
|
subscriptions?: ResourceSubscriptions;
|
|
46
54
|
}
|
|
47
55
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolHandlerFactory.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolHandlerFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"toolHandlerFactory.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/utils/toolHandlerFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,cAAc,EACf,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,WAAW,EAAmB,MAAM,KAAK,CAAC;AAGlF,OAAO,KAAK,EAAE,OAAO,EAAmB,MAAM,mBAAmB,CAAC;AAYlE,OAAO,EAAE,KAAK,qBAAqB,EAAmB,MAAM,+BAA+B,CAAC;AAE5F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAY,MAAM,0BAA0B,CAAC;AAE3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAIzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,qEAAqE;AACrE,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;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;AAyBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,cAAc,CAchB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAO9E;AAMD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,iBAAiB,GAAG,SAAS,CAAC,WAAW,CAAC,CAGpF;AAmDD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,iBAAiB,GAAG,SAAS,CAAC,WAAW,CAAC,CAkCrF;AA0GD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,OAAO,EACZ,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,aAAa,EAAE,YAAY,EAAE,GAC5B,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,mBAAmB,CAAC,CAkBvD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,iBAAiB,EACtB,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,gBAAgB,GAC1B,CACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,cAAc,GAAG,mBAAmB,CAAC,CA2IjD"}
|
|
@@ -7,7 +7,7 @@ import { ZodError, z } from 'zod';
|
|
|
7
7
|
import { config } from '../../../config/index.js';
|
|
8
8
|
import { attachTypedFail, createContext, readContentStore, readEnrichmentStore, } from '../../../core/context.js';
|
|
9
9
|
import { createContextInputs, createRequestInput, isInputRequiredSignal, } from '../../../mcp-server/inputRequired.js';
|
|
10
|
-
import {
|
|
10
|
+
import { selectNotifiers } from '../../../mcp-server/notifications.js';
|
|
11
11
|
import { withRequiredScopes } from '../../../mcp-server/transports/auth/lib/authUtils.js';
|
|
12
12
|
import { McpError } from '../../../types-global/errors.js';
|
|
13
13
|
import { ErrorHandler } from '../../../utils/internal/error-handler/errorHandler.js';
|
|
@@ -349,11 +349,7 @@ export function createToolHandler(def, services, notifiers) {
|
|
|
349
349
|
return async (input, serverContext) => {
|
|
350
350
|
const mcpReq = serverContext?.mcpReq;
|
|
351
351
|
const signal = mcpReq?.signal ?? new AbortController().signal;
|
|
352
|
-
|
|
353
|
-
// this request's `ctx.mcpReq.notify` so they carry `relatedRequestId` and
|
|
354
|
-
// reach the client under per-request serving (#135). Fall back to the
|
|
355
|
-
// server-level notifiers when the scope exposes no sender.
|
|
356
|
-
const effectiveNotifiers = buildRequestScopedNotifiers(mcpReq ?? {}, notifiers.subscriptions) ?? notifiers;
|
|
352
|
+
const effectiveNotifiers = selectNotifiers(notifiers, mcpReq);
|
|
357
353
|
const sdkSessionId = typeof serverContext?.sessionId === 'string' ? serverContext.sessionId : undefined;
|
|
358
354
|
// Surface sessionId on `Context` only when it has request-spanning
|
|
359
355
|
// lifetime — stateful HTTP (or `auto`, which resolves to stateful for
|
|
@@ -387,31 +383,41 @@ export function createToolHandler(def, services, notifiers) {
|
|
|
387
383
|
}
|
|
388
384
|
// Validate input
|
|
389
385
|
const validatedInput = def.input.parse(input);
|
|
390
|
-
// Construct Context with detected capabilities
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
inputs: createContextInputs(mcpReq),
|
|
400
|
-
requestInput: createRequestInput(),
|
|
401
|
-
...(mcpReq?.log && { wireLog: mcpReq.log }),
|
|
402
|
-
notifyPromptListChanged: effectiveNotifiers.notifyPromptListChanged,
|
|
403
|
-
notifyResourceListChanged: effectiveNotifiers.notifyResourceListChanged,
|
|
404
|
-
notifyResourceUpdated: effectiveNotifiers.notifyResourceUpdated,
|
|
405
|
-
notifyToolListChanged: effectiveNotifiers.notifyToolListChanged,
|
|
406
|
-
}), def.errors);
|
|
386
|
+
// Construct Context with detected capabilities, from inside the execution
|
|
387
|
+
// span so `ctx.traceId` / `ctx.spanId` — and the child logger built from
|
|
388
|
+
// them — name the `tool_execution:*` span the handler runs in rather than
|
|
389
|
+
// the enclosing request span (#296). When the definition declares an error
|
|
390
|
+
// contract, `attachTypedFail` adds `ctx.fail` so handlers can
|
|
391
|
+
// `throw ctx.fail('reason', ...)`; otherwise ctx is unchanged.
|
|
392
|
+
// Assigned by the measured callback below and read after it settles, on
|
|
393
|
+
// both the success and error paths.
|
|
394
|
+
let ctx;
|
|
407
395
|
// Execute handler with performance measurement.
|
|
408
396
|
// Wrap with Promise.resolve — handler may return sync or async.
|
|
409
|
-
const result = await measureToolExecution(() =>
|
|
410
|
-
|
|
397
|
+
const result = await measureToolExecution((spanContext) => {
|
|
398
|
+
ctx = attachTypedFail(createContext({
|
|
399
|
+
appContext: spanContext,
|
|
400
|
+
logger: services.logger,
|
|
401
|
+
storage: services.storage,
|
|
402
|
+
signal,
|
|
403
|
+
sessionId: handlerSessionId,
|
|
404
|
+
inputs: createContextInputs(mcpReq),
|
|
405
|
+
requestInput: createRequestInput(),
|
|
406
|
+
...(mcpReq?.log && { wireLog: mcpReq.log }),
|
|
407
|
+
notifyPromptListChanged: effectiveNotifiers.notifyPromptListChanged,
|
|
408
|
+
notifyResourceListChanged: effectiveNotifiers.notifyResourceListChanged,
|
|
409
|
+
notifyResourceUpdated: effectiveNotifiers.notifyResourceUpdated,
|
|
410
|
+
notifyToolListChanged: effectiveNotifiers.notifyToolListChanged,
|
|
411
|
+
}), def.errors);
|
|
412
|
+
return Promise.resolve(def.handler(validatedInput, ctx));
|
|
413
|
+
}, { ...appContext, toolName: def.name }, validatedInput, () => {
|
|
414
|
+
const store = ctx ? readEnrichmentStore(ctx) : undefined;
|
|
411
415
|
return store && Object.keys(store.values).length > 0
|
|
412
416
|
? { [ATTR_MCP_TOOL_ENRICHED]: true }
|
|
413
417
|
: {};
|
|
414
418
|
});
|
|
419
|
+
// Assigned by the measured callback above before the handler ran.
|
|
420
|
+
const handlerCtx = ctx;
|
|
415
421
|
const validatedResult = def.output.parse(result);
|
|
416
422
|
// Render content[] from the domain payload only (Resolution B). Isolate
|
|
417
423
|
// formatter errors from handler errors so they get classified correctly.
|
|
@@ -426,12 +432,12 @@ export function createToolHandler(def, services, notifiers) {
|
|
|
426
432
|
// ride content[] only — never structuredContent — so a handler can surface
|
|
427
433
|
// media for the model without the base64 duplicating into the typed output.
|
|
428
434
|
// Empty for tools that never call ctx.content, leaving content[] unchanged.
|
|
429
|
-
const collected = readContentStore(
|
|
435
|
+
const collected = readContentStore(handlerCtx)?.blocks;
|
|
430
436
|
if (collected && collected.length > 0) {
|
|
431
437
|
domainContent = [...collected, ...domainContent];
|
|
432
438
|
}
|
|
433
439
|
// Merge enrichment into structuredContent and append the content[] trailer.
|
|
434
|
-
return buildToolSuccessResult(def,
|
|
440
|
+
return buildToolSuccessResult(def, handlerCtx, validatedResult, domainContent);
|
|
435
441
|
}
|
|
436
442
|
catch (error) {
|
|
437
443
|
// `ctx.requestInput(...)` is protocol control flow, not a failure: return
|