alepha 0.20.2 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
- package/assets/swagger-ui/swagger-ui.css +1 -1
- package/dist/api/audits/index.browser.js +49 -0
- package/dist/api/audits/index.browser.js.map +1 -1
- package/dist/api/audits/index.js +49 -0
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +2 -61
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +4 -4
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +1 -10
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.browser.js +37 -0
- package/dist/api/parameters/index.browser.js.map +1 -1
- package/dist/api/parameters/index.d.ts +12 -68
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +57 -4
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.js.map +1 -1
- package/dist/api/users/index.browser.js +6 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +148 -227
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +60 -14
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +2 -1
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/bucket/index.d.ts +77 -107
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +153 -5
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +12 -2
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +26 -0
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +11 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +11 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/captcha/index.js.map +1 -1
- package/dist/cli/config/index.d.ts +7 -5
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -3
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +637 -11660
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +707 -532
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +4 -8
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +20 -16
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +51 -77
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +65 -15
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +10 -13
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +30 -12
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/command/index.js +1 -1
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +27 -3
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +8 -11
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -3
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -3
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/crypto/index.js.map +1 -1
- package/dist/datetime/index.d.ts +69 -10
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +135 -13
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/core/index.js.map +1 -1
- package/dist/email/smtp/index.js +130 -16
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +30 -2
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +35 -12
- package/dist/lock/core/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js +32 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +238 -31
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +198 -67
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +2 -362
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +18 -409
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +41 -194
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +27 -422
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.bun.js +17 -20
- package/dist/orm/postgres/index.bun.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +1 -5
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/orm/postgres/index.js +17 -20
- package/dist/orm/postgres/index.js.map +1 -1
- package/dist/react/core/index.d.ts +102 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +65 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +6 -0
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +7 -7
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +7 -1
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +6 -0
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.js +22 -17
- package/dist/react/intro/index.js.map +1 -1
- package/dist/react/router/index.browser.js +98 -4
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +58 -5
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +122 -6
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/{chunk-DBEY4PJZ.js → chunk-6Ep1yQYe.js} +1 -1
- package/dist/react/testing/index.js +1 -1
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +195 -1
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +64 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/react/websocket/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -2
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +1 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +1 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +2 -2
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +24 -10
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js +10 -3
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +1 -4
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +47 -9
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.js +19 -1
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +4 -5
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.browser.js.map +1 -1
- package/dist/system/index.js.map +1 -1
- package/dist/system/index.workerd.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/websocket/index.browser.js +32 -5
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +3 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +42 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +685 -274
- package/src/api/files/__tests__/FileController.spec.ts +1 -1
- package/src/api/jobs/__tests__/$job.spec.ts +5 -1
- package/src/api/parameters/services/ParameterProvider.ts +21 -4
- package/src/api/users/__tests__/SessionService.spec.ts +99 -0
- package/src/api/users/__tests__/UserJobs.spec.ts +67 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +15 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/jobs/UserJobs.ts +44 -17
- package/src/api/users/providers/RealmProvider.ts +4 -0
- package/src/api/users/schemas/userQuerySchema.ts +0 -1
- package/src/api/users/services/SessionService.ts +27 -0
- package/src/api/users/services/UserService.ts +1 -5
- package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
- package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
- package/src/api/verifications/services/VerificationService.ts +1 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +74 -0
- package/src/bucket/index.ts +19 -2
- package/src/bucket/primitives/$bucket.ts +9 -1
- package/src/bucket/providers/CloudflareR2Provider.ts +2 -137
- package/src/bucket/providers/NodeS3BucketProvider.ts +218 -0
- package/src/cache/core/index.ts +29 -0
- package/src/cache/core/primitives/$cache.ts +14 -1
- package/src/cli/config/defineConfig.ts +13 -15
- package/src/cli/core/__tests__/init.spec.ts +214 -7
- package/src/cli/core/commands/init.ts +12 -0
- package/src/cli/core/services/PackageManagerUtils.ts +23 -6
- package/src/cli/core/services/ProjectScaffolder.ts +315 -33
- package/src/cli/core/tasks/BuildCloudflareTask.ts +5 -0
- package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
- package/src/cli/core/tasks/BuildServerTask.ts +8 -0
- package/src/cli/core/templates/agentMd.ts +2 -10
- package/src/cli/core/templates/apiIndexTs.ts +23 -1
- package/src/cli/core/templates/componentsJsonTs.ts +39 -0
- package/src/cli/core/templates/mainCss.ts +1 -0
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
- package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
- package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
- package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
- package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
- package/src/cli/core/templates/webAppRouterTs.ts +104 -1
- package/src/cli/core/templates/webIndexTs.ts +23 -1
- package/src/cli/devtools/index.ts +12 -26
- package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
- package/src/cli/platform/index.ts +15 -24
- package/src/cli/vendor/atoms/vendorOptions.ts +1 -1
- package/src/cli/vendor/index.ts +14 -23
- package/src/command/providers/CliProvider.ts +1 -1
- package/src/core/Alepha.ts +11 -1
- package/src/core/helpers/ref.ts +18 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/interfaces/Service.ts +3 -1
- package/src/core/providers/SchemaValidator.ts +9 -1
- package/src/core/providers/TypeProvider.ts +2 -3
- package/src/datetime/REFACTORING.md +118 -0
- package/src/datetime/providers/DateTimeProvider.ts +203 -24
- package/src/lock/core/index.ts +31 -0
- package/src/lock/core/primitives/$lock.ts +14 -1
- package/src/logger/services/Logger.ts +1 -1
- package/src/mcp/__tests__/$resource.spec.ts +1 -1
- package/src/mcp/__tests__/$tool.spec.ts +1 -1
- package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
- package/src/mcp/__tests__/jsonrpc.spec.ts +1 -1
- package/src/mcp/helpers/jsonrpc.ts +26 -1
- package/src/mcp/index.ts +10 -5
- package/src/mcp/interfaces/McpTypes.ts +83 -6
- package/src/mcp/primitives/$prompt.ts +18 -1
- package/src/mcp/primitives/$resource.ts +18 -1
- package/src/mcp/primitives/$tool.ts +83 -7
- package/src/mcp/providers/McpServerProvider.ts +74 -16
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +226 -0
- package/src/orm/REFACTORING.md +330 -0
- package/src/orm/__tests__/$repository-tests.ts +1 -0
- package/src/orm/__tests__/orm-next-tests.ts +2 -67
- package/src/orm/__tests__/orm-next.spec.ts +0 -21
- package/src/orm/core/index.shared.ts +0 -2
- package/src/orm/core/index.ts +1 -2
- package/src/orm/core/primitives/$repository.ts +3 -6
- package/src/orm/core/primitives/$transactional.ts +11 -0
- package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
- package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
- package/src/orm/core/schemas/updateSchema.ts +1 -1
- package/src/orm/core/services/ModelBuilder.ts +1 -13
- package/src/orm/core/services/PgRelationManager.ts +4 -2
- package/src/orm/core/services/Repository.ts +1 -42
- package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
- package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +86 -0
- package/src/react/core/hooks/useQuery.ts +153 -0
- package/src/react/core/index.ts +1 -0
- package/src/react/form/services/FormModel.ts +15 -6
- package/src/react/form/services/parseField.ts +8 -0
- package/src/react/i18n/providers/I18nProvider.ts +8 -2
- package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
- package/src/react/router/__tests__/$page.spec.tsx +0 -16
- package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
- package/src/react/router/__tests__/ssr.spec.tsx +339 -0
- package/src/react/router/primitives/$page.ts +28 -4
- package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
- package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
- package/src/react/router/providers/ReactPageProvider.ts +27 -9
- package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
- package/src/react/router/providers/ReactServerProvider.ts +1 -0
- package/src/react/ui/atoms/uiThemeListAtom.ts +36 -0
- package/src/react/ui/index.ts +6 -0
- package/src/react/ui/services/SchemaControl.ts +209 -0
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/primitives/$basicAuth.ts +1 -1
- package/src/security/primitives/$issuer.ts +6 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +75 -0
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +306 -0
- package/src/server/core/errors/ValidationError.ts +13 -1
- package/src/server/core/interfaces/ServerRequest.ts +1 -0
- package/src/server/core/primitives/$action.ts +16 -5
- package/src/server/core/providers/ServerProvider.ts +1 -1
- package/src/server/core/providers/ServerRouterProvider.ts +28 -6
- package/src/server/core/services/HttpClient.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +6 -8
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +10 -4
- package/src/websocket/services/WebSocketClient.ts +11 -5
- package/src/mcp/transports/SseMcpTransport.ts +0 -182
- package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
- package/src/orm/core/helpers/parseQueryString.ts +0 -502
- package/src/orm/core/primitives/$view.ts +0 -88
|
@@ -25,7 +25,7 @@ describe("jsonrpc constants", () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
test("MCP_PROTOCOL_VERSION should be defined", () => {
|
|
28
|
-
expect(MCP_PROTOCOL_VERSION).toBe("
|
|
28
|
+
expect(MCP_PROTOCOL_VERSION).toBe("2025-11-25");
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
test("JsonRpcErrorCodes should have correct values", () => {
|
|
@@ -12,7 +12,32 @@ import type {
|
|
|
12
12
|
|
|
13
13
|
export const JSONRPC_VERSION = "2.0" as const;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The latest MCP protocol revision Alepha targets.
|
|
17
|
+
* See {@link SUPPORTED_PROTOCOL_VERSIONS} for the full negotiation list.
|
|
18
|
+
*/
|
|
19
|
+
export const MCP_PROTOCOL_VERSION = "2025-11-25" as const;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Protocol versions Alepha will accept during `initialize` negotiation,
|
|
23
|
+
* highest preference first. The server echoes back whichever version the
|
|
24
|
+
* client requested if it appears here, otherwise picks the first entry.
|
|
25
|
+
*/
|
|
26
|
+
export const SUPPORTED_PROTOCOL_VERSIONS = [
|
|
27
|
+
"2025-11-25",
|
|
28
|
+
"2025-06-18",
|
|
29
|
+
"2025-03-26",
|
|
30
|
+
"2024-11-05",
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
33
|
+
export type SupportedProtocolVersion =
|
|
34
|
+
(typeof SUPPORTED_PROTOCOL_VERSIONS)[number];
|
|
35
|
+
|
|
36
|
+
export const isSupportedProtocolVersion = (
|
|
37
|
+
v: unknown,
|
|
38
|
+
): v is SupportedProtocolVersion =>
|
|
39
|
+
typeof v === "string" &&
|
|
40
|
+
(SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(v);
|
|
16
41
|
|
|
17
42
|
export const JsonRpcErrorCodes = {
|
|
18
43
|
PARSE_ERROR: -32700,
|
package/src/mcp/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { $prompt } from "./primitives/$prompt.ts";
|
|
|
3
3
|
import { $resource } from "./primitives/$resource.ts";
|
|
4
4
|
import { $tool } from "./primitives/$tool.ts";
|
|
5
5
|
import { McpServerProvider } from "./providers/McpServerProvider.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { StreamableHttpMcpTransport } from "./transports/StreamableHttpMcpTransport.ts";
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
9
9
|
|
|
@@ -28,12 +28,15 @@ export {
|
|
|
28
28
|
createParseError,
|
|
29
29
|
createResponse,
|
|
30
30
|
isNotification,
|
|
31
|
+
isSupportedProtocolVersion,
|
|
31
32
|
isValidJsonRpcRequest,
|
|
32
33
|
JSONRPC_VERSION,
|
|
33
34
|
JsonRpcErrorCodes,
|
|
34
35
|
JsonRpcParseError,
|
|
35
36
|
MCP_PROTOCOL_VERSION,
|
|
36
37
|
parseMessage,
|
|
38
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
39
|
+
type SupportedProtocolVersion,
|
|
37
40
|
} from "./helpers/jsonrpc.ts";
|
|
38
41
|
export type {
|
|
39
42
|
JsonRpcError,
|
|
@@ -88,8 +91,10 @@ export { $tool, ToolPrimitive } from "./primitives/$tool.ts";
|
|
|
88
91
|
export { McpServerProvider } from "./providers/McpServerProvider.ts";
|
|
89
92
|
export {
|
|
90
93
|
mcpSseOptions,
|
|
94
|
+
mcpStreamableHttpOptions,
|
|
91
95
|
SseMcpTransport,
|
|
92
|
-
|
|
96
|
+
StreamableHttpMcpTransport,
|
|
97
|
+
} from "./transports/StreamableHttpMcpTransport.ts";
|
|
93
98
|
|
|
94
99
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
95
100
|
|
|
@@ -101,7 +106,7 @@ export {
|
|
|
101
106
|
* - MCP tool definitions
|
|
102
107
|
* - MCP prompt definitions
|
|
103
108
|
* - JSON-RPC protocol
|
|
104
|
-
* -
|
|
109
|
+
* - Streamable HTTP transport (spec 2025-03-26+)
|
|
105
110
|
*
|
|
106
111
|
* @module alepha.mcp
|
|
107
112
|
*/
|
|
@@ -109,6 +114,6 @@ export const AlephaMcp = $module({
|
|
|
109
114
|
name: "alepha.mcp",
|
|
110
115
|
primitives: [$tool, $resource, $prompt],
|
|
111
116
|
services: [McpServerProvider],
|
|
112
|
-
// Transports are opt-in — user wires the one(s) they need via alepha.with(
|
|
113
|
-
variants: [
|
|
117
|
+
// Transports are opt-in — user wires the one(s) they need via alepha.with(StreamableHttpMcpTransport).
|
|
118
|
+
variants: [StreamableHttpMcpTransport],
|
|
114
119
|
});
|
|
@@ -40,14 +40,48 @@ export interface McpCapabilities {
|
|
|
40
40
|
prompts?: Record<string, never>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Spec 2025-11-25: optional `description` aligns with the MCP registry's
|
|
45
|
+
* `server.json` format and provides human-readable context during init.
|
|
46
|
+
*/
|
|
43
47
|
export interface McpServerInfo {
|
|
44
48
|
name: string;
|
|
45
49
|
version: string;
|
|
50
|
+
description?: string;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
export interface McpClientInfo {
|
|
49
54
|
name: string;
|
|
50
55
|
version: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Icon descriptor (spec 2025-11-25 / SEP-973). Mirrors web app manifest
|
|
61
|
+
* icon shape — clients render these in tool palettes / picker UIs.
|
|
62
|
+
*/
|
|
63
|
+
export interface McpIcon {
|
|
64
|
+
src: string;
|
|
65
|
+
mimeType?: string;
|
|
66
|
+
sizes?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Tool annotations (spec 2025-03-26+). Hints to the client about how to
|
|
71
|
+
* present and gate the tool. None are guarantees — the client uses these
|
|
72
|
+
* heuristically (e.g. to show a confirmation prompt for destructive tools).
|
|
73
|
+
*/
|
|
74
|
+
export interface McpToolAnnotations {
|
|
75
|
+
/** Human-friendly display title (distinct from `name`, the programmatic id). */
|
|
76
|
+
title?: string;
|
|
77
|
+
/** Tool reads only; safe to auto-approve. */
|
|
78
|
+
readOnlyHint?: boolean;
|
|
79
|
+
/** Tool may delete or overwrite data; client should require confirmation. */
|
|
80
|
+
destructiveHint?: boolean;
|
|
81
|
+
/** Calling the tool with the same args twice yields the same end state. */
|
|
82
|
+
idempotentHint?: boolean;
|
|
83
|
+
/** Tool interacts with the open world (network, etc.) vs. a closed system. */
|
|
84
|
+
openWorldHint?: boolean;
|
|
51
85
|
}
|
|
52
86
|
|
|
53
87
|
export interface McpInitializeParams {
|
|
@@ -68,14 +102,27 @@ export interface McpInitializeResult {
|
|
|
68
102
|
|
|
69
103
|
export interface McpToolDescriptor {
|
|
70
104
|
name: string;
|
|
105
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
106
|
+
title?: string;
|
|
71
107
|
description: string;
|
|
72
108
|
inputSchema: McpJsonSchema;
|
|
109
|
+
/** Output schema enabling `structuredContent` on call results (spec 2025-06-18). */
|
|
110
|
+
outputSchema?: McpJsonSchema;
|
|
111
|
+
/** Behavior hints (spec 2025-03-26+). */
|
|
112
|
+
annotations?: McpToolAnnotations;
|
|
113
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
114
|
+
icons?: McpIcon[];
|
|
115
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
116
|
+
_meta?: Record<string, unknown>;
|
|
73
117
|
}
|
|
74
118
|
|
|
75
119
|
export interface McpJsonSchema {
|
|
76
120
|
type: string;
|
|
77
121
|
properties?: Record<string, unknown>;
|
|
78
122
|
required?: string[];
|
|
123
|
+
/** JSON Schema dialect (spec 2025-11-25 / SEP-1613 — defaults to 2020-12). */
|
|
124
|
+
$schema?: string;
|
|
125
|
+
[key: string]: unknown;
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
export interface McpToolCallParams {
|
|
@@ -85,15 +132,33 @@ export interface McpToolCallParams {
|
|
|
85
132
|
|
|
86
133
|
export interface McpToolCallResult {
|
|
87
134
|
content: McpContent[];
|
|
135
|
+
/**
|
|
136
|
+
* Structured tool output (spec 2025-06-18). When the tool declares an
|
|
137
|
+
* `outputSchema`, the server MUST populate `structuredContent`; the
|
|
138
|
+
* `content` array carrying a JSON-stringified text block is kept as
|
|
139
|
+
* a back-compat fallback for older clients.
|
|
140
|
+
*/
|
|
141
|
+
structuredContent?: unknown;
|
|
88
142
|
isError?: boolean;
|
|
143
|
+
_meta?: Record<string, unknown>;
|
|
89
144
|
}
|
|
90
145
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
146
|
+
/**
|
|
147
|
+
* Discriminated content union covering text, image, audio (added 2025-03-26),
|
|
148
|
+
* inlined resources, and resource links (added 2025-06-18).
|
|
149
|
+
*/
|
|
150
|
+
export type McpContent =
|
|
151
|
+
| { type: "text"; text: string }
|
|
152
|
+
| { type: "image"; data: string; mimeType: string }
|
|
153
|
+
| { type: "audio"; data: string; mimeType: string }
|
|
154
|
+
| { type: "resource"; resource: McpResourceContent }
|
|
155
|
+
| {
|
|
156
|
+
type: "resource_link";
|
|
157
|
+
uri: string;
|
|
158
|
+
name: string;
|
|
159
|
+
description?: string;
|
|
160
|
+
mimeType?: string;
|
|
161
|
+
};
|
|
97
162
|
|
|
98
163
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
99
164
|
// Resource Types
|
|
@@ -102,8 +167,14 @@ export interface McpContent {
|
|
|
102
167
|
export interface McpResourceDescriptor {
|
|
103
168
|
uri: string;
|
|
104
169
|
name: string;
|
|
170
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
171
|
+
title?: string;
|
|
105
172
|
description?: string;
|
|
106
173
|
mimeType?: string;
|
|
174
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
175
|
+
icons?: McpIcon[];
|
|
176
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
177
|
+
_meta?: Record<string, unknown>;
|
|
107
178
|
}
|
|
108
179
|
|
|
109
180
|
export interface McpResourceReadParams {
|
|
@@ -127,8 +198,14 @@ export interface McpResourceContent {
|
|
|
127
198
|
|
|
128
199
|
export interface McpPromptDescriptor {
|
|
129
200
|
name: string;
|
|
201
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
202
|
+
title?: string;
|
|
130
203
|
description?: string;
|
|
131
204
|
arguments?: McpPromptArgument[];
|
|
205
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
206
|
+
icons?: McpIcon[];
|
|
207
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
208
|
+
_meta?: Record<string, unknown>;
|
|
132
209
|
}
|
|
133
210
|
|
|
134
211
|
export interface McpPromptArgument {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "alepha";
|
|
11
11
|
import type {
|
|
12
12
|
McpContext,
|
|
13
|
+
McpIcon,
|
|
13
14
|
McpPromptArgument,
|
|
14
15
|
McpPromptDescriptor,
|
|
15
16
|
PromptHandlerArgs,
|
|
@@ -80,6 +81,12 @@ export interface PromptPrimitiveOptions<T extends TObject> {
|
|
|
80
81
|
*/
|
|
81
82
|
name?: string;
|
|
82
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Human-friendly display title (spec 2025-11-25). Distinct from `name`,
|
|
86
|
+
* which remains the programmatic identifier.
|
|
87
|
+
*/
|
|
88
|
+
title?: string;
|
|
89
|
+
|
|
83
90
|
/**
|
|
84
91
|
* Description of what this prompt does.
|
|
85
92
|
*
|
|
@@ -89,6 +96,11 @@ export interface PromptPrimitiveOptions<T extends TObject> {
|
|
|
89
96
|
*/
|
|
90
97
|
description?: string;
|
|
91
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Optional icons surfaced in client UIs (spec 2025-11-25 / SEP-973).
|
|
101
|
+
*/
|
|
102
|
+
icons?: McpIcon[];
|
|
103
|
+
|
|
92
104
|
/**
|
|
93
105
|
* TypeBox schema defining the prompt arguments.
|
|
94
106
|
*
|
|
@@ -157,13 +169,18 @@ export class PromptPrimitive<T extends TObject> extends Primitive<
|
|
|
157
169
|
* Convert the prompt to an MCP prompt descriptor for protocol messages.
|
|
158
170
|
*/
|
|
159
171
|
public toDescriptor(): McpPromptDescriptor {
|
|
160
|
-
|
|
172
|
+
const descriptor: McpPromptDescriptor = {
|
|
161
173
|
name: this.name,
|
|
162
174
|
description: this.description,
|
|
163
175
|
arguments: this.options.args
|
|
164
176
|
? this.schemaToArguments(this.options.args)
|
|
165
177
|
: [],
|
|
166
178
|
};
|
|
179
|
+
if (this.options.title) descriptor.title = this.options.title;
|
|
180
|
+
if (this.options.icons && this.options.icons.length > 0) {
|
|
181
|
+
descriptor.icons = this.options.icons;
|
|
182
|
+
}
|
|
183
|
+
return descriptor;
|
|
167
184
|
}
|
|
168
185
|
|
|
169
186
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { $inject, createPrimitive, KIND, Primitive } from "alepha";
|
|
2
2
|
import type {
|
|
3
3
|
McpContext,
|
|
4
|
+
McpIcon,
|
|
4
5
|
McpResourceDescriptor,
|
|
5
6
|
ResourceContent,
|
|
6
7
|
ResourceHandler,
|
|
@@ -78,6 +79,17 @@ export interface ResourcePrimitiveOptions {
|
|
|
78
79
|
*/
|
|
79
80
|
name?: string;
|
|
80
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Human-friendly display title (spec 2025-11-25). Distinct from `name`,
|
|
84
|
+
* which remains the programmatic identifier.
|
|
85
|
+
*/
|
|
86
|
+
title?: string;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Optional icons surfaced in client UIs (spec 2025-11-25 / SEP-973).
|
|
90
|
+
*/
|
|
91
|
+
icons?: McpIcon[];
|
|
92
|
+
|
|
81
93
|
/**
|
|
82
94
|
* Description of what this resource contains.
|
|
83
95
|
*
|
|
@@ -159,12 +171,17 @@ export class ResourcePrimitive extends Primitive<ResourcePrimitiveOptions> {
|
|
|
159
171
|
* Convert the resource to an MCP resource descriptor for protocol messages.
|
|
160
172
|
*/
|
|
161
173
|
public toDescriptor(): McpResourceDescriptor {
|
|
162
|
-
|
|
174
|
+
const descriptor: McpResourceDescriptor = {
|
|
163
175
|
uri: this.uri,
|
|
164
176
|
name: this.name,
|
|
165
177
|
description: this.description,
|
|
166
178
|
mimeType: this.mimeType,
|
|
167
179
|
};
|
|
180
|
+
if (this.options.title) descriptor.title = this.options.title;
|
|
181
|
+
if (this.options.icons && this.options.icons.length > 0) {
|
|
182
|
+
descriptor.icons = this.options.icons;
|
|
183
|
+
}
|
|
184
|
+
return descriptor;
|
|
168
185
|
}
|
|
169
186
|
}
|
|
170
187
|
|
|
@@ -10,7 +10,9 @@ import {
|
|
|
10
10
|
} from "alepha";
|
|
11
11
|
import type {
|
|
12
12
|
McpContext,
|
|
13
|
+
McpIcon,
|
|
13
14
|
McpJsonSchema,
|
|
15
|
+
McpToolAnnotations,
|
|
14
16
|
McpToolDescriptor,
|
|
15
17
|
ToolHandlerArgs,
|
|
16
18
|
ToolHandlerResult,
|
|
@@ -84,6 +86,15 @@ export interface ToolPrimitiveOptions<T extends ToolPrimitiveSchema> {
|
|
|
84
86
|
*/
|
|
85
87
|
name?: string;
|
|
86
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Human-friendly display title (spec 2025-11-25). Distinct from `name`,
|
|
91
|
+
* which remains the programmatic identifier. Clients use `title` in
|
|
92
|
+
* tool palettes / picker UIs.
|
|
93
|
+
*
|
|
94
|
+
* @example "Search Lore"
|
|
95
|
+
*/
|
|
96
|
+
title?: string;
|
|
97
|
+
|
|
87
98
|
/**
|
|
88
99
|
* A human-readable description of what the tool does.
|
|
89
100
|
*
|
|
@@ -95,6 +106,18 @@ export interface ToolPrimitiveOptions<T extends ToolPrimitiveSchema> {
|
|
|
95
106
|
*/
|
|
96
107
|
description: string;
|
|
97
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Behavior hints (spec 2025-03-26+). Clients use these to gate UI prompts
|
|
111
|
+
* (e.g. require confirmation before a tool with `destructiveHint: true`).
|
|
112
|
+
* None are guarantees — they are heuristics for the client, not the model.
|
|
113
|
+
*/
|
|
114
|
+
annotations?: McpToolAnnotations;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Icons surfaced in client tool palettes / picker UIs (spec 2025-11-25).
|
|
118
|
+
*/
|
|
119
|
+
icons?: McpIcon[];
|
|
120
|
+
|
|
98
121
|
/**
|
|
99
122
|
* TypeBox schema defining the tool's parameters and result type.
|
|
100
123
|
*
|
|
@@ -141,6 +164,15 @@ export class ToolPrimitive<T extends ToolPrimitiveSchema> extends Primitive<
|
|
|
141
164
|
return this.options.description;
|
|
142
165
|
}
|
|
143
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Whether the tool declared a result schema. When true, `tools/call`
|
|
169
|
+
* responses include `structuredContent` populated with the validated
|
|
170
|
+
* result (spec 2025-06-18).
|
|
171
|
+
*/
|
|
172
|
+
public hasOutputSchema(): boolean {
|
|
173
|
+
return !!this.options.schema?.result;
|
|
174
|
+
}
|
|
175
|
+
|
|
144
176
|
protected onInit(): void {
|
|
145
177
|
this.mcpServer.registerTool(this);
|
|
146
178
|
}
|
|
@@ -184,21 +216,57 @@ export class ToolPrimitive<T extends ToolPrimitiveSchema> extends Primitive<
|
|
|
184
216
|
|
|
185
217
|
/**
|
|
186
218
|
* Convert the tool to an MCP tool descriptor for protocol messages.
|
|
219
|
+
*
|
|
220
|
+
* Emits the spec 2025-11-25 surface: `title`, `annotations`, `icons`,
|
|
221
|
+
* and (when `schema.result` is defined) `outputSchema` so the server
|
|
222
|
+
* can populate `structuredContent` on call results.
|
|
187
223
|
*/
|
|
188
224
|
public toDescriptor(): McpToolDescriptor {
|
|
189
|
-
|
|
225
|
+
const inputSchema: McpJsonSchema = this.options.schema?.params
|
|
226
|
+
? this.schemaToJsonSchema(this.options.schema.params)
|
|
227
|
+
: { type: "object", properties: {}, required: [] };
|
|
228
|
+
|
|
229
|
+
const descriptor: McpToolDescriptor = {
|
|
190
230
|
name: this.name,
|
|
191
231
|
description: this.description,
|
|
192
|
-
inputSchema
|
|
193
|
-
? this.schemaToJsonSchema(this.options.schema.params)
|
|
194
|
-
: { type: "object", properties: {}, required: [] },
|
|
232
|
+
inputSchema,
|
|
195
233
|
};
|
|
234
|
+
|
|
235
|
+
if (this.options.title) descriptor.title = this.options.title;
|
|
236
|
+
if (this.options.annotations)
|
|
237
|
+
descriptor.annotations = this.options.annotations;
|
|
238
|
+
if (this.options.icons && this.options.icons.length > 0) {
|
|
239
|
+
descriptor.icons = this.options.icons;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Output schema is emitted when the tool declares `schema.result`,
|
|
243
|
+
// unlocking structured content on tools/call responses.
|
|
244
|
+
if (this.options.schema?.result) {
|
|
245
|
+
const out = this.propertyToJsonSchema(this.options.schema.result);
|
|
246
|
+
// The result schema may be a primitive — wrap so the descriptor
|
|
247
|
+
// value is always a JSON Schema object with `type`.
|
|
248
|
+
descriptor.outputSchema = (
|
|
249
|
+
typeof out === "object" && out !== null && "type" in out
|
|
250
|
+
? out
|
|
251
|
+
: { type: "object", properties: {}, required: [] }
|
|
252
|
+
) as McpJsonSchema;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return descriptor;
|
|
196
256
|
}
|
|
197
257
|
|
|
198
258
|
/**
|
|
199
259
|
* Convert a TypeBox schema to JSON Schema format.
|
|
260
|
+
*
|
|
261
|
+
* Emits the 2020-12 dialect annotation at the root (spec 2025-11-25 /
|
|
262
|
+
* SEP-1613 — JSON Schema 2020-12 is the default dialect for MCP).
|
|
263
|
+
* The TypeBox shapes Alepha emits today are already 2020-12-compatible;
|
|
264
|
+
* this is just the dialect declaration.
|
|
200
265
|
*/
|
|
201
|
-
protected schemaToJsonSchema(
|
|
266
|
+
protected schemaToJsonSchema(
|
|
267
|
+
schema: TObject,
|
|
268
|
+
options?: { root?: boolean },
|
|
269
|
+
): McpJsonSchema {
|
|
202
270
|
const properties: Record<string, unknown> = {};
|
|
203
271
|
const required: string[] = [];
|
|
204
272
|
|
|
@@ -211,11 +279,19 @@ export class ToolPrimitive<T extends ToolPrimitiveSchema> extends Primitive<
|
|
|
211
279
|
}
|
|
212
280
|
}
|
|
213
281
|
|
|
214
|
-
|
|
282
|
+
const result: McpJsonSchema = {
|
|
215
283
|
type: "object",
|
|
216
284
|
properties,
|
|
217
285
|
required,
|
|
218
286
|
};
|
|
287
|
+
|
|
288
|
+
// Annotate the dialect on the root schema only (avoid noise on nested
|
|
289
|
+
// sub-schemas where MCP doesn't expect $schema).
|
|
290
|
+
if (options?.root !== false) {
|
|
291
|
+
result.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
219
295
|
}
|
|
220
296
|
|
|
221
297
|
/**
|
|
@@ -251,7 +327,7 @@ export class ToolPrimitive<T extends ToolPrimitiveSchema> extends Primitive<
|
|
|
251
327
|
result.items = this.propertyToJsonSchema(schema.items as TSchema);
|
|
252
328
|
}
|
|
253
329
|
} else if (t.schema.isObject(schema)) {
|
|
254
|
-
Object.assign(result, this.schemaToJsonSchema(schema));
|
|
330
|
+
Object.assign(result, this.schemaToJsonSchema(schema, { root: false }));
|
|
255
331
|
} else if (t.schema.isUnsafe(schema) || t.schema.isOptional(schema)) {
|
|
256
332
|
// Handle Unsafe types (like t.enum) and optional wrappers by checking the underlying type property
|
|
257
333
|
const schemaAny = schema as { type?: string; enum?: unknown[] };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $inject, Alepha } from "alepha";
|
|
1
|
+
import { $inject, Alepha, TypeBoxError } from "alepha";
|
|
2
2
|
import { $logger } from "alepha/logger";
|
|
3
3
|
import {
|
|
4
4
|
McpError,
|
|
@@ -11,13 +11,14 @@ import {
|
|
|
11
11
|
createErrorResponse,
|
|
12
12
|
createInternalError,
|
|
13
13
|
createResponse,
|
|
14
|
+
isSupportedProtocolVersion,
|
|
14
15
|
MCP_PROTOCOL_VERSION,
|
|
16
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
15
17
|
} from "../helpers/jsonrpc.ts";
|
|
16
18
|
import type {
|
|
17
19
|
JsonRpcRequest,
|
|
18
20
|
JsonRpcResponse,
|
|
19
21
|
McpCapabilities,
|
|
20
|
-
McpContent,
|
|
21
22
|
McpContext,
|
|
22
23
|
McpInitializeResult,
|
|
23
24
|
McpPromptDescriptor,
|
|
@@ -55,7 +56,20 @@ export class McpServerProvider {
|
|
|
55
56
|
|
|
56
57
|
protected initialized = false;
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Protocol version negotiated with the client during `initialize`.
|
|
61
|
+
* Used by transports to validate the `MCP-Protocol-Version` header on
|
|
62
|
+
* subsequent HTTP requests (per spec 2025-06-18+).
|
|
63
|
+
*/
|
|
64
|
+
public negotiatedVersion: string = MCP_PROTOCOL_VERSION;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Server identity returned during `initialize`. Consumers may override
|
|
68
|
+
* fields directly (e.g. `mcpServer.serverInfo = { name: "roadmap-mcp",
|
|
69
|
+
* version: "0.20.3", description: "..." }`) — the `description` field
|
|
70
|
+
* is supported per spec 2025-11-25 (minor change #2).
|
|
71
|
+
*/
|
|
72
|
+
public serverInfo: McpServerInfo = {
|
|
59
73
|
name: "alepha-mcp",
|
|
60
74
|
version: "1.0.0",
|
|
61
75
|
};
|
|
@@ -243,15 +257,25 @@ export class McpServerProvider {
|
|
|
243
257
|
protected handleInitialize(
|
|
244
258
|
params: Record<string, unknown>,
|
|
245
259
|
): McpInitializeResult {
|
|
260
|
+
const requested = params.protocolVersion;
|
|
261
|
+
// Echo the client's version when supported, otherwise reply with our
|
|
262
|
+
// preferred version (highest entry in SUPPORTED_PROTOCOL_VERSIONS).
|
|
263
|
+
// The client can then decide to retry, downgrade, or disconnect.
|
|
264
|
+
const negotiated = isSupportedProtocolVersion(requested)
|
|
265
|
+
? requested
|
|
266
|
+
: SUPPORTED_PROTOCOL_VERSIONS[0];
|
|
267
|
+
|
|
246
268
|
this.log.info("MCP client initializing", {
|
|
247
269
|
clientInfo: params.clientInfo,
|
|
248
|
-
|
|
270
|
+
requestedProtocolVersion: requested,
|
|
271
|
+
negotiatedProtocolVersion: negotiated,
|
|
249
272
|
});
|
|
250
273
|
|
|
251
274
|
this.initialized = true;
|
|
275
|
+
this.negotiatedVersion = negotiated;
|
|
252
276
|
|
|
253
277
|
return {
|
|
254
|
-
protocolVersion:
|
|
278
|
+
protocolVersion: negotiated,
|
|
255
279
|
capabilities: this.getCapabilities(),
|
|
256
280
|
serverInfo: this.serverInfo,
|
|
257
281
|
};
|
|
@@ -276,24 +300,58 @@ export class McpServerProvider {
|
|
|
276
300
|
|
|
277
301
|
const tool = this.tools.get(name);
|
|
278
302
|
if (!tool) {
|
|
303
|
+
// McpToolNotFoundError is intentionally a JSON-RPC protocol error,
|
|
304
|
+
// not a tool execution error — see SEP-1303 (only validation/runtime
|
|
305
|
+
// failures of an existing tool are reported via isError: true).
|
|
279
306
|
throw new McpToolNotFoundError(name);
|
|
280
307
|
}
|
|
281
308
|
|
|
282
309
|
try {
|
|
283
310
|
const result = await tool.execute(args, context);
|
|
284
311
|
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
312
|
+
const callResult: McpToolCallResult = {
|
|
313
|
+
content: [
|
|
314
|
+
{
|
|
315
|
+
type: "text",
|
|
316
|
+
text:
|
|
317
|
+
typeof result === "string"
|
|
318
|
+
? result
|
|
319
|
+
: JSON.stringify(result ?? null),
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// Spec 2025-06-18: when the tool declares an outputSchema, the server
|
|
325
|
+
// MUST populate `structuredContent` with the validated result. The
|
|
326
|
+
// text-stringified `content` block remains as a back-compat fallback.
|
|
327
|
+
if (tool.hasOutputSchema() && result !== undefined) {
|
|
328
|
+
callResult.structuredContent = result;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return callResult;
|
|
296
332
|
} catch (error) {
|
|
333
|
+
// Spec 2025-11-25 / SEP-1303: input-validation failures (and other
|
|
334
|
+
// tool-runtime errors) are returned as Tool Execution Errors, not
|
|
335
|
+
// JSON-RPC protocol errors, so the model can self-correct.
|
|
336
|
+
// For TypeBox validation errors we surface the failing path so the
|
|
337
|
+
// model knows which argument was malformed.
|
|
338
|
+
if (error instanceof TypeBoxError) {
|
|
339
|
+
const path = error.value?.path || "/";
|
|
340
|
+
const message = error.value?.message || error.message;
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: "text",
|
|
345
|
+
text: `Validation error at ${path}: ${message}`,
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
structuredContent: {
|
|
349
|
+
errors: [{ path, message }],
|
|
350
|
+
},
|
|
351
|
+
isError: true,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
297
355
|
return {
|
|
298
356
|
content: [
|
|
299
357
|
{
|