@alvin0/ai-agent-sdk-mcp-server 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 alvin0 (chaulamdinhai) <chaulamdinhai@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @alvin0/ai-agent-sdk-mcp-server
2
+
3
+ Runtime: **Universal** (Edge/Worker, browser, Deno, Bun, and Node).
4
+
5
+ Universal MCP server hosting built only on Web Standards and the core runtime.
6
+
7
+ ```sh
8
+ pnpm add @alvin0/ai-agent-sdk-core @alvin0/ai-agent-sdk-mcp-server
9
+ ```
10
+
11
+ Use `createMcpServer()` for an inert `Request`/`Response` host surface. The
12
+ application owns authentication and mounting; each request owns its protocol
13
+ resources, so the returned server has no fabricated application cleanup handle.
14
+
15
+ ```ts
16
+ import { createMcpServer } from '@alvin0/ai-agent-sdk-mcp-server'
17
+ ```
18
+
19
+ Composition: `host.mcp-server`. Lifecycle: `inert-host-mounted`; the host owns
20
+ authentication and request mounting, while each request owns its resources.
@@ -0,0 +1,145 @@
1
+ import { JsonObject } from "@alvin0/ai-agent-sdk-core";
2
+ import { ApprovalBroker, SdkLogger, ToolCatalog, ToolInterceptor } from "@alvin0/ai-agent-sdk-core/tools";
3
+ import { AgentSession, DefinedAgent, RuntimeAgent } from "@alvin0/ai-agent-sdk-core/agent";
4
+ //#region src/common/server-public-types.d.ts
5
+ interface McpRequestAuthInfo {
6
+ readonly token: string;
7
+ readonly clientId: string;
8
+ readonly scopes: readonly string[];
9
+ readonly expiresAt?: number;
10
+ readonly resource?: URL;
11
+ readonly extra?: Record<string, unknown>;
12
+ }
13
+ interface SdkMcpRequestContext {
14
+ readonly era: 'legacy' | 'modern';
15
+ readonly authInfo?: McpRequestAuthInfo;
16
+ readonly requestInfo?: Request;
17
+ }
18
+ interface SdkMcpCallContext {
19
+ readonly mcpReq: {
20
+ readonly id: string | number;
21
+ readonly signal: AbortSignal;
22
+ readonly log: (level: 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency', data: unknown, logger?: string) => Promise<void>;
23
+ };
24
+ readonly http?: {
25
+ readonly request?: Request;
26
+ readonly authInfo?: McpRequestAuthInfo;
27
+ };
28
+ }
29
+ interface SdkMcpHandlerRequestOptions {
30
+ readonly authInfo?: McpRequestAuthInfo;
31
+ readonly parsedBody?: unknown;
32
+ }
33
+ interface SdkMcpEventBus {
34
+ publish(event: JsonObject): void | Promise<void>;
35
+ subscribe?(listener: (event: JsonObject) => void): (() => void) | Promise<() => void>;
36
+ }
37
+ interface SdkMcpHandlerOptions {
38
+ readonly legacy?: 'stateless' | 'reject';
39
+ readonly onerror?: (error: Error) => void;
40
+ readonly responseMode?: 'auto' | 'sse' | 'json';
41
+ readonly bus?: SdkMcpEventBus | object;
42
+ readonly maxSubscriptions?: number;
43
+ readonly keepAliveMs?: number;
44
+ }
45
+ interface SdkMcpServer {
46
+ connect(transport: object): Promise<void>;
47
+ close(): Promise<void>;
48
+ /** Escape hatch for protocol-level operations without exporting upstream declarations. */
49
+ readonly server: object;
50
+ }
51
+ interface SdkMcpNotifier {
52
+ toolsChanged(): void;
53
+ promptsChanged(): void;
54
+ resourcesChanged(): void;
55
+ resourceUpdated(uri: string): void;
56
+ }
57
+ interface SdkMcpHttpHandler {
58
+ fetch(request: Request, options?: SdkMcpHandlerRequestOptions): Promise<Response>;
59
+ close(): Promise<void>;
60
+ readonly notify: SdkMcpNotifier;
61
+ readonly bus: object;
62
+ }
63
+ interface SdkMcpCallToolResult {
64
+ readonly [key: string]: unknown;
65
+ readonly content: readonly unknown[];
66
+ readonly structuredContent?: unknown;
67
+ readonly isError?: boolean | undefined;
68
+ }
69
+ //#endregion
70
+ //#region src/server/advanced.d.ts
71
+ interface McpAgentSessionContext {
72
+ readonly conversationId?: string;
73
+ readonly request: SdkMcpRequestContext;
74
+ readonly call: SdkMcpCallContext;
75
+ }
76
+ interface McpAgentTool {
77
+ readonly name: string;
78
+ readonly description?: string;
79
+ readonly agent: DefinedAgent;
80
+ /** Host-owned persistence seam: return a fresh or resumed session. */
81
+ readonly createSession: (context: McpAgentSessionContext) => AgentSession | Promise<AgentSession>;
82
+ }
83
+ interface McpServerErrorContext {
84
+ readonly operation: 'tool' | 'agent';
85
+ readonly exportName: string;
86
+ readonly requestId: string;
87
+ }
88
+ interface SdkMcpServerOptions {
89
+ readonly name: string;
90
+ readonly version: string;
91
+ readonly logger?: SdkLogger;
92
+ /** Internal family selected by the official Web/stdio host factory. */
93
+ readonly integrationFamily?: 'mcp-web-server' | 'mcp-stdio-server';
94
+ readonly instructions?: string;
95
+ /** SDK tools exposed through the existing validation/policy pipeline. */
96
+ readonly tools?: ToolCatalog;
97
+ readonly agents?: readonly McpAgentTool[];
98
+ readonly approvals?: ApprovalBroker;
99
+ readonly interceptors?: readonly ToolInterceptor[];
100
+ /** Maximum exported tools and agents. Defaults to 1,024. */
101
+ readonly maxExports?: number;
102
+ /** Maximum serialized export schema bytes. Defaults to 4 MiB. */
103
+ readonly maxDefinitionBytes?: number;
104
+ /** Maximum serialized request arguments. Defaults to 1 MiB. */
105
+ readonly maxInputBytes?: number;
106
+ /** Maximum serialized tool/agent result. Defaults to 4 MiB. */
107
+ readonly maxOutputBytes?: number;
108
+ /** Default tool/agent operation deadline. Defaults to 10 minutes. */
109
+ readonly operationTimeoutMs?: number;
110
+ /** Maximum wait after cancellation. Defaults to 30 seconds. */
111
+ readonly teardownTimeoutMs?: number;
112
+ /** Maximum time granted to the diagnostic observer. Defaults to 5 seconds. */
113
+ readonly observerTimeoutMs?: number;
114
+ /** Report host/runtime failures without giving the observer control over request completion. */
115
+ readonly onError?: (error: unknown, context: McpServerErrorContext) => void | Promise<void>;
116
+ /** Opt in to returning internal exception messages to remote callers. Defaults to false. */
117
+ readonly exposeInternalErrors?: boolean;
118
+ }
119
+ /** Create one MCP server instance for a connection or HTTP request. */
120
+ declare function createSdkMcpServer(options: SdkMcpServerOptions, request?: SdkMcpRequestContext): SdkMcpServer;
121
+ /**
122
+ * Create a fetch-shaped API for Cloudflare Workers, Deno, Bun, Next.js route
123
+ * handlers, or any web framework that accepts Request/Response.
124
+ */
125
+ declare function createSdkMcpHandler(options: SdkMcpServerOptions, handlerOptions?: SdkMcpHandlerOptions): SdkMcpHttpHandler;
126
+ //#endregion
127
+ //#region src/preferred/server.d.ts
128
+ interface McpServerDefinition {
129
+ readonly id: string;
130
+ readonly logger?: SdkLogger;
131
+ readonly tools?: ToolCatalog;
132
+ readonly agents?: Readonly<Record<string, RuntimeAgent>>;
133
+ readonly maxRequestBytes?: number;
134
+ readonly maxResponseBytes?: number;
135
+ }
136
+ interface McpWebServer {
137
+ handle(request: Request, options?: {
138
+ readonly signal?: AbortSignal;
139
+ }): Promise<Response>;
140
+ }
141
+ /** Capture one inert Web-standard server definition; each handle call owns its request resources. */
142
+ declare function createMcpServer(definition: McpServerDefinition): McpWebServer;
143
+ //#endregion
144
+ export { McpAgentSessionContext, McpAgentTool, type McpRequestAuthInfo, type McpServerDefinition, McpServerErrorContext, type McpWebServer, type SdkMcpCallContext, type SdkMcpCallToolResult, type SdkMcpEventBus, type SdkMcpHandlerOptions, type SdkMcpHandlerRequestOptions, type SdkMcpHttpHandler, type SdkMcpNotifier, type SdkMcpRequestContext, type SdkMcpServer, SdkMcpServerOptions, createMcpServer, createSdkMcpHandler, createSdkMcpServer };
145
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/common/server-public-types.ts","../src/server/advanced.ts","../src/preferred/server.ts"],"mappings":";;;;UAEiB;WACN;WACA;WACA;WACA;WACA,WAAW;WACX,QAAQ;;UAGF;WACN;WACA,WAAW;WACX,cAAc;;UAGR;WACN;aACE;aACA,QAAQ;aACR,MACP,+FACA,eACA,oBACG;;WAEE;aACE,UAAU;aACV,WAAW;;;UAIP;WACN,WAAW;WACX;;UAGM;EACf,QAAQ,OAAO,oBAAoB;EACnC,WAAW,WAAW,OAAO,qCAAqC;;UAGnD;WACN;WACA,WAAW,OAAO;WAClB;WACA,MAAM;WACN;WACA;;UAGM;EACf,QAAQ,oBAAoB;EAC5B,SAAS;;WAEA;;UAGM;EACf;EACA;EACA;EACA,gBAAgB;;UAGD;EACf,MAAM,SAAS,SAAS,UAAU,8BAA8B,QAAQ;EACxE,SAAS;WACA,QAAQ;WACR;;UAGM;YACL;WACD;WACA;WACA;;;;UCxCM;WACN;WACA,SAAS;WACT,MAAM;;UAGA;WACN;WACA;WACA,OAAO;;WAEP,gBAAgB,SAAS,2BAA2B,eAAe,QAAQ;;UAGrE;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA,SAAS;;WAET;WACA;;WAEA,QAAQ;WACR,kBAAkB;WAClB,YAAY;WACZ,wBAAwB;;WAExB;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA,WAAW,gBAAgB,SAAS,iCAAiC;;WAErE;;;iBAMK,mBACd,SAAS,qBACT,UAAS,uBACR;;;;;iBA+Ea,oBACd,SAAS,qBACT,iBAAiB,uBAChB;;;UCxKc;WACN;WACA,SAAS;WACT,QAAQ;WACR,SAAS,SAAS,eAAe;WACjC;WACA;;UAGM;EACf,OAAO,SAAS,SAAS;aAAqB,SAAS;MAAgB,QAAQ;;;iBAIjE,gBAAgB,YAAY,sBAAsB"}
package/dist/index.js ADDED
@@ -0,0 +1,789 @@
1
+ import { McpServer, createMcpHandler, fromJsonSchema } from "@modelcontextprotocol/server";
2
+ import { ToolCallId, isJsonValue, waitForSettlement } from "@alvin0/ai-agent-sdk-core";
3
+ import { dispatchToolCall } from "@alvin0/ai-agent-sdk-core/tools";
4
+
5
+ //#region src/common/integration-operation.ts
6
+ const MCP_SERVER_INTEGRATION_OPERATIONS = Object.freeze({
7
+ "mcp-web-server": Object.freeze([
8
+ "request",
9
+ "tool-call",
10
+ "agent-call"
11
+ ]),
12
+ "mcp-stdio-server": Object.freeze([
13
+ "request",
14
+ "tool-call",
15
+ "agent-call",
16
+ "close"
17
+ ])
18
+ });
19
+ const MESSAGES = Object.freeze({
20
+ start: "SDK integration operation started",
21
+ attempt: "SDK integration attempt started",
22
+ success: "SDK integration operation completed",
23
+ failure: "SDK integration operation failed",
24
+ abort: "SDK integration operation aborted"
25
+ });
26
+ function beginIntegrationOperation(logger, family, operation) {
27
+ validateOperation(family, operation);
28
+ const operationId = crypto.randomUUID(), startedAt = monotonicNow();
29
+ emit(logger, "info", MESSAGES.start, {
30
+ integrationSchemaVersion: 1,
31
+ integrationFamily: family,
32
+ integrationOperation: operation,
33
+ operationId,
34
+ kind: "logical-start"
35
+ });
36
+ let terminal = false;
37
+ const finish = (status, errorCode) => {
38
+ if (terminal) return;
39
+ terminal = true;
40
+ emit(logger, status === "error" ? "error" : "info", terminalMessage(status), {
41
+ integrationSchemaVersion: 1,
42
+ integrationFamily: family,
43
+ integrationOperation: operation,
44
+ operationId,
45
+ kind: "logical-terminal",
46
+ status,
47
+ durationMs: durationSince(startedAt),
48
+ ...errorCode === void 0 ? {} : { errorCode: boundedCode(errorCode) }
49
+ });
50
+ };
51
+ return Object.freeze({
52
+ attempt(attemptNumber) {
53
+ if (!Number.isSafeInteger(attemptNumber) || attemptNumber < 1) throw new TypeError("integration attemptNumber must be a positive safe integer");
54
+ const attemptId = crypto.randomUUID(), attemptStartedAt = monotonicNow();
55
+ emit(logger, "info", MESSAGES.attempt, {
56
+ integrationSchemaVersion: 1,
57
+ integrationFamily: family,
58
+ integrationOperation: operation,
59
+ operationId,
60
+ kind: "attempt-start",
61
+ attemptId,
62
+ attemptNumber
63
+ });
64
+ let attemptTerminal = false;
65
+ const finishAttempt = (status, errorCode) => {
66
+ if (attemptTerminal) return;
67
+ attemptTerminal = true;
68
+ emit(logger, status === "error" ? "error" : "info", terminalMessage(status), {
69
+ integrationSchemaVersion: 1,
70
+ integrationFamily: family,
71
+ integrationOperation: operation,
72
+ operationId,
73
+ kind: "attempt-terminal",
74
+ attemptId,
75
+ attemptNumber,
76
+ status,
77
+ durationMs: durationSince(attemptStartedAt),
78
+ ...errorCode === void 0 ? {} : { errorCode: boundedCode(errorCode) }
79
+ });
80
+ };
81
+ return Object.freeze({
82
+ success: () => finishAttempt("success"),
83
+ fail: (code) => finishAttempt("error", code),
84
+ abort: () => finishAttempt("aborted")
85
+ });
86
+ },
87
+ success: () => finish("success"),
88
+ fail: (code) => finish("error", code),
89
+ abort: () => finish("aborted")
90
+ });
91
+ }
92
+ function integrationErrorCode(error) {
93
+ if (typeof error === "object" && error !== null) for (const key of ["code", "name"]) {
94
+ const descriptor = Object.getOwnPropertyDescriptor(error, key);
95
+ if (descriptor !== void 0 && "value" in descriptor && typeof descriptor.value === "string") return boundedCode(descriptor.value);
96
+ }
97
+ return "INTEGRATION_ERROR";
98
+ }
99
+ function integrationChildLogger(logger, scope) {
100
+ assertIdentity$1(scope, 64, "integration scope");
101
+ try {
102
+ return logger?.child({ integrationScope: scope });
103
+ } catch {
104
+ return;
105
+ }
106
+ }
107
+ function validateOperation(family, operation) {
108
+ const operations = MCP_SERVER_INTEGRATION_OPERATIONS[family];
109
+ assertIdentity$1(family, 64, "integration family");
110
+ assertIdentity$1(operation, 64, "integration operation");
111
+ if (operations === void 0 || !operations.includes(operation)) throw new TypeError("Invalid MCP integration operation");
112
+ }
113
+ function emit(logger, level, message, fields) {
114
+ try {
115
+ logger?.[level](message, fields);
116
+ } catch {}
117
+ }
118
+ function terminalMessage(status) {
119
+ return status === "success" ? MESSAGES.success : status === "error" ? MESSAGES.failure : MESSAGES.abort;
120
+ }
121
+ function monotonicNow() {
122
+ return performance.now();
123
+ }
124
+ function durationSince(startedAt) {
125
+ const value = monotonicNow() - startedAt;
126
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
127
+ }
128
+ function boundedCode(value) {
129
+ const normalized = value.replace(/[^A-Za-z0-9_.:-]/g, "_");
130
+ return (normalized.length === 0 ? "INTEGRATION_ERROR" : normalized).slice(0, 128);
131
+ }
132
+ function assertIdentity$1(value, limit, label) {
133
+ if (typeof value !== "string" || value.length === 0 || value.length > limit) throw new TypeError(`${label} must contain 1-${limit} characters`);
134
+ }
135
+
136
+ //#endregion
137
+ //#region src/common/preferred-state.ts
138
+ const MCP_WEB_SERVER_FACTORY = Symbol.for("ai-agent-sdk.mcp-web-server.factory.v1");
139
+ const STATES = /* @__PURE__ */ new WeakMap();
140
+ function attachPreferredState(options, state) {
141
+ STATES.set(options, state);
142
+ }
143
+ function copyPreferredState(source, target) {
144
+ const state = STATES.get(source);
145
+ if (state !== void 0) STATES.set(target, state);
146
+ }
147
+ function preferredState(options) {
148
+ return STATES.get(options);
149
+ }
150
+
151
+ //#endregion
152
+ //#region src/common/config.ts
153
+ /** Internal limits shared by preferred and advanced Universal MCP servers. */
154
+ const MCP_SERVER_DEFAULTS = Object.freeze({
155
+ maxExports: 1024,
156
+ maxDefinitionBytes: 4194304,
157
+ maxInputBytes: 1048576,
158
+ maxOutputBytes: 4194304,
159
+ operationTimeoutMs: 6e5,
160
+ teardownTimeoutMs: 3e4,
161
+ observerTimeoutMs: 5e3
162
+ });
163
+
164
+ //#endregion
165
+ //#region src/server/advanced.ts
166
+ /** Export SDK tools and agents as a Universal fetch-shaped MCP server. */
167
+ /** Create one MCP server instance for a connection or HTTP request. */
168
+ function createSdkMcpServer(options, request = { era: "modern" }) {
169
+ const limits = resolveLimits(options);
170
+ assertIdentity(options.name, "server name");
171
+ if (options.version.trim().length === 0) throw new TypeError("MCP server version must not be empty");
172
+ const server = new McpServer({
173
+ name: options.name,
174
+ version: options.version
175
+ }, {
176
+ capabilities: { tools: { listChanged: false } },
177
+ ...options.instructions === void 0 ? {} : { instructions: options.instructions }
178
+ });
179
+ const names = /* @__PURE__ */ new Set();
180
+ const schemas = options.tools?.schemas() ?? [];
181
+ const runtimeAgents = Object.entries(preferredState(options)?.agents ?? {});
182
+ if (schemas.length + (options.agents?.length ?? 0) + runtimeAgents.length > limits.maxExports) throw new RangeError(`MCP server exceeds the ${limits.maxExports}-export limit`);
183
+ if (serializedBytes([
184
+ schemas,
185
+ options.agents?.map((agent) => ({
186
+ name: agent.name,
187
+ description: agent.description,
188
+ agentId: agent.agent.id
189
+ })) ?? [],
190
+ runtimeAgents.map(([name]) => ({ name }))
191
+ ]) > limits.maxDefinitionBytes) throw new RangeError(`MCP server definitions exceed the ${limits.maxDefinitionBytes}-byte limit`);
192
+ for (const schema of schemas) {
193
+ if (names.has(schema.name)) throw new TypeError(`duplicate MCP export '${schema.name}'`);
194
+ names.add(schema.name);
195
+ server.registerTool(schema.name, {
196
+ description: schema.description,
197
+ inputSchema: fromJsonSchema(structuredClone(schema.parameters))
198
+ }, async (args, context) => await callSdkTool(options, schema.name, args, context));
199
+ }
200
+ for (const agent of options.agents ?? []) {
201
+ assertIdentity(agent.name, "agent MCP tool name");
202
+ if (names.has(agent.name)) throw new TypeError(`duplicate MCP export '${agent.name}'`);
203
+ names.add(agent.name);
204
+ server.registerTool(agent.name, {
205
+ description: agent.description ?? agent.agent.description ?? `Run the ${agent.agent.name} agent for one conversational turn.`,
206
+ inputSchema: fromJsonSchema({
207
+ type: "object",
208
+ properties: {
209
+ input: {
210
+ type: "string",
211
+ minLength: 1
212
+ },
213
+ conversationId: {
214
+ type: "string",
215
+ minLength: 1
216
+ }
217
+ },
218
+ required: ["input"],
219
+ additionalProperties: false
220
+ })
221
+ }, async (args, context) => await callAgent(options, agent, request, args, context));
222
+ }
223
+ for (const [name, agent] of runtimeAgents) {
224
+ assertIdentity(name, "agent MCP tool name");
225
+ if (names.has(name)) throw new TypeError(`duplicate MCP export '${name}'`);
226
+ names.add(name);
227
+ server.registerTool(name, {
228
+ description: `Run the ${name} agent for one turn.`,
229
+ inputSchema: fromJsonSchema({
230
+ type: "object",
231
+ properties: { input: {
232
+ type: "string",
233
+ minLength: 1
234
+ } },
235
+ required: ["input"],
236
+ additionalProperties: false
237
+ })
238
+ }, async (args, context) => await callRuntimeAgent(options, name, agent, args, context));
239
+ }
240
+ return server;
241
+ }
242
+ /**
243
+ * Create a fetch-shaped API for Cloudflare Workers, Deno, Bun, Next.js route
244
+ * handlers, or any web framework that accepts Request/Response.
245
+ */
246
+ function createSdkMcpHandler(options, handlerOptions) {
247
+ const handler = createMcpHandler((request) => createSdkMcpServer(withRequestLogger(options), request), handlerOptions);
248
+ return {
249
+ fetch: async (request, requestOptions) => {
250
+ const operation = beginIntegrationOperation(integrationChildLogger(options.logger, "mcp-server-request"), serverFamily(options), "request");
251
+ const attempt = operation.attempt(1);
252
+ try {
253
+ const response = await handler.fetch(request, requestOptions);
254
+ if (response.status >= 500) {
255
+ attempt.fail(`HTTP_${response.status}`);
256
+ operation.fail(`HTTP_${response.status}`);
257
+ } else {
258
+ attempt.success();
259
+ operation.success();
260
+ }
261
+ return response;
262
+ } catch (error) {
263
+ const code = integrationErrorCode(error);
264
+ attempt.fail(code);
265
+ operation.fail(code);
266
+ throw error;
267
+ }
268
+ },
269
+ close: handler.close,
270
+ notify: handler.notify,
271
+ bus: handler.bus
272
+ };
273
+ }
274
+ function withRequestLogger(options) {
275
+ const logger = integrationChildLogger(options.logger, "mcp-server-request");
276
+ if (logger === void 0) return options;
277
+ const child = {
278
+ ...options,
279
+ logger
280
+ };
281
+ copyPreferredState(options, child);
282
+ return child;
283
+ }
284
+ function serverFamily(options) {
285
+ return options.integrationFamily ?? "mcp-web-server";
286
+ }
287
+ async function callRuntimeAgent(options, name, agent, args, context) {
288
+ const limits = resolveLimits(options);
289
+ const operation = beginIntegrationOperation(options.logger, serverFamily(options), "agent-call");
290
+ const attempt = operation.attempt(1);
291
+ if (serializedBytes(args) > limits.maxInputBytes) {
292
+ attempt.fail("INPUT_TOO_LARGE");
293
+ operation.fail("INPUT_TOO_LARGE");
294
+ return errorResult(`agent input exceeds the ${limits.maxInputBytes}-byte limit`, "INPUT_TOO_LARGE");
295
+ }
296
+ const signal = AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)]);
297
+ try {
298
+ const response = await raceWithSignal(agent.generate(args.input, { signal }), signal, limits.teardownTimeoutMs);
299
+ const result = {
300
+ content: [{
301
+ type: "text",
302
+ text: response.text || "(empty response)"
303
+ }],
304
+ structuredContent: {
305
+ text: response.text,
306
+ runId: response.runId,
307
+ traceId: response.traceId
308
+ }
309
+ };
310
+ if (serializedBytes(result) > limits.maxOutputBytes) {
311
+ attempt.fail("OUTPUT_TOO_LARGE");
312
+ operation.fail("OUTPUT_TOO_LARGE");
313
+ return errorResult(`agent result exceeds the ${limits.maxOutputBytes}-byte limit`, "OUTPUT_TOO_LARGE");
314
+ }
315
+ attempt.success();
316
+ operation.success();
317
+ return result;
318
+ } catch (error) {
319
+ const code = integrationErrorCode(error);
320
+ if (signal.aborted) {
321
+ attempt.abort();
322
+ operation.abort();
323
+ } else {
324
+ attempt.fail(code);
325
+ operation.fail(code);
326
+ }
327
+ await reportError(options, limits, error, "agent", name, context);
328
+ return errorResult(internalErrorMessage(options, error, "agent operation failed"), "AGENT_FAILED");
329
+ }
330
+ }
331
+ async function callSdkTool(options, toolName, args, context) {
332
+ const limits = resolveLimits(options);
333
+ const operation = beginIntegrationOperation(options.logger, serverFamily(options), "tool-call");
334
+ const attempt = operation.attempt(1);
335
+ if (serializedBytes(args) > limits.maxInputBytes) {
336
+ attempt.fail("INPUT_TOO_LARGE");
337
+ operation.fail("INPUT_TOO_LARGE");
338
+ return errorResult(`tool input exceeds the ${limits.maxInputBytes}-byte limit`, "INPUT_TOO_LARGE");
339
+ }
340
+ const catalog = options.tools;
341
+ if (catalog === void 0) {
342
+ attempt.fail("UNKNOWN_TOOL");
343
+ operation.fail("UNKNOWN_TOOL");
344
+ return errorResult(`tool '${toolName}' is not available`, "UNKNOWN_TOOL");
345
+ }
346
+ try {
347
+ const result = await dispatchToolCall({
348
+ catalog,
349
+ call: {
350
+ callId: ToolCallId(`mcp:${String(context.mcpReq.id)}`),
351
+ toolName,
352
+ rawArguments: JSON.stringify(args)
353
+ },
354
+ position: {
355
+ turn: 1,
356
+ step: 1
357
+ },
358
+ signal: AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)]),
359
+ defaultTimeoutMs: limits.operationTimeoutMs,
360
+ teardownTimeoutMs: limits.teardownTimeoutMs,
361
+ ...options.approvals === void 0 ? {} : { approvals: options.approvals },
362
+ ...options.interceptors === void 0 ? {} : { interceptors: options.interceptors }
363
+ });
364
+ if (serializedBytes(result) > limits.maxOutputBytes) {
365
+ attempt.fail("OUTPUT_TOO_LARGE");
366
+ operation.fail("OUTPUT_TOO_LARGE");
367
+ return errorResult(`tool result exceeds the ${limits.maxOutputBytes}-byte limit`, "OUTPUT_TOO_LARGE");
368
+ }
369
+ const content = [...toMcpContent(result.content), ...toMcpContent(result.additionalContext ?? [])];
370
+ if (result.isError) {
371
+ attempt.fail(result.error.code);
372
+ operation.fail(result.error.code);
373
+ return {
374
+ isError: true,
375
+ content: content.length === 0 ? [{
376
+ type: "text",
377
+ text: result.error.message
378
+ }] : content,
379
+ structuredContent: { error: result.error }
380
+ };
381
+ }
382
+ attempt.success();
383
+ operation.success();
384
+ return {
385
+ content: content.length === 0 ? [{
386
+ type: "text",
387
+ text: "(no output)"
388
+ }] : content,
389
+ ...result.value === void 0 ? {} : { structuredContent: result.value }
390
+ };
391
+ } catch (error) {
392
+ const code = integrationErrorCode(error);
393
+ attempt.fail(code);
394
+ operation.fail(code);
395
+ await reportError(options, limits, error, "tool", toolName, context);
396
+ return errorResult(internalErrorMessage(options, error, "tool operation failed"), "TOOL_OPERATION_FAILED");
397
+ }
398
+ }
399
+ async function callAgent(options, definition, request, args, context) {
400
+ const limits = resolveLimits(options);
401
+ const operation = beginIntegrationOperation(options.logger, serverFamily(options), "agent-call");
402
+ const attempt = operation.attempt(1);
403
+ if (serializedBytes(args) > limits.maxInputBytes) {
404
+ attempt.fail("INPUT_TOO_LARGE");
405
+ operation.fail("INPUT_TOO_LARGE");
406
+ return errorResult(`agent input exceeds the ${limits.maxInputBytes}-byte limit`, "INPUT_TOO_LARGE");
407
+ }
408
+ const signal = AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)]);
409
+ try {
410
+ const session = await raceWithSignal(Promise.resolve(definition.createSession({
411
+ ...args.conversationId === void 0 ? {} : { conversationId: args.conversationId },
412
+ request,
413
+ call: context
414
+ })), signal, limits.teardownTimeoutMs);
415
+ if (session.definition.id !== definition.agent.id) {
416
+ attempt.fail("WRONG_AGENT_SESSION");
417
+ operation.fail("WRONG_AGENT_SESSION");
418
+ return errorResult(`session factory for '${definition.name}' returned agent '${session.definition.id}', expected '${definition.agent.id}'`, "WRONG_AGENT_SESSION");
419
+ }
420
+ const response = await raceWithSignal(session.run(args.input, { signal }), signal, limits.teardownTimeoutMs);
421
+ if (!isJsonValue(response.outcome)) {
422
+ attempt.fail("INVALID_AGENT_RESULT");
423
+ operation.fail("INVALID_AGENT_RESULT");
424
+ return errorResult("agent outcome was not lossless JSON", "INVALID_AGENT_RESULT");
425
+ }
426
+ const result = {
427
+ content: [{
428
+ type: "text",
429
+ text: response.text || "(empty response)"
430
+ }],
431
+ structuredContent: {
432
+ text: response.text,
433
+ outcome: response.outcome,
434
+ conversationId: session.conversationId
435
+ }
436
+ };
437
+ if (serializedBytes(result) > limits.maxOutputBytes) {
438
+ attempt.fail("OUTPUT_TOO_LARGE");
439
+ operation.fail("OUTPUT_TOO_LARGE");
440
+ return errorResult(`agent result exceeds the ${limits.maxOutputBytes}-byte limit`, "OUTPUT_TOO_LARGE");
441
+ }
442
+ attempt.success();
443
+ operation.success();
444
+ return result;
445
+ } catch (error) {
446
+ const code = integrationErrorCode(error);
447
+ if (signal.aborted) {
448
+ attempt.abort();
449
+ operation.abort();
450
+ } else {
451
+ attempt.fail(code);
452
+ operation.fail(code);
453
+ }
454
+ await reportError(options, limits, error, "agent", definition.name, context);
455
+ return errorResult(internalErrorMessage(options, error, "agent operation failed"), "AGENT_FAILED");
456
+ }
457
+ }
458
+ function toMcpContent(blocks) {
459
+ const result = [];
460
+ for (const block of blocks) {
461
+ if (block.type === "text") {
462
+ result.push({
463
+ type: "text",
464
+ text: block.text
465
+ });
466
+ continue;
467
+ }
468
+ if (block.type === "image" && block.source.kind === "base64") {
469
+ result.push({
470
+ type: "image",
471
+ data: block.source.data,
472
+ mimeType: block.source.mediaType
473
+ });
474
+ continue;
475
+ }
476
+ if (block.type === "image" && block.source.kind === "url") {
477
+ result.push({
478
+ type: "text",
479
+ text: `[image](${block.source.url})`
480
+ });
481
+ continue;
482
+ }
483
+ if (block.type === "image" && block.source.kind === "file") {
484
+ result.push({
485
+ type: "text",
486
+ text: `[image file: ${block.source.fileId}]`
487
+ });
488
+ continue;
489
+ }
490
+ if (block.type === "reasoning") {
491
+ result.push({
492
+ type: "text",
493
+ text: block.text
494
+ });
495
+ continue;
496
+ }
497
+ result.push({
498
+ type: "text",
499
+ text: JSON.stringify(jsonSafeBlock(block))
500
+ });
501
+ }
502
+ return result;
503
+ }
504
+ function jsonSafeBlock(block) {
505
+ if (isJsonValue(block)) return block;
506
+ return { type: block.type };
507
+ }
508
+ function errorResult(message, code) {
509
+ return {
510
+ isError: true,
511
+ content: [{
512
+ type: "text",
513
+ text: `Error: ${message}`
514
+ }],
515
+ structuredContent: { error: {
516
+ message,
517
+ code
518
+ } }
519
+ };
520
+ }
521
+ function assertIdentity(value, field) {
522
+ if (value.trim().length === 0) throw new TypeError(`${field} must not be empty`);
523
+ }
524
+ function errorMessage(value) {
525
+ return value instanceof Error && value.message.length > 0 ? value.message : String(value);
526
+ }
527
+ function resolveLimits(options) {
528
+ return {
529
+ maxExports: positiveSafeInteger(options.maxExports ?? MCP_SERVER_DEFAULTS.maxExports, "maxExports"),
530
+ maxDefinitionBytes: positiveSafeInteger(options.maxDefinitionBytes ?? MCP_SERVER_DEFAULTS.maxDefinitionBytes, "maxDefinitionBytes"),
531
+ maxInputBytes: positiveSafeInteger(options.maxInputBytes ?? MCP_SERVER_DEFAULTS.maxInputBytes, "maxInputBytes"),
532
+ maxOutputBytes: positiveSafeInteger(options.maxOutputBytes ?? MCP_SERVER_DEFAULTS.maxOutputBytes, "maxOutputBytes"),
533
+ operationTimeoutMs: positiveSafeInteger(options.operationTimeoutMs ?? MCP_SERVER_DEFAULTS.operationTimeoutMs, "operationTimeoutMs"),
534
+ teardownTimeoutMs: positiveSafeInteger(options.teardownTimeoutMs ?? MCP_SERVER_DEFAULTS.teardownTimeoutMs, "teardownTimeoutMs"),
535
+ observerTimeoutMs: positiveSafeInteger(options.observerTimeoutMs ?? MCP_SERVER_DEFAULTS.observerTimeoutMs, "observerTimeoutMs")
536
+ };
537
+ }
538
+ async function reportError(options, limits, error, operation, exportName, context) {
539
+ if (options.onError === void 0) return;
540
+ const pending = Promise.resolve().then(() => options.onError?.(error, Object.freeze({
541
+ operation,
542
+ exportName,
543
+ requestId: String(context.mcpReq.id)
544
+ })));
545
+ await waitForSettlement(pending, limits.observerTimeoutMs);
546
+ }
547
+ function internalErrorMessage(options, error, fallback) {
548
+ return options.exposeInternalErrors === true ? errorMessage(error) : fallback;
549
+ }
550
+ function positiveSafeInteger(value, label) {
551
+ if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`MCP server ${label} must be a positive safe integer`);
552
+ return value;
553
+ }
554
+ function serializedBytes(value) {
555
+ const serialized = JSON.stringify(value);
556
+ if (serialized === void 0) throw new TypeError("MCP server value is not JSON serializable");
557
+ return new TextEncoder().encode(serialized).byteLength;
558
+ }
559
+ async function raceWithSignal(pending, signal, teardownTimeoutMs) {
560
+ if (signal.aborted) throw signal.reason ?? /* @__PURE__ */ new Error("MCP server operation aborted");
561
+ try {
562
+ return await new Promise((resolve, reject) => {
563
+ const abort = () => {
564
+ signal.removeEventListener("abort", abort);
565
+ reject(signal.reason ?? /* @__PURE__ */ new Error("MCP server operation aborted"));
566
+ };
567
+ signal.addEventListener("abort", abort, { once: true });
568
+ pending.then((value) => {
569
+ signal.removeEventListener("abort", abort);
570
+ resolve(value);
571
+ }, (error) => {
572
+ signal.removeEventListener("abort", abort);
573
+ reject(error);
574
+ });
575
+ });
576
+ } catch (error) {
577
+ if (signal.aborted) await waitForSettlement(pending, teardownTimeoutMs);
578
+ throw error;
579
+ }
580
+ }
581
+
582
+ //#endregion
583
+ //#region src/preferred/server.ts
584
+ /** Capture one inert Web-standard server definition; each handle call owns its request resources. */
585
+ function createMcpServer(definition) {
586
+ const source = objectValue(definition);
587
+ const id = identity(ownValue(source, "id"), "MCP server id");
588
+ const logger = optionalObject(ownValue(source, "logger", false), "MCP server logger");
589
+ const tools = captureToolCatalog(ownValue(source, "tools", false));
590
+ const agents = captureAgents(ownValue(source, "agents", false));
591
+ const maxRequestBytes = positive(ownValue(source, "maxRequestBytes", false) ?? MCP_SERVER_DEFAULTS.maxInputBytes, "maxRequestBytes");
592
+ const maxResponseBytes = positive(ownValue(source, "maxResponseBytes", false) ?? MCP_SERVER_DEFAULTS.maxOutputBytes, "maxResponseBytes");
593
+ const advanced = Object.freeze({
594
+ name: id,
595
+ version: "1.0.0",
596
+ ...logger === void 0 ? {} : { logger },
597
+ ...tools === void 0 ? {} : { tools },
598
+ maxInputBytes: maxRequestBytes,
599
+ maxOutputBytes: maxResponseBytes
600
+ });
601
+ attachPreferredState(advanced, Object.freeze({ agents }));
602
+ const factory = (request, family) => {
603
+ const scoped = {
604
+ ...advanced,
605
+ integrationFamily: family
606
+ };
607
+ copyPreferredState(advanced, scoped);
608
+ return createSdkMcpServer(scoped, request);
609
+ };
610
+ const handle = async (request, options) => {
611
+ if (!(request instanceof Request)) throw new TypeError("MCP Web server requires a Request");
612
+ const signal = options?.signal === void 0 ? request.signal : AbortSignal.any([request.signal, options.signal]);
613
+ signal.throwIfAborted();
614
+ const forwarded = signal === request.signal ? request : new Request(request, { signal });
615
+ if (!await requestFits(forwarded, maxRequestBytes)) return payloadTooLarge();
616
+ const handlerOptions = {
617
+ ...advanced,
618
+ integrationFamily: "mcp-web-server"
619
+ };
620
+ copyPreferredState(advanced, handlerOptions);
621
+ const handler = createSdkMcpHandler(handlerOptions);
622
+ try {
623
+ return boundedResponse(await handler.fetch(forwarded), maxResponseBytes, handler.close);
624
+ } catch (error) {
625
+ await settleClose(handler.close);
626
+ throw error;
627
+ }
628
+ };
629
+ const result = { handle };
630
+ Object.defineProperty(result, MCP_WEB_SERVER_FACTORY, {
631
+ value: factory,
632
+ enumerable: false
633
+ });
634
+ return Object.freeze(result);
635
+ }
636
+ function captureAgents(value) {
637
+ if (value === void 0) return Object.freeze({});
638
+ const source = objectValue(value), entries = [];
639
+ for (const key of Reflect.ownKeys(source)) {
640
+ if (typeof key !== "string") throw new TypeError("MCP agent names must be strings");
641
+ identity(key, "MCP agent name");
642
+ const agent = objectValue(ownValue(source, key));
643
+ const generate = method(agent, "generate");
644
+ entries.push([key, Object.freeze({ generate: (input, options) => Reflect.apply(generate, agent, [input, options]) })]);
645
+ }
646
+ return Object.freeze(Object.fromEntries(entries));
647
+ }
648
+ function captureToolCatalog(value) {
649
+ if (value === void 0) return void 0;
650
+ const catalog = objectValue(value);
651
+ const get = method(catalog, "get"), has = method(catalog, "has"), names = method(catalog, "names");
652
+ const schemas = method(catalog, "schemas"), executionMode = method(catalog, "executionMode");
653
+ return Object.freeze({
654
+ get: (name) => Reflect.apply(get, catalog, [name]),
655
+ has: (name) => Reflect.apply(has, catalog, [name]),
656
+ names: () => Reflect.apply(names, catalog, []),
657
+ schemas: () => Reflect.apply(schemas, catalog, []),
658
+ executionMode(name, args) {
659
+ return Reflect.apply(executionMode, catalog, [name, args]);
660
+ }
661
+ });
662
+ }
663
+ async function requestFits(request, limit) {
664
+ const declared = request.headers.get("content-length");
665
+ if (declared !== null) {
666
+ const bytes = Number(declared);
667
+ if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > limit) return false;
668
+ }
669
+ if (request.body === null) return true;
670
+ try {
671
+ return (await request.clone().arrayBuffer()).byteLength <= limit;
672
+ } catch {
673
+ return false;
674
+ }
675
+ }
676
+ function boundedResponse(response, limit, close) {
677
+ if (response.body === null) {
678
+ settleClose(close);
679
+ return response;
680
+ }
681
+ const declared = response.headers.get("content-length");
682
+ if (declared !== null && Number(declared) > limit) {
683
+ response.body.cancel();
684
+ settleClose(close);
685
+ return responseTooLarge();
686
+ }
687
+ const reader = response.body.getReader();
688
+ let bytes = 0, closed = false;
689
+ const finish = async () => {
690
+ if (closed) return;
691
+ closed = true;
692
+ await settleClose(close);
693
+ };
694
+ const body = new ReadableStream({
695
+ async pull(controller) {
696
+ try {
697
+ const next = await reader.read();
698
+ if (next.done) {
699
+ controller.close();
700
+ await finish();
701
+ return;
702
+ }
703
+ bytes += next.value.byteLength;
704
+ if (bytes > limit) {
705
+ await reader.cancel();
706
+ await finish();
707
+ controller.error(/* @__PURE__ */ new RangeError("MCP response exceeded maxResponseBytes"));
708
+ return;
709
+ }
710
+ controller.enqueue(next.value);
711
+ } catch (error) {
712
+ await finish();
713
+ controller.error(error);
714
+ }
715
+ },
716
+ async cancel(reason) {
717
+ try {
718
+ await reader.cancel(reason);
719
+ } finally {
720
+ await finish();
721
+ }
722
+ }
723
+ });
724
+ return new Response(body, {
725
+ status: response.status,
726
+ statusText: response.statusText,
727
+ headers: response.headers
728
+ });
729
+ }
730
+ function payloadTooLarge() {
731
+ return Response.json({
732
+ jsonrpc: "2.0",
733
+ id: null,
734
+ error: {
735
+ code: -32600,
736
+ message: "MCP request exceeds maxRequestBytes"
737
+ }
738
+ }, { status: 413 });
739
+ }
740
+ function responseTooLarge() {
741
+ return Response.json({
742
+ jsonrpc: "2.0",
743
+ id: null,
744
+ error: {
745
+ code: -32603,
746
+ message: "MCP response exceeds maxResponseBytes"
747
+ }
748
+ }, { status: 500 });
749
+ }
750
+ async function settleClose(close) {
751
+ try {
752
+ await close();
753
+ } catch {}
754
+ }
755
+ function objectValue(value) {
756
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new TypeError("Invalid MCP server definition");
757
+ return value;
758
+ }
759
+ function ownValue(source, key, required = true) {
760
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
761
+ if (descriptor === void 0) {
762
+ if (!required) return void 0;
763
+ throw new TypeError(`Missing MCP server field ${String(key)}`);
764
+ }
765
+ if (!("value" in descriptor)) throw new TypeError(`MCP server field ${String(key)} must be data`);
766
+ return descriptor.value;
767
+ }
768
+ function method(source, key) {
769
+ const value = Reflect.get(source, key);
770
+ if (typeof value !== "function") throw new TypeError(`MCP server method ${String(key)} is invalid`);
771
+ return value;
772
+ }
773
+ function identity(value, label) {
774
+ if (typeof value !== "string" || value.length < 1 || value.length > 128) throw new TypeError(`${label} is invalid`);
775
+ return value;
776
+ }
777
+ function positive(value, label) {
778
+ if (!Number.isSafeInteger(value) || Number(value) < 1) throw new TypeError(`MCP server ${label} is invalid`);
779
+ return Number(value);
780
+ }
781
+ function optionalObject(value, label) {
782
+ if (value === void 0) return void 0;
783
+ if ((typeof value !== "object" || value === null) && typeof value !== "function") throw new TypeError(`${label} is invalid`);
784
+ return value;
785
+ }
786
+
787
+ //#endregion
788
+ export { createMcpServer, createSdkMcpHandler, createSdkMcpServer };
789
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["assertIdentity"],"sources":["../src/common/integration-operation.ts","../src/common/preferred-state.ts","../src/common/config.ts","../src/server/advanced.ts","../src/preferred/server.ts"],"sourcesContent":["import type { IntegrationOperationEvidenceFields, SdkLogger } from '@alvin0/ai-agent-sdk-core/observability'\n\nexport const MCP_SERVER_INTEGRATION_OPERATIONS = Object.freeze({\n 'mcp-web-server': Object.freeze(['request', 'tool-call', 'agent-call']),\n 'mcp-stdio-server': Object.freeze(['request', 'tool-call', 'agent-call', 'close']),\n} as const)\n\nexport type McpServerIntegrationFamily = keyof typeof MCP_SERVER_INTEGRATION_OPERATIONS\nexport type McpServerIntegrationOperation =\n (typeof MCP_SERVER_INTEGRATION_OPERATIONS)[McpServerIntegrationFamily][number]\n\nexport interface IntegrationAttempt {\n success(): void\n fail(errorCode?: string): void\n abort(): void\n}\n\nexport interface IntegrationOperation {\n attempt(attemptNumber: number): IntegrationAttempt\n success(): void\n fail(errorCode?: string): void\n abort(): void\n}\n\nconst MESSAGES = Object.freeze({\n start: 'SDK integration operation started',\n attempt: 'SDK integration attempt started',\n success: 'SDK integration operation completed',\n failure: 'SDK integration operation failed',\n abort: 'SDK integration operation aborted',\n})\n\nexport function beginIntegrationOperation(\n logger: SdkLogger | undefined,\n family: McpServerIntegrationFamily,\n operation: McpServerIntegrationOperation,\n): IntegrationOperation {\n validateOperation(family, operation)\n const operationId = crypto.randomUUID(), startedAt = monotonicNow()\n emit(logger, 'info', MESSAGES.start, {\n integrationSchemaVersion: 1, integrationFamily: family,\n integrationOperation: operation, operationId, kind: 'logical-start',\n })\n let terminal = false\n const finish = (status: 'success' | 'error' | 'aborted', errorCode?: string): void => {\n if (terminal) return\n terminal = true\n emit(logger, status === 'error' ? 'error' : 'info', terminalMessage(status), {\n integrationSchemaVersion: 1, integrationFamily: family,\n integrationOperation: operation, operationId, kind: 'logical-terminal',\n status, durationMs: durationSince(startedAt),\n ...(errorCode === undefined ? {} : { errorCode: boundedCode(errorCode) }),\n })\n }\n return Object.freeze({\n attempt(attemptNumber: number) {\n if (!Number.isSafeInteger(attemptNumber) || attemptNumber < 1) {\n throw new TypeError('integration attemptNumber must be a positive safe integer')\n }\n const attemptId = crypto.randomUUID(), attemptStartedAt = monotonicNow()\n emit(logger, 'info', MESSAGES.attempt, {\n integrationSchemaVersion: 1, integrationFamily: family,\n integrationOperation: operation, operationId, kind: 'attempt-start',\n attemptId, attemptNumber,\n })\n let attemptTerminal = false\n const finishAttempt = (status: 'success' | 'error' | 'aborted', errorCode?: string): void => {\n if (attemptTerminal) return\n attemptTerminal = true\n emit(logger, status === 'error' ? 'error' : 'info', terminalMessage(status), {\n integrationSchemaVersion: 1, integrationFamily: family,\n integrationOperation: operation, operationId, kind: 'attempt-terminal',\n attemptId, attemptNumber, status, durationMs: durationSince(attemptStartedAt),\n ...(errorCode === undefined ? {} : { errorCode: boundedCode(errorCode) }),\n })\n }\n return Object.freeze({\n success: () => finishAttempt('success'),\n fail: (code?: string) => finishAttempt('error', code),\n abort: () => finishAttempt('aborted'),\n })\n },\n success: () => finish('success'),\n fail: (code?: string) => finish('error', code),\n abort: () => finish('aborted'),\n })\n}\n\nexport function integrationErrorCode(error: unknown): string {\n if (typeof error === 'object' && error !== null) {\n for (const key of ['code', 'name']) {\n const descriptor = Object.getOwnPropertyDescriptor(error, key)\n if (descriptor !== undefined && 'value' in descriptor && typeof descriptor.value === 'string') {\n return boundedCode(descriptor.value)\n }\n }\n }\n return 'INTEGRATION_ERROR'\n}\n\nexport function integrationChildLogger(logger: SdkLogger | undefined, scope: string): SdkLogger | undefined {\n assertIdentity(scope, 64, 'integration scope')\n try { return logger?.child({ integrationScope: scope }) } catch { return undefined }\n}\n\nfunction validateOperation(family: McpServerIntegrationFamily, operation: McpServerIntegrationOperation): void {\n const operations = MCP_SERVER_INTEGRATION_OPERATIONS[family] as readonly string[] | undefined\n assertIdentity(family, 64, 'integration family')\n assertIdentity(operation, 64, 'integration operation')\n if (operations === undefined || !operations.includes(operation)) throw new TypeError('Invalid MCP integration operation')\n}\n\nfunction emit(logger: SdkLogger | undefined, level: 'info' | 'error', message: string,\n fields: IntegrationOperationEvidenceFields): void {\n try { logger?.[level](message, fields) } catch { /* logging never owns protocol completion */ }\n}\n\nfunction terminalMessage(status: 'success' | 'error' | 'aborted'): string {\n return status === 'success' ? MESSAGES.success : status === 'error' ? MESSAGES.failure : MESSAGES.abort\n}\nfunction monotonicNow(): number { return performance.now() }\nfunction durationSince(startedAt: number): number {\n const value = monotonicNow() - startedAt\n return Number.isFinite(value) ? Math.max(0, value) : 0\n}\nfunction boundedCode(value: string): string {\n const normalized = value.replace(/[^A-Za-z0-9_.:-]/g, '_')\n return (normalized.length === 0 ? 'INTEGRATION_ERROR' : normalized).slice(0, 128)\n}\nfunction assertIdentity(value: string, limit: number, label: string): void {\n if (typeof value !== 'string' || value.length === 0 || value.length > limit) {\n throw new TypeError(`${label} must contain 1-${limit} characters`)\n }\n}\n","import type { RuntimeAgentResponse } from '@alvin0/ai-agent-sdk-core/agent'\nimport type { SdkMcpRequestContext, SdkMcpServer } from './server-public-types.ts'\n\nexport type McpServerRuntimeFamily = 'mcp-web-server' | 'mcp-stdio-server'\n\nexport interface PreferredServerState {\n readonly agents: Readonly<Record<string, PreferredServerAgent>>\n}\n\nexport interface PreferredServerAgent {\n generate(input: string, options: { readonly signal?: AbortSignal }): Promise<RuntimeAgentResponse>\n}\n\nexport type InternalMcpServerFactory = (\n request: SdkMcpRequestContext,\n family: McpServerRuntimeFamily,\n) => SdkMcpServer\n\nexport const MCP_WEB_SERVER_FACTORY = Symbol.for('ai-agent-sdk.mcp-web-server.factory.v1')\n\nconst STATES = new WeakMap<object, PreferredServerState>()\n\nexport function attachPreferredState(options: object, state: PreferredServerState): void {\n STATES.set(options, state)\n}\n\nexport function copyPreferredState(source: object, target: object): void {\n const state = STATES.get(source)\n if (state !== undefined) STATES.set(target, state)\n}\n\nexport function preferredState(options: object): PreferredServerState | undefined {\n return STATES.get(options)\n}\n\nexport function internalMcpServerFactory(value: unknown): InternalMcpServerFactory | undefined {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return undefined\n const descriptor = Object.getOwnPropertyDescriptor(value, MCP_WEB_SERVER_FACTORY)\n return descriptor !== undefined && 'value' in descriptor && typeof descriptor.value === 'function'\n ? descriptor.value as InternalMcpServerFactory : undefined\n}\n","/** Internal limits shared by preferred and advanced Universal MCP servers. */\nexport const MCP_SERVER_DEFAULTS = Object.freeze({\n maxExports: 1_024,\n maxDefinitionBytes: 4 * 1024 * 1024,\n maxInputBytes: 1024 * 1024,\n maxOutputBytes: 4 * 1024 * 1024,\n operationTimeoutMs: 10 * 60_000,\n teardownTimeoutMs: 30_000,\n observerTimeoutMs: 5_000,\n})\n","/** Export SDK tools and agents as a Universal fetch-shaped MCP server. */\n\nimport {\n McpServer,\n createMcpHandler,\n fromJsonSchema,\n type CallToolResult,\n type CreateMcpHandlerOptions,\n type ServerContext,\n} from '@modelcontextprotocol/server'\nimport type { ContentBlock } from '@alvin0/ai-agent-sdk-core'\nimport { ToolCallId, isJsonValue, type JsonValue } from '@alvin0/ai-agent-sdk-core'\nimport type { AgentSession, DefinedAgent } from '@alvin0/ai-agent-sdk-core/agent'\nimport type { ApprovalBroker, SdkLogger, ToolCatalog, ToolInterceptor } from '@alvin0/ai-agent-sdk-core/tools'\nimport {\n dispatchToolCall,\n} from '@alvin0/ai-agent-sdk-core/tools'\nimport { waitForSettlement } from '@alvin0/ai-agent-sdk-core'\nimport {\n beginIntegrationOperation,\n integrationChildLogger,\n integrationErrorCode,\n type McpServerIntegrationFamily,\n} from '../common/integration-operation.ts'\nimport { copyPreferredState, preferredState, type PreferredServerAgent } from '../common/preferred-state.ts'\nimport { MCP_SERVER_DEFAULTS } from '../common/config.ts'\nimport type {\n SdkMcpCallContext,\n SdkMcpHandlerOptions,\n SdkMcpHandlerRequestOptions,\n SdkMcpHttpHandler,\n SdkMcpRequestContext,\n SdkMcpServer,\n} from '../common/server-public-types.ts'\n\nexport type * from '../common/server-public-types.ts'\n\nexport interface McpAgentSessionContext {\n readonly conversationId?: string\n readonly request: SdkMcpRequestContext\n readonly call: SdkMcpCallContext\n}\n\nexport interface McpAgentTool {\n readonly name: string\n readonly description?: string\n readonly agent: DefinedAgent\n /** Host-owned persistence seam: return a fresh or resumed session. */\n readonly createSession: (context: McpAgentSessionContext) => AgentSession | Promise<AgentSession>\n}\n\nexport interface McpServerErrorContext {\n readonly operation: 'tool' | 'agent'\n readonly exportName: string\n readonly requestId: string\n}\n\nexport interface SdkMcpServerOptions {\n readonly name: string\n readonly version: string\n readonly logger?: SdkLogger\n /** Internal family selected by the official Web/stdio host factory. */\n readonly integrationFamily?: 'mcp-web-server' | 'mcp-stdio-server'\n readonly instructions?: string\n /** SDK tools exposed through the existing validation/policy pipeline. */\n readonly tools?: ToolCatalog\n readonly agents?: readonly McpAgentTool[]\n readonly approvals?: ApprovalBroker\n readonly interceptors?: readonly ToolInterceptor[]\n /** Maximum exported tools and agents. Defaults to 1,024. */\n readonly maxExports?: number\n /** Maximum serialized export schema bytes. Defaults to 4 MiB. */\n readonly maxDefinitionBytes?: number\n /** Maximum serialized request arguments. Defaults to 1 MiB. */\n readonly maxInputBytes?: number\n /** Maximum serialized tool/agent result. Defaults to 4 MiB. */\n readonly maxOutputBytes?: number\n /** Default tool/agent operation deadline. Defaults to 10 minutes. */\n readonly operationTimeoutMs?: number\n /** Maximum wait after cancellation. Defaults to 30 seconds. */\n readonly teardownTimeoutMs?: number\n /** Maximum time granted to the diagnostic observer. Defaults to 5 seconds. */\n readonly observerTimeoutMs?: number\n /** Report host/runtime failures without giving the observer control over request completion. */\n readonly onError?: (error: unknown, context: McpServerErrorContext) => void | Promise<void>\n /** Opt in to returning internal exception messages to remote callers. Defaults to false. */\n readonly exposeInternalErrors?: boolean\n}\n\ntype McpResultBlock = CallToolResult['content'][number]\n\n/** Create one MCP server instance for a connection or HTTP request. */\nexport function createSdkMcpServer(\n options: SdkMcpServerOptions,\n request: SdkMcpRequestContext = { era: 'modern' },\n): SdkMcpServer {\n const limits = resolveLimits(options)\n assertIdentity(options.name, 'server name')\n if (options.version.trim().length === 0) throw new TypeError('MCP server version must not be empty')\n const server = new McpServer(\n { name: options.name, version: options.version },\n {\n capabilities: { tools: { listChanged: false } },\n ...(options.instructions === undefined ? {} : { instructions: options.instructions }),\n },\n )\n const names = new Set<string>()\n const schemas = options.tools?.schemas() ?? []\n const runtimeAgents = Object.entries(preferredState(options)?.agents ?? {})\n if (schemas.length + (options.agents?.length ?? 0) + runtimeAgents.length > limits.maxExports) {\n throw new RangeError(`MCP server exceeds the ${limits.maxExports}-export limit`)\n }\n if (serializedBytes([schemas, options.agents?.map(agent => ({\n name: agent.name, description: agent.description, agentId: agent.agent.id,\n })) ?? [], runtimeAgents.map(([name]) => ({ name }))]) > limits.maxDefinitionBytes) {\n throw new RangeError(`MCP server definitions exceed the ${limits.maxDefinitionBytes}-byte limit`)\n }\n for (const schema of schemas) {\n if (names.has(schema.name)) throw new TypeError(`duplicate MCP export '${schema.name}'`)\n names.add(schema.name)\n server.registerTool(\n schema.name,\n {\n description: schema.description,\n // The Worker/browser validator dereferences by attaching private\n // metadata. SDK tool schemas are intentionally frozen, so give the\n // protocol boundary an isolated mutable copy.\n inputSchema: fromJsonSchema<Record<string, unknown>>(structuredClone(schema.parameters)),\n },\n async (args, context) => await callSdkTool(options, schema.name, args, context),\n )\n }\n for (const agent of options.agents ?? []) {\n assertIdentity(agent.name, 'agent MCP tool name')\n if (names.has(agent.name)) throw new TypeError(`duplicate MCP export '${agent.name}'`)\n names.add(agent.name)\n server.registerTool(\n agent.name,\n {\n description: agent.description\n ?? agent.agent.description\n ?? `Run the ${agent.agent.name} agent for one conversational turn.`,\n inputSchema: fromJsonSchema<{ input: string; conversationId?: string }>({\n type: 'object',\n properties: {\n input: { type: 'string', minLength: 1 },\n conversationId: { type: 'string', minLength: 1 },\n },\n required: ['input'],\n additionalProperties: false,\n }),\n },\n async (args, context) => await callAgent(options, agent, request, args, context),\n )\n }\n for (const [name, agent] of runtimeAgents) {\n assertIdentity(name, 'agent MCP tool name')\n if (names.has(name)) throw new TypeError(`duplicate MCP export '${name}'`)\n names.add(name)\n server.registerTool(name, {\n description: `Run the ${name} agent for one turn.`,\n inputSchema: fromJsonSchema<{ input: string }>({\n type: 'object', properties: { input: { type: 'string', minLength: 1 } },\n required: ['input'], additionalProperties: false,\n }),\n }, async (args, context) => await callRuntimeAgent(options, name, agent, args, context))\n }\n return server as unknown as SdkMcpServer\n}\n\n/**\n * Create a fetch-shaped API for Cloudflare Workers, Deno, Bun, Next.js route\n * handlers, or any web framework that accepts Request/Response.\n */\nexport function createSdkMcpHandler(\n options: SdkMcpServerOptions,\n handlerOptions?: SdkMcpHandlerOptions,\n): SdkMcpHttpHandler {\n const handler = createMcpHandler(\n request => createSdkMcpServer(withRequestLogger(options), request as SdkMcpRequestContext) as unknown as McpServer,\n handlerOptions as CreateMcpHandlerOptions,\n )\n return {\n fetch: async (request: Request, requestOptions?: SdkMcpHandlerRequestOptions) => {\n const operation = beginIntegrationOperation(\n integrationChildLogger(options.logger, 'mcp-server-request'), serverFamily(options), 'request',\n )\n const attempt = operation.attempt(1)\n try {\n const response = await handler.fetch(request, requestOptions as never)\n if (response.status >= 500) {\n attempt.fail(`HTTP_${response.status}`); operation.fail(`HTTP_${response.status}`)\n } else {\n attempt.success(); operation.success()\n }\n return response\n } catch (error: unknown) {\n const code = integrationErrorCode(error)\n attempt.fail(code); operation.fail(code)\n throw error\n }\n },\n close: handler.close,\n notify: handler.notify,\n bus: handler.bus,\n } as unknown as SdkMcpHttpHandler\n}\n\nfunction withRequestLogger(options: SdkMcpServerOptions): SdkMcpServerOptions {\n const logger = integrationChildLogger(options.logger, 'mcp-server-request')\n if (logger === undefined) return options\n const child = { ...options, logger }\n copyPreferredState(options, child)\n return child\n}\n\nfunction serverFamily(options: SdkMcpServerOptions): McpServerIntegrationFamily {\n return options.integrationFamily ?? 'mcp-web-server'\n}\n\nasync function callRuntimeAgent(\n options: SdkMcpServerOptions,\n name: string,\n agent: PreferredServerAgent,\n args: { input: string },\n context: ServerContext,\n): Promise<CallToolResult> {\n const limits = resolveLimits(options)\n const operation = beginIntegrationOperation(options.logger, serverFamily(options), 'agent-call')\n const attempt = operation.attempt(1)\n if (serializedBytes(args) > limits.maxInputBytes) {\n attempt.fail('INPUT_TOO_LARGE'); operation.fail('INPUT_TOO_LARGE')\n return errorResult(`agent input exceeds the ${limits.maxInputBytes}-byte limit`, 'INPUT_TOO_LARGE')\n }\n const signal = AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)])\n try {\n const response = await raceWithSignal(agent.generate(args.input, { signal }), signal, limits.teardownTimeoutMs)\n const result: CallToolResult = {\n content: [{ type: 'text', text: response.text || '(empty response)' }],\n structuredContent: { text: response.text, runId: response.runId, traceId: response.traceId },\n }\n if (serializedBytes(result) > limits.maxOutputBytes) {\n attempt.fail('OUTPUT_TOO_LARGE'); operation.fail('OUTPUT_TOO_LARGE')\n return errorResult(`agent result exceeds the ${limits.maxOutputBytes}-byte limit`, 'OUTPUT_TOO_LARGE')\n }\n attempt.success(); operation.success()\n return result\n } catch (error: unknown) {\n const code = integrationErrorCode(error)\n if (signal.aborted) { attempt.abort(); operation.abort() }\n else { attempt.fail(code); operation.fail(code) }\n await reportError(options, limits, error, 'agent', name, context)\n return errorResult(internalErrorMessage(options, error, 'agent operation failed'), 'AGENT_FAILED')\n }\n}\n\nasync function callSdkTool(\n options: SdkMcpServerOptions,\n toolName: string,\n args: Record<string, unknown>,\n context: ServerContext,\n): Promise<CallToolResult> {\n const limits = resolveLimits(options)\n const operation = beginIntegrationOperation(options.logger, serverFamily(options), 'tool-call')\n const attempt = operation.attempt(1)\n if (serializedBytes(args) > limits.maxInputBytes) {\n attempt.fail('INPUT_TOO_LARGE'); operation.fail('INPUT_TOO_LARGE')\n return errorResult(`tool input exceeds the ${limits.maxInputBytes}-byte limit`, 'INPUT_TOO_LARGE')\n }\n const catalog = options.tools\n if (catalog === undefined) {\n attempt.fail('UNKNOWN_TOOL'); operation.fail('UNKNOWN_TOOL')\n return errorResult(`tool '${toolName}' is not available`, 'UNKNOWN_TOOL')\n }\n try {\n const result = await dispatchToolCall({\n catalog,\n call: {\n callId: ToolCallId(`mcp:${String(context.mcpReq.id)}`),\n toolName,\n rawArguments: JSON.stringify(args),\n },\n position: { turn: 1, step: 1 },\n signal: AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)]),\n defaultTimeoutMs: limits.operationTimeoutMs,\n teardownTimeoutMs: limits.teardownTimeoutMs,\n ...(options.approvals === undefined ? {} : { approvals: options.approvals }),\n ...(options.interceptors === undefined ? {} : { interceptors: options.interceptors }),\n })\n if (serializedBytes(result) > limits.maxOutputBytes) {\n attempt.fail('OUTPUT_TOO_LARGE'); operation.fail('OUTPUT_TOO_LARGE')\n return errorResult(`tool result exceeds the ${limits.maxOutputBytes}-byte limit`, 'OUTPUT_TOO_LARGE')\n }\n const content = [\n ...toMcpContent(result.content),\n ...toMcpContent(result.additionalContext ?? []),\n ]\n if (result.isError) {\n attempt.fail(result.error.code); operation.fail(result.error.code)\n return {\n isError: true,\n content: content.length === 0 ? [{ type: 'text', text: result.error.message }] : content,\n structuredContent: { error: result.error },\n }\n }\n attempt.success(); operation.success()\n return {\n content: content.length === 0 ? [{ type: 'text', text: '(no output)' }] : content,\n ...(result.value === undefined ? {} : { structuredContent: result.value }),\n }\n } catch (error: unknown) {\n const code = integrationErrorCode(error)\n attempt.fail(code); operation.fail(code)\n await reportError(options, limits, error, 'tool', toolName, context)\n return errorResult(internalErrorMessage(options, error, 'tool operation failed'), 'TOOL_OPERATION_FAILED')\n }\n}\n\nasync function callAgent(\n options: SdkMcpServerOptions,\n definition: McpAgentTool,\n request: SdkMcpRequestContext,\n args: { input: string; conversationId?: string },\n context: ServerContext,\n): Promise<CallToolResult> {\n const limits = resolveLimits(options)\n const operation = beginIntegrationOperation(options.logger, serverFamily(options), 'agent-call')\n const attempt = operation.attempt(1)\n if (serializedBytes(args) > limits.maxInputBytes) {\n attempt.fail('INPUT_TOO_LARGE'); operation.fail('INPUT_TOO_LARGE')\n return errorResult(`agent input exceeds the ${limits.maxInputBytes}-byte limit`, 'INPUT_TOO_LARGE')\n }\n const signal = AbortSignal.any([context.mcpReq.signal, AbortSignal.timeout(limits.operationTimeoutMs)])\n try {\n const creating = Promise.resolve(definition.createSession({\n ...(args.conversationId === undefined ? {} : { conversationId: args.conversationId }),\n request,\n call: context,\n }))\n const session = await raceWithSignal(creating, signal, limits.teardownTimeoutMs)\n if (session.definition.id !== definition.agent.id) {\n attempt.fail('WRONG_AGENT_SESSION'); operation.fail('WRONG_AGENT_SESSION')\n return errorResult(\n `session factory for '${definition.name}' returned agent '${session.definition.id}', expected '${definition.agent.id}'`,\n 'WRONG_AGENT_SESSION',\n )\n }\n const running = session.run(args.input, { signal })\n const response = await raceWithSignal(running, signal, limits.teardownTimeoutMs)\n if (!isJsonValue(response.outcome)) {\n attempt.fail('INVALID_AGENT_RESULT'); operation.fail('INVALID_AGENT_RESULT')\n return errorResult('agent outcome was not lossless JSON', 'INVALID_AGENT_RESULT')\n }\n const result: CallToolResult = {\n content: [{ type: 'text', text: response.text || '(empty response)' }],\n structuredContent: {\n text: response.text,\n outcome: response.outcome,\n conversationId: session.conversationId,\n },\n }\n if (serializedBytes(result) > limits.maxOutputBytes) {\n attempt.fail('OUTPUT_TOO_LARGE'); operation.fail('OUTPUT_TOO_LARGE')\n return errorResult(`agent result exceeds the ${limits.maxOutputBytes}-byte limit`, 'OUTPUT_TOO_LARGE')\n }\n attempt.success(); operation.success()\n return result\n } catch (error: unknown) {\n const code = integrationErrorCode(error)\n if (signal.aborted) { attempt.abort(); operation.abort() }\n else { attempt.fail(code); operation.fail(code) }\n await reportError(options, limits, error, 'agent', definition.name, context)\n return errorResult(internalErrorMessage(options, error, 'agent operation failed'), 'AGENT_FAILED')\n }\n}\n\nfunction toMcpContent(blocks: readonly ContentBlock[]): McpResultBlock[] {\n const result: McpResultBlock[] = []\n for (const block of blocks) {\n if (block.type === 'text') {\n result.push({ type: 'text', text: block.text })\n continue\n }\n if (block.type === 'image' && block.source.kind === 'base64') {\n result.push({\n type: 'image',\n data: block.source.data,\n mimeType: block.source.mediaType,\n })\n continue\n }\n if (block.type === 'image' && block.source.kind === 'url') {\n result.push({ type: 'text', text: `[image](${block.source.url})` })\n continue\n }\n if (block.type === 'image' && block.source.kind === 'file') {\n result.push({ type: 'text', text: `[image file: ${block.source.fileId}]` })\n continue\n }\n if (block.type === 'reasoning') {\n result.push({ type: 'text', text: block.text })\n continue\n }\n result.push({ type: 'text', text: JSON.stringify(jsonSafeBlock(block)) })\n }\n return result\n}\n\nfunction jsonSafeBlock(block: ContentBlock): JsonValue {\n if (isJsonValue(block)) return block\n return { type: block.type }\n}\n\nfunction errorResult(message: string, code: string): CallToolResult {\n return {\n isError: true,\n content: [{ type: 'text', text: `Error: ${message}` }],\n structuredContent: { error: { message, code } },\n }\n}\n\nfunction assertIdentity(value: string, field: string): void {\n if (value.trim().length === 0) throw new TypeError(`${field} must not be empty`)\n}\n\nfunction errorMessage(value: unknown): string {\n return value instanceof Error && value.message.length > 0 ? value.message : String(value)\n}\n\ninterface ResolvedMcpServerLimits {\n readonly maxExports: number\n readonly maxDefinitionBytes: number\n readonly maxInputBytes: number\n readonly maxOutputBytes: number\n readonly operationTimeoutMs: number\n readonly teardownTimeoutMs: number\n readonly observerTimeoutMs: number\n}\n\nfunction resolveLimits(options: SdkMcpServerOptions): ResolvedMcpServerLimits {\n return {\n maxExports: positiveSafeInteger(options.maxExports ?? MCP_SERVER_DEFAULTS.maxExports, 'maxExports'),\n maxDefinitionBytes: positiveSafeInteger(\n options.maxDefinitionBytes ?? MCP_SERVER_DEFAULTS.maxDefinitionBytes, 'maxDefinitionBytes',\n ),\n maxInputBytes: positiveSafeInteger(options.maxInputBytes ?? MCP_SERVER_DEFAULTS.maxInputBytes, 'maxInputBytes'),\n maxOutputBytes: positiveSafeInteger(options.maxOutputBytes ?? MCP_SERVER_DEFAULTS.maxOutputBytes, 'maxOutputBytes'),\n operationTimeoutMs: positiveSafeInteger(\n options.operationTimeoutMs ?? MCP_SERVER_DEFAULTS.operationTimeoutMs, 'operationTimeoutMs',\n ),\n teardownTimeoutMs: positiveSafeInteger(\n options.teardownTimeoutMs ?? MCP_SERVER_DEFAULTS.teardownTimeoutMs, 'teardownTimeoutMs',\n ),\n observerTimeoutMs: positiveSafeInteger(\n options.observerTimeoutMs ?? MCP_SERVER_DEFAULTS.observerTimeoutMs, 'observerTimeoutMs',\n ),\n }\n}\n\nasync function reportError(\n options: SdkMcpServerOptions,\n limits: ResolvedMcpServerLimits,\n error: unknown,\n operation: McpServerErrorContext['operation'],\n exportName: string,\n context: ServerContext,\n): Promise<void> {\n if (options.onError === undefined) return\n const pending = Promise.resolve().then(() => options.onError?.(error, Object.freeze({\n operation,\n exportName,\n requestId: String(context.mcpReq.id),\n })))\n await waitForSettlement(pending, limits.observerTimeoutMs)\n}\n\nfunction internalErrorMessage(options: SdkMcpServerOptions, error: unknown, fallback: string): string {\n return options.exposeInternalErrors === true ? errorMessage(error) : fallback\n}\n\nfunction positiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`MCP server ${label} must be a positive safe integer`)\n return value\n}\n\nfunction serializedBytes(value: unknown): number {\n const serialized = JSON.stringify(value)\n if (serialized === undefined) throw new TypeError('MCP server value is not JSON serializable')\n return new TextEncoder().encode(serialized).byteLength\n}\n\nasync function raceWithSignal<T>(\n pending: Promise<T>,\n signal: AbortSignal,\n teardownTimeoutMs: number,\n): Promise<T> {\n if (signal.aborted) throw signal.reason ?? new Error('MCP server operation aborted')\n try {\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(signal.reason ?? new Error('MCP server operation aborted'))\n }\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n } catch (error: unknown) {\n if (signal.aborted) await waitForSettlement(pending, teardownTimeoutMs)\n throw error\n }\n}\n","import type { RuntimeAgent, RuntimeAgentInvocationOptions, RuntimeAgentResponse } from '@alvin0/ai-agent-sdk-core/agent'\nimport type { SdkLogger, ToolCatalog } from '@alvin0/ai-agent-sdk-core/tools'\nimport { createSdkMcpHandler, createSdkMcpServer, type SdkMcpServerOptions } from '../server/advanced.ts'\nimport {\n attachPreferredState, copyPreferredState, MCP_WEB_SERVER_FACTORY,\n type InternalMcpServerFactory, type PreferredServerAgent,\n} from '../common/preferred-state.ts'\nimport { MCP_SERVER_DEFAULTS } from '../common/config.ts'\n\nexport interface McpServerDefinition {\n readonly id: string\n readonly logger?: SdkLogger\n readonly tools?: ToolCatalog\n readonly agents?: Readonly<Record<string, RuntimeAgent>>\n readonly maxRequestBytes?: number\n readonly maxResponseBytes?: number\n}\n\nexport interface McpWebServer {\n handle(request: Request, options?: { readonly signal?: AbortSignal }): Promise<Response>\n}\n\n/** Capture one inert Web-standard server definition; each handle call owns its request resources. */\nexport function createMcpServer(definition: McpServerDefinition): McpWebServer {\n const source = objectValue(definition)\n const id = identity(ownValue(source, 'id'), 'MCP server id')\n const logger = optionalObject<SdkLogger>(ownValue(source, 'logger', false), 'MCP server logger')\n const tools = captureToolCatalog(ownValue(source, 'tools', false))\n const agents = captureAgents(ownValue(source, 'agents', false))\n const maxRequestBytes = positive(\n ownValue(source, 'maxRequestBytes', false) ?? MCP_SERVER_DEFAULTS.maxInputBytes, 'maxRequestBytes',\n )\n const maxResponseBytes = positive(\n ownValue(source, 'maxResponseBytes', false) ?? MCP_SERVER_DEFAULTS.maxOutputBytes, 'maxResponseBytes',\n )\n const advanced: SdkMcpServerOptions = Object.freeze({\n name: id, version: '1.0.0',\n ...(logger === undefined ? {} : { logger }),\n ...(tools === undefined ? {} : { tools }),\n maxInputBytes: maxRequestBytes, maxOutputBytes: maxResponseBytes,\n })\n attachPreferredState(advanced, Object.freeze({ agents }))\n\n const factory: InternalMcpServerFactory = (request, family) => {\n const scoped: SdkMcpServerOptions = { ...advanced, integrationFamily: family }\n copyPreferredState(advanced, scoped)\n return createSdkMcpServer(scoped, request)\n }\n const handle = async (request: Request, options?: { readonly signal?: AbortSignal }): Promise<Response> => {\n if (!(request instanceof Request)) throw new TypeError('MCP Web server requires a Request')\n const signal = options?.signal === undefined ? request.signal\n : AbortSignal.any([request.signal, options.signal])\n signal.throwIfAborted()\n const forwarded = signal === request.signal ? request : new Request(request, { signal })\n if (!await requestFits(forwarded, maxRequestBytes)) return payloadTooLarge()\n const handlerOptions: SdkMcpServerOptions = { ...advanced, integrationFamily: 'mcp-web-server' }\n copyPreferredState(advanced, handlerOptions)\n const handler = createSdkMcpHandler(handlerOptions)\n try {\n const response = await handler.fetch(forwarded)\n return boundedResponse(response, maxResponseBytes, handler.close)\n } catch (error: unknown) {\n await settleClose(handler.close)\n throw error\n }\n }\n const result = { handle }\n Object.defineProperty(result, MCP_WEB_SERVER_FACTORY, { value: factory, enumerable: false })\n return Object.freeze(result)\n}\n\nfunction captureAgents(value: unknown): Readonly<Record<string, PreferredServerAgent>> {\n if (value === undefined) return Object.freeze({})\n const source = objectValue(value), entries: [string, PreferredServerAgent][] = []\n for (const key of Reflect.ownKeys(source)) {\n if (typeof key !== 'string') throw new TypeError('MCP agent names must be strings')\n identity(key, 'MCP agent name')\n const agent = objectValue(ownValue(source, key)) as RuntimeAgent\n const generate = method(agent, 'generate')\n entries.push([key, Object.freeze({\n generate: (input: string, options: RuntimeAgentInvocationOptions): Promise<RuntimeAgentResponse> =>\n Reflect.apply(generate, agent, [input, options]) as Promise<RuntimeAgentResponse>,\n })])\n }\n return Object.freeze(Object.fromEntries(entries))\n}\n\nfunction captureToolCatalog(value: unknown): ToolCatalog | undefined {\n if (value === undefined) return undefined\n const catalog = objectValue(value) as ToolCatalog\n const get = method(catalog, 'get'), has = method(catalog, 'has'), names = method(catalog, 'names')\n const schemas = method(catalog, 'schemas'), executionMode = method(catalog, 'executionMode')\n return Object.freeze({\n get: (name: string) => Reflect.apply(get, catalog, [name]) as ReturnType<ToolCatalog['get']>,\n has: (name: string) => Reflect.apply(has, catalog, [name]) as boolean,\n names: () => Reflect.apply(names, catalog, []) as readonly string[],\n schemas: () => Reflect.apply(schemas, catalog, []) as ReturnType<ToolCatalog['schemas']>,\n executionMode(name: string, args: unknown): 'parallel' | 'exclusive' {\n return Reflect.apply(executionMode, catalog, [name, args]) as 'parallel' | 'exclusive'\n },\n })\n}\n\nasync function requestFits(request: Request, limit: number): Promise<boolean> {\n const declared = request.headers.get('content-length')\n if (declared !== null) {\n const bytes = Number(declared)\n if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > limit) return false\n }\n if (request.body === null) return true\n try { return (await request.clone().arrayBuffer()).byteLength <= limit } catch { return false }\n}\n\nfunction boundedResponse(response: Response, limit: number, close: () => Promise<void>): Response {\n if (response.body === null) { void settleClose(close); return response }\n const declared = response.headers.get('content-length')\n if (declared !== null && Number(declared) > limit) {\n void response.body.cancel(); void settleClose(close)\n return responseTooLarge()\n }\n const reader = response.body.getReader()\n let bytes = 0, closed = false\n const finish = async (): Promise<void> => {\n if (closed) return\n closed = true\n await settleClose(close)\n }\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const next = await reader.read()\n if (next.done) { controller.close(); await finish(); return }\n bytes += next.value.byteLength\n if (bytes > limit) {\n await reader.cancel(); await finish()\n controller.error(new RangeError('MCP response exceeded maxResponseBytes'))\n return\n }\n controller.enqueue(next.value)\n } catch (error: unknown) { await finish(); controller.error(error) }\n },\n async cancel(reason) { try { await reader.cancel(reason) } finally { await finish() } },\n })\n return new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers })\n}\n\nfunction payloadTooLarge(): Response {\n return Response.json({ jsonrpc: '2.0', id: null,\n error: { code: -32600, message: 'MCP request exceeds maxRequestBytes' } }, { status: 413 })\n}\nfunction responseTooLarge(): Response {\n return Response.json({ jsonrpc: '2.0', id: null,\n error: { code: -32603, message: 'MCP response exceeds maxResponseBytes' } }, { status: 500 })\n}\nasync function settleClose(close: () => Promise<void>): Promise<void> { try { await close() } catch {} }\nfunction objectValue(value: unknown): object {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new TypeError('Invalid MCP server definition')\n return value\n}\nfunction ownValue(source: object, key: PropertyKey, required = true): unknown {\n const descriptor = Object.getOwnPropertyDescriptor(source, key)\n if (descriptor === undefined) {\n if (!required) return undefined\n throw new TypeError(`Missing MCP server field ${String(key)}`)\n }\n if (!('value' in descriptor)) throw new TypeError(`MCP server field ${String(key)} must be data`)\n return descriptor.value\n}\nfunction method(source: object, key: PropertyKey): Function {\n const value = Reflect.get(source, key)\n if (typeof value !== 'function') throw new TypeError(`MCP server method ${String(key)} is invalid`)\n return value\n}\nfunction identity(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.length < 1 || value.length > 128) throw new TypeError(`${label} is invalid`)\n return value\n}\nfunction positive(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || Number(value) < 1) throw new TypeError(`MCP server ${label} is invalid`)\n return Number(value)\n}\nfunction optionalObject<T>(value: unknown, label: string): T | undefined {\n if (value === undefined) return undefined\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') throw new TypeError(`${label} is invalid`)\n return value as T\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@alvin0/ai-agent-sdk-mcp-server",
3
+ "author": {
4
+ "name": "alvin0 - chaulamdinhai",
5
+ "email": "chaulamdinhai@gmail.com"
6
+ },
7
+ "version": "0.1.0",
8
+ "description": "Universal Web Standards MCP server hosting for ai-agent-sdk",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/alvin0/ai-agent-sdk.git",
13
+ "directory": "packages/mcp-server"
14
+ },
15
+ "homepage": "https://github.com/alvin0/ai-agent-sdk/tree/main/packages/mcp-server#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/alvin0/ai-agent-sdk/issues"
18
+ },
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "provenance": true
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/server": "2.0.0"
42
+ },
43
+ "peerDependencies": {
44
+ "@alvin0/ai-agent-sdk-core": "^0.1.0"
45
+ },
46
+ "devDependencies": {
47
+ "@alvin0/ai-agent-sdk-core": "^0.1.0",
48
+ "@arethetypeswrong/cli": "0.18.5",
49
+ "playwright": "1.62.1",
50
+ "publint": "0.3.24",
51
+ "tsdown": "0.22.14",
52
+ "typescript": "7.0.2",
53
+ "vitest": "4.1.11",
54
+ "wrangler": "4.127.1"
55
+ },
56
+ "aiAgentSdk": {
57
+ "runtime": "universal",
58
+ "coreApi": 1,
59
+ "roles": [
60
+ "mcp-server"
61
+ ]
62
+ },
63
+ "scripts": {
64
+ "build": "tsdown",
65
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true});require('node:fs').rmSync('artifacts',{recursive:true,force:true})\"",
66
+ "typecheck": "tsc --noEmit",
67
+ "test": "vitest run --config vitest.config.ts",
68
+ "pack": "pnpm pack --pack-destination artifacts",
69
+ "test:pack": "node scripts/test-packed.mts",
70
+ "check:publint": "publint",
71
+ "check:types": "attw --profile esm-only --pack ."
72
+ }
73
+ }