@silkweave/mcp 2.6.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,11 +62,11 @@ Exposes `POST /mcp` (invoke tools), `GET /mcp` (SSE stream), and `DELETE /mcp` (
62
62
 
63
63
  ### cliProxy
64
64
 
65
- MCP CLI proxy client - connects to a running HTTP MCP server and invokes tools from the command line.
65
+ MCP CLI proxy client - connects to a running HTTP MCP server and invokes tools from the command line. Imported from the dedicated `@silkweave/mcp/cli-proxy` subpath (kept out of the package root so importing the `stdio`/`http` servers does not pull the CLI client's `commander` + `@clack/prompts` into the server path). Those two are **optional peer dependencies** - install them alongside `@silkweave/mcp` when you use the CLI proxy.
66
66
 
67
67
  ```typescript
68
68
  import { silkweave } from '@silkweave/core'
69
- import { cliProxy } from '@silkweave/mcp'
69
+ import { cliProxy } from '@silkweave/mcp/cli-proxy'
70
70
 
71
71
  await silkweave({ name: 'my-tools', description: 'My Tools', version: '1.0.0' })
72
72
  .adapter(cliProxy({ url: 'http://localhost:8080/mcp' }))
@@ -0,0 +1,13 @@
1
+ import { AdapterFactory } from "@silkweave/core";
2
+ import { ContentBlock } from "@modelcontextprotocol/sdk/types.js";
3
+
4
+ //#region src/adapter/cliProxy.d.ts
5
+ type CLIFormatterFn = (message: ContentBlock, index: number, messages: ContentBlock[]) => string | undefined;
6
+ interface CliProxyOptions {
7
+ url: URL;
8
+ formatter?: CLIFormatterFn;
9
+ }
10
+ declare const cliProxy: AdapterFactory<CliProxyOptions>;
11
+ //#endregion
12
+ export { CLIFormatterFn, CliProxyOptions, cliProxy };
13
+ //# sourceMappingURL=cliProxy.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliProxy.d.mts","names":[],"sources":["../src/adapter/cliProxy.ts"],"mappings":";;;;KAWY,cAAA,IAAkB,OAAA,EAAS,YAAA,EAAc,KAAA,UAAe,QAAA,EAAU,YAAA;AAAA,UAE7D,eAAA;EACf,GAAA,EAAK,GAAA;EACL,SAAA,GAAY,cAAA;AAAA;AAAA,cA4DD,QAAA,EAAU,cAAA,CAAe,eAAA"}
@@ -0,0 +1,113 @@
1
+ import { i as parseResourceMessage } from "./result-BiFuFt5B.mjs";
2
+ import { LoggingMessageNotificationSchema, ProgressNotificationSchema } from "@modelcontextprotocol/sdk/types.js";
3
+ import { createCLILogger } from "@silkweave/logger";
4
+ import { kebabCase } from "change-case";
5
+ import { randomUUID } from "crypto";
6
+ import { intro } from "@clack/prompts";
7
+ import { Client } from "@modelcontextprotocol/sdk/client";
8
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
9
+ import { Command } from "commander";
10
+ //#region src/adapter/cliProxy.ts
11
+ function coerce(value, type) {
12
+ if (value === void 0) return;
13
+ if (type === "number" || type === "integer") {
14
+ const n = Number(value);
15
+ return Number.isNaN(n) ? value : n;
16
+ }
17
+ return value;
18
+ }
19
+ function addCliOption(command, key, prop) {
20
+ const flag = kebabCase(key);
21
+ const description = prop.description;
22
+ const defaultValue = prop.default;
23
+ const type = prop.type;
24
+ if (type === "boolean") {
25
+ command.option(`--${flag}`, description, defaultValue);
26
+ command.option(`--no-${flag}`);
27
+ return;
28
+ }
29
+ if (type === "number" || type === "integer") {
30
+ command.option(`--${flag} <number>`, description, defaultValue);
31
+ return;
32
+ }
33
+ if (type === "string" || prop.enum) {
34
+ command.option(`--${flag} <string>`, description, defaultValue);
35
+ return;
36
+ }
37
+ if (type === "object" || type === "array") {
38
+ command.option(`--${flag} <json>`, description ?? "", JSON.parse, defaultValue);
39
+ return;
40
+ }
41
+ throw new Error(`Unsupported JSON Schema type for CLI option "${key}": ${type ?? "undefined"}`);
42
+ }
43
+ const defaultFormatter = (message) => {
44
+ if (message.type === "text" && !message.text.includes("mcp://toolResult/")) return `${message.text}`;
45
+ else if (message.type === "resource") return parseResourceMessage(message);
46
+ else return JSON.stringify(message);
47
+ };
48
+ const cliProxy = ({ url, formatter = defaultFormatter }) => {
49
+ return (options, baseContext) => {
50
+ const context = baseContext.fork({ adapter: "cliProxy" });
51
+ const program = new Command().name(options.name).description(options.description).version(options.version).option("-s, --silent", "Silent mode, prevent log messages", false);
52
+ return {
53
+ context,
54
+ start: async () => {
55
+ const client = new Client({
56
+ name: options.name,
57
+ description: options.description,
58
+ version: options.version
59
+ });
60
+ const transport = new StreamableHTTPClientTransport(url);
61
+ await client.connect(transport);
62
+ const { tools } = await client.listTools();
63
+ for (const tool of tools) {
64
+ const name = kebabCase(tool.name);
65
+ const command = program.command(name);
66
+ if (tool.description) command.description(tool.description);
67
+ const properties = tool.inputSchema.properties ?? {};
68
+ for (const key of Object.keys(properties)) addCliOption(command, key, properties[key]);
69
+ command.action(async (args) => {
70
+ const { silent } = program.opts();
71
+ const logger = createCLILogger();
72
+ if (!silent) {
73
+ intro(`${options.name} - ${tool.name}`);
74
+ client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {
75
+ logger[level](data);
76
+ });
77
+ client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {
78
+ logger.info({
79
+ progress,
80
+ total,
81
+ message
82
+ });
83
+ });
84
+ }
85
+ const input = {};
86
+ for (const key of Object.keys(properties)) {
87
+ const value = args[key];
88
+ if (value !== void 0) input[key] = coerce(value, properties[key]?.type);
89
+ }
90
+ (await client.callTool({
91
+ name: tool.name,
92
+ arguments: input,
93
+ _meta: {
94
+ progressToken: randomUUID(),
95
+ disposition: "json"
96
+ }
97
+ })).content.forEach((message, index, messages) => {
98
+ const text = formatter(message, index, messages);
99
+ process.stdout.write(`${text}\n`);
100
+ });
101
+ });
102
+ }
103
+ await program.parseAsync();
104
+ await transport.close();
105
+ },
106
+ stop: async () => {}
107
+ };
108
+ };
109
+ };
110
+ //#endregion
111
+ export { cliProxy };
112
+
113
+ //# sourceMappingURL=cliProxy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliProxy.mjs","names":[],"sources":["../src/adapter/cliProxy.ts"],"sourcesContent":["import { intro } from '@clack/prompts'\nimport { Client } from '@modelcontextprotocol/sdk/client'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { ContentBlock, LoggingMessageNotificationSchema, ProgressNotificationSchema, ToolResultContent } from '@modelcontextprotocol/sdk/types.js'\nimport { AdapterFactory } from '@silkweave/core'\nimport { createCLILogger } from '@silkweave/logger'\nimport { kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { randomUUID } from 'crypto'\nimport { parseResourceMessage } from '../util/result.js'\n\nexport type CLIFormatterFn = (message: ContentBlock, index: number, messages: ContentBlock[]) => string | undefined\n\nexport interface CliProxyOptions {\n url: URL\n formatter?: CLIFormatterFn\n}\n\ninterface JsonSchemaProperty {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | string\n description?: string\n default?: unknown\n enum?: unknown[]\n}\n\ninterface JsonSchemaObject {\n type?: 'object'\n properties?: Record<string, JsonSchemaProperty>\n required?: string[]\n}\n\nfunction coerce(value: unknown, type: JsonSchemaProperty['type']): unknown {\n if (value === undefined) { return undefined }\n if (type === 'number' || type === 'integer') {\n const n = Number(value)\n return Number.isNaN(n) ? value : n\n }\n return value\n}\n\nfunction addCliOption(command: Command, key: string, prop: JsonSchemaProperty) {\n const flag = kebabCase(key)\n const description = prop.description\n const defaultValue = prop.default\n const type = prop.type\n if (type === 'boolean') {\n command.option(`--${flag}`, description, defaultValue as boolean | undefined)\n command.option(`--no-${flag}`)\n return\n }\n if (type === 'number' || type === 'integer') {\n command.option(`--${flag} <number>`, description, defaultValue as string | undefined)\n return\n }\n if (type === 'string' || prop.enum) {\n command.option(`--${flag} <string>`, description, defaultValue as string | undefined)\n return\n }\n if (type === 'object' || type === 'array') {\n command.option(`--${flag} <json>`, description ?? '', JSON.parse, defaultValue as never)\n return\n }\n throw new Error(`Unsupported JSON Schema type for CLI option \"${key}\": ${type ?? 'undefined'}`)\n}\n\nconst defaultFormatter: CLIFormatterFn = (message) => {\n if (message.type === 'text' && !message.text.includes('mcp://toolResult/')) {\n return `${message.text}`\n } else if (message.type === 'resource') {\n return parseResourceMessage(message)\n } else {\n return JSON.stringify(message)\n }\n}\n\nexport const cliProxy: AdapterFactory<CliProxyOptions> = ({ url, formatter = defaultFormatter }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'cliProxy' })\n const program = new Command()\n .name(options.name)\n .description(options.description)\n .version(options.version)\n .option('-s, --silent', 'Silent mode, prevent log messages', false)\n\n return {\n context,\n start: async () => {\n const client = new Client({\n name: options.name,\n description: options.description,\n version: options.version\n })\n const transport = new StreamableHTTPClientTransport(url)\n await client.connect(transport)\n const { tools } = await client.listTools()\n for (const tool of tools) {\n const name = kebabCase(tool.name)\n const command = program.command(name)\n if (tool.description) { command.description(tool.description) }\n const schema = tool.inputSchema as JsonSchemaObject\n const properties = schema.properties ?? {}\n for (const key of Object.keys(properties)) {\n addCliOption(command, key, properties[key])\n }\n command.action(async (args: Record<string, unknown>) => {\n const { silent } = program.opts<{ silent: boolean }>()\n const logger = createCLILogger()\n if (!silent) {\n intro(`${options.name} - ${tool.name}`)\n client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {\n logger[level](data)\n })\n client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {\n logger.info({ progress, total, message })\n })\n }\n const input: Record<string, unknown> = {}\n for (const key of Object.keys(properties)) {\n const value = args[key]\n if (value !== undefined) { input[key] = coerce(value, properties[key]?.type) }\n }\n const response = await client.callTool({\n name: tool.name,\n arguments: input,\n _meta: { progressToken: randomUUID(), disposition: 'json' }\n }) as ToolResultContent\n response.content.forEach((message, index, messages) => {\n const text = formatter(message, index, messages)\n process.stdout.write(`${text}\\n`)\n })\n })\n }\n await program.parseAsync()\n await transport.close()\n },\n stop: async () => { /* noop */ }\n }\n }\n}\n"],"mappings":"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"}
package/build/index.d.mts CHANGED
@@ -1,20 +1,12 @@
1
- import { CallToolResult, ContentBlock, EmbeddedResource } from "@modelcontextprotocol/sdk/types.js";
2
- import { Action, AdapterFactory, SilkweaveContext, SilkweaveError, SilkweaveOptions } from "@silkweave/core";
3
1
  import { CreateMcpExpressAppOptions } from "@modelcontextprotocol/sdk/server/express.js";
2
+ import { Action, AdapterFactory, SilkweaveContext, SilkweaveError, SilkweaveOptions } from "@silkweave/core";
4
3
  import { Express, RequestHandler } from "express";
5
4
  import { AuthConfig, AuthInfo } from "@silkweave/auth";
6
5
  import { AsyncLocalStorage } from "node:async_hooks";
7
6
  import { CorsOptions, CorsOptions as CorsOptions$1 } from "cors";
7
+ import { CallToolResult, EmbeddedResource } from "@modelcontextprotocol/sdk/types.js";
8
8
  import { Server } from "http";
9
9
 
10
- //#region src/adapter/cliProxy.d.ts
11
- type CLIFormatterFn = (message: ContentBlock, index: number, messages: ContentBlock[]) => string | undefined;
12
- interface CliProxyOptions {
13
- url: URL;
14
- formatter?: CLIFormatterFn;
15
- }
16
- declare const cliProxy: AdapterFactory<CliProxyOptions>;
17
- //#endregion
18
10
  //#region src/adapter/http.d.ts
19
11
  interface StartMcpHttpOptions extends CreateMcpExpressAppOptions {
20
12
  host: string;
@@ -171,5 +163,5 @@ declare function createSideloadResource(buffer: Buffer, {
171
163
  contentType
172
164
  }: Pick<SideloadResource, 'name' | 'contentType'>): Promise<SideloadResource>;
173
165
  //#endregion
174
- export { CLIFormatterFn, CliProxyOptions, type CorsOptions, MCP_REQUIRED_HEADERS, McpTransportHandlers, OAuthRouteHandlers, SideloadResource, SideloadResourceOptions, StartMcpHttpOptions, authMiddleware, authStorage, buildMcpExpressApp, cliProxy, createSideloadResource, errorToolResult, handleToolError, http, jsonToolResult, mcpCors, mcpTransport, oauthRoutes, parseResourceMessage, protectedResourceMetadata, sideloadResource, smartToolResult, startMcpServer, stdio };
166
+ export { type CorsOptions, MCP_REQUIRED_HEADERS, McpTransportHandlers, OAuthRouteHandlers, SideloadResource, SideloadResourceOptions, StartMcpHttpOptions, authMiddleware, authStorage, buildMcpExpressApp, createSideloadResource, errorToolResult, handleToolError, http, jsonToolResult, mcpCors, mcpTransport, oauthRoutes, parseResourceMessage, protectedResourceMetadata, sideloadResource, smartToolResult, startMcpServer, stdio };
175
167
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/cliProxy.ts","../src/adapter/http.ts","../src/adapter/stdio.ts","../src/handlers/auth.ts","../src/handlers/cors.ts","../src/handlers/metadata.ts","../src/handlers/oauth.ts","../src/handlers/sideload.ts","../src/handlers/transport.ts","../src/util/result.ts","../src/util/sideload.ts"],"mappings":";;;;;;;;;;KAWY,cAAA,IAAkB,OAAA,EAAS,YAAA,EAAc,KAAA,UAAe,QAAA,EAAU,YAAA;AAAA,UAE7D,eAAA;EACf,GAAA,EAAK,GAAA;EACL,SAAA,GAAY,cAAA;AAAA;AAAA,cA4DD,QAAA,EAAU,cAAA,CAAe,eAAA;;;UC9DrB,mBAAA,SAA4B,0BAAA;EAC3C,IAAA;EACA,IAAA;EACA,IAAA,GAAO,UAAA;EDLG;ECOV,IAAA,GAAO,aAAA;;EAEP,iBAAA;EDTqC;ECWrC,WAAA;AAAA;;;;;ADTF;;;iBCmBgB,kBAAA,CACd,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,gBAAA,EACT,OAAA,EAAS,MAAA,IACT,OAAA,EAAS,mBAAA,GACR,OAAA;;;;;;;iBAiDmB,cAAA,CACpB,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,MAAA,IACT,OAAA,EAAS,mBAAA,EACT,OAAA,GAAU,gBAAA,GACT,OAAA,CAAQ,MAAA;;;;;cAgBE,IAAA,EAAM,cAAA,CAAe,mBAAA;;;cCxDrB,KAAA,EAAO,cAAA;;;;;;;cC1CP,WAAA,EAAW,iBAAA,CAAA,QAAA;;AHExB;;;;;;;;;iBGUgB,cAAA,CAAe,IAAA,EAAM,UAAA,EAAY,OAAA,EAAS,gBAAA,GAAmB,cAAA;;;;cCjBhE,oBAAA;;;;;;;AJOb;;iBIGgB,OAAA,CAAQ,UAAA,GAAY,aAAA,aAA+B,cAAA;;;;;;;;iBCNnD,yBAAA,CAA0B,IAAA,EAAM,UAAA,GAAa,cAAA;;;UCa5C,kBAAA;;EAEf,mBAAA,EAAqB,cAAA;;EAErB,SAAA,EAAW,cAAA;;EAEX,QAAA,EAAU,cAAA;;EAEV,YAAA;ENlBwB;EMoBxB,KAAA,EAAO,cAAA;ENpBiF;EMsBxF,QAAA,EAAU,cAAA;AAAA;;;;;;ANpBZ;;;;;iBMiCgB,WAAA,CAAY,IAAA,EAAM,UAAA,GAAa,kBAAA;;;UC1C9B,uBAAA;;EAEf,WAAA;AAAA;;;;;;APKF;iBOIgB,gBAAA,CAAiB,OAAA,GAAS,uBAAA,GAA+B,cAAA;;;UCiGxD,oBAAA;;EAEf,IAAA,EAAM,cAAA;;EAEN,MAAA,EAAQ,cAAA;AAAA;;;ARzGV;;;;;iBQmHgB,YAAA,CACd,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,gBAAA,EACT,OAAA,EAAS,MAAA,KACR,oBAAA;;;iBC9Ha,eAAA,CAAgB,IAAA,+BAAmC,cAAA;AAAA,iBAqBnD,cAAA,CAAe,IAAA,UAAc,OAAA,aAAkB,cAAA;AAAA,iBAM/C,eAAA,CAAA;EAAkB,IAAA;EAAM,IAAA;EAAM;AAAA,GAAW,cAAA,GAAiB,cAAA;AAAA,iBAU1D,eAAA,CAAgB,KAAA,YAAiB,cAAA;AAAA,iBAejC,oBAAA,CAAA;EAAuB;AAAA,GAAY,gBAAA;;;UCrDlC,gBAAA;EACf,EAAA;EACA,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,iBAGoB,sBAAA,CAAuB,MAAA,EAAQ,MAAA;EAAU,IAAA;EAAM;AAAA,GAAe,IAAA,CAAK,gBAAA,4BAAyC,OAAA,CAAA,gBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/http.ts","../src/adapter/stdio.ts","../src/handlers/auth.ts","../src/handlers/cors.ts","../src/handlers/metadata.ts","../src/handlers/oauth.ts","../src/handlers/sideload.ts","../src/handlers/transport.ts","../src/util/result.ts","../src/util/sideload.ts"],"mappings":";;;;;;;;;;UAaiB,mBAAA,SAA4B,0BAAA;EAC3C,IAAA;EACA,IAAA;EACA,IAAA,GAAO,UAAA;EAHQ;EAKf,IAAA,GAAO,aAAA;;EAEP,iBAAA;EAFO;EAIP,WAAA;AAAA;;;;;;;;iBAUc,kBAAA,CACd,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,gBAAA,EACT,OAAA,EAAS,MAAA,IACT,OAAA,EAAS,mBAAA,GACR,OAAA;;;;;AALH;;iBAsDsB,cAAA,CACpB,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,MAAA,IACT,OAAA,EAAS,mBAAA,EACT,OAAA,GAAU,gBAAA,GACT,OAAA,CAAQ,MAAA;;;;;cAgBE,IAAA,EAAM,cAAA,CAAe,mBAAA;;;cCxDrB,KAAA,EAAO,cAAA;;;;;;;cC1CP,WAAA,EAAW,iBAAA,CAAA,QAAA;;AFIxB;;;;;;;;;iBEQgB,cAAA,CAAe,IAAA,EAAM,UAAA,EAAY,OAAA,EAAS,gBAAA,GAAmB,cAAA;;;;cCjBhE,oBAAA;;;;;;;AHSb;;iBGCgB,OAAA,CAAQ,UAAA,GAAY,aAAA,aAA+B,cAAA;;;;;;;;iBCNnD,yBAAA,CAA0B,IAAA,EAAM,UAAA,GAAa,cAAA;;;UCa5C,kBAAA;;EAEf,mBAAA,EAAqB,cAAA;;EAErB,SAAA,EAAW,cAAA;;EAEX,QAAA,EAAU,cAAA;;EAEV,YAAA;ELhBmC;EKkBnC,KAAA,EAAO,cAAA;ELfA;EKiBP,QAAA,EAAU,cAAA;AAAA;;;;;;;;;;;iBAaI,WAAA,CAAY,IAAA,EAAM,UAAA,GAAa,kBAAA;;;UC1C9B,uBAAA;;EAEf,WAAA;AAAA;;;;;;ANOF;iBMEgB,gBAAA,CAAiB,OAAA,GAAS,uBAAA,GAA+B,cAAA;;;UCiGxD,oBAAA;;EAEf,IAAA,EAAM,cAAA;;EAEN,MAAA,EAAQ,cAAA;AAAA;;;APvGV;;;;;iBOiHgB,YAAA,CACd,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,gBAAA,EACT,OAAA,EAAS,MAAA,KACR,oBAAA;;;iBC9Ha,eAAA,CAAgB,IAAA,+BAAmC,cAAA;AAAA,iBAqBnD,cAAA,CAAe,IAAA,UAAc,OAAA,aAAkB,cAAA;AAAA,iBAM/C,eAAA,CAAA;EAAkB,IAAA;EAAM,IAAA;EAAM;AAAA,GAAW,cAAA,GAAiB,cAAA;AAAA,iBAU1D,eAAA,CAAgB,KAAA,YAAiB,cAAA;AAAA,iBAejC,oBAAA,CAAA;EAAuB;AAAA,GAAY,gBAAA;;;UCrDlC,gBAAA;EACf,EAAA;EACA,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,iBAGoB,sBAAA,CAAuB,MAAA,EAAQ,MAAA;EAAU,IAAA;EAAM;AAAA,GAAe,IAAA,CAAK,gBAAA,4BAAyC,OAAA,CAAA,gBAAA"}
package/build/index.mjs CHANGED
@@ -1,14 +1,6 @@
1
- import { intro } from "@clack/prompts";
2
- import { Client } from "@modelcontextprotocol/sdk/client";
3
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
- import { LoggingMessageNotificationSchema, ProgressNotificationSchema, isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
5
- import { createCLILogger, createLogger } from "@silkweave/logger";
6
- import { capitalCase, kebabCase, pascalCase } from "change-case";
7
- import { Command } from "commander";
8
- import { randomUUID } from "crypto";
9
- import { SilkweaveError, createContext, isStreamingAction, runStreamingAction } from "@silkweave/core";
10
- import { randomUUID as randomUUID$1 } from "node:crypto";
1
+ import { a as smartToolResult, i as parseResourceMessage, n as handleToolError, r as jsonToolResult, t as errorToolResult } from "./result-BiFuFt5B.mjs";
11
2
  import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
3
+ import { createContext, isStreamingAction, runStreamingAction } from "@silkweave/core";
12
4
  import express from "express";
13
5
  import { generateProtectedResourceMetadata, validateToken } from "@silkweave/auth";
14
6
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -17,182 +9,11 @@ import { readFile, writeFile } from "fs/promises";
17
9
  import { InMemoryEventStore } from "@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js";
18
10
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
19
11
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
12
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
13
+ import { createLogger } from "@silkweave/logger";
14
+ import { capitalCase, pascalCase } from "change-case";
15
+ import { randomUUID } from "crypto";
20
16
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
- //#region src/util/result.ts
22
- function smartToolResult(data) {
23
- const text = typeof data === "string" ? data : JSON.stringify(data);
24
- const mimeType = typeof data === "string" ? "text/plain" : "application/json";
25
- const ext = typeof data === "string" ? "txt" : "json";
26
- if (text.length > 4096) {
27
- const uri = `mcp://toolResult/${randomUUID$1()}.${ext}`;
28
- const buffer = Buffer.from(text);
29
- const blob = buffer.toString("base64");
30
- return { content: [{
31
- type: "text",
32
- text: `Received resource ${uri} with ${buffer.byteLength} bytes`
33
- }, {
34
- type: "resource",
35
- resource: {
36
- uri,
37
- mimeType,
38
- blob
39
- }
40
- }] };
41
- } else return { content: [{
42
- type: "text",
43
- text
44
- }] };
45
- }
46
- function jsonToolResult(data, isError = false) {
47
- const result = { content: [{
48
- type: "text",
49
- text: JSON.stringify(data)
50
- }] };
51
- if (isError) result.isError = true;
52
- return result;
53
- }
54
- function errorToolResult({ code, name, message }) {
55
- return {
56
- isError: true,
57
- content: [{
58
- type: "text",
59
- text: JSON.stringify({
60
- success: false,
61
- code,
62
- name,
63
- message
64
- })
65
- }]
66
- };
67
- }
68
- function handleToolError(error) {
69
- if (error instanceof SilkweaveError) return jsonToolResult({
70
- success: false,
71
- name: error.name,
72
- message: error.message,
73
- code: error.code
74
- }, true);
75
- else if (error instanceof Error) {
76
- console.error(error);
77
- return jsonToolResult({
78
- success: false,
79
- name: error.name,
80
- message: error.message
81
- }, true);
82
- } else {
83
- console.error("Unknown tool error:", error);
84
- return jsonToolResult({
85
- success: false,
86
- name: "Unknown error",
87
- message: "An unknown error occurred"
88
- }, true);
89
- }
90
- }
91
- function parseResourceMessage({ resource }) {
92
- return "blob" in resource ? Buffer.from(resource.blob, "base64").toString("utf-8") : resource.text;
93
- }
94
- //#endregion
95
- //#region src/adapter/cliProxy.ts
96
- function coerce(value, type) {
97
- if (value === void 0) return;
98
- if (type === "number" || type === "integer") {
99
- const n = Number(value);
100
- return Number.isNaN(n) ? value : n;
101
- }
102
- return value;
103
- }
104
- function addCliOption(command, key, prop) {
105
- const flag = kebabCase(key);
106
- const description = prop.description;
107
- const defaultValue = prop.default;
108
- const type = prop.type;
109
- if (type === "boolean") {
110
- command.option(`--${flag}`, description, defaultValue);
111
- command.option(`--no-${flag}`);
112
- return;
113
- }
114
- if (type === "number" || type === "integer") {
115
- command.option(`--${flag} <number>`, description, defaultValue);
116
- return;
117
- }
118
- if (type === "string" || prop.enum) {
119
- command.option(`--${flag} <string>`, description, defaultValue);
120
- return;
121
- }
122
- if (type === "object" || type === "array") {
123
- command.option(`--${flag} <json>`, description ?? "", JSON.parse, defaultValue);
124
- return;
125
- }
126
- throw new Error(`Unsupported JSON Schema type for CLI option "${key}": ${type ?? "undefined"}`);
127
- }
128
- const defaultFormatter = (message) => {
129
- if (message.type === "text" && !message.text.includes("mcp://toolResult/")) return `${message.text}`;
130
- else if (message.type === "resource") return parseResourceMessage(message);
131
- else return JSON.stringify(message);
132
- };
133
- const cliProxy = ({ url, formatter = defaultFormatter }) => {
134
- return (options, baseContext) => {
135
- const context = baseContext.fork({ adapter: "cliProxy" });
136
- const program = new Command().name(options.name).description(options.description).version(options.version).option("-s, --silent", "Silent mode, prevent log messages", false);
137
- return {
138
- context,
139
- start: async () => {
140
- const client = new Client({
141
- name: options.name,
142
- description: options.description,
143
- version: options.version
144
- });
145
- const transport = new StreamableHTTPClientTransport(url);
146
- await client.connect(transport);
147
- const { tools } = await client.listTools();
148
- for (const tool of tools) {
149
- const name = kebabCase(tool.name);
150
- const command = program.command(name);
151
- if (tool.description) command.description(tool.description);
152
- const properties = tool.inputSchema.properties ?? {};
153
- for (const key of Object.keys(properties)) addCliOption(command, key, properties[key]);
154
- command.action(async (args) => {
155
- const { silent } = program.opts();
156
- const logger = createCLILogger();
157
- if (!silent) {
158
- intro(`${options.name} - ${tool.name}`);
159
- client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {
160
- logger[level](data);
161
- });
162
- client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {
163
- logger.info({
164
- progress,
165
- total,
166
- message
167
- });
168
- });
169
- }
170
- const input = {};
171
- for (const key of Object.keys(properties)) {
172
- const value = args[key];
173
- if (value !== void 0) input[key] = coerce(value, properties[key]?.type);
174
- }
175
- (await client.callTool({
176
- name: tool.name,
177
- arguments: input,
178
- _meta: {
179
- progressToken: randomUUID(),
180
- disposition: "json"
181
- }
182
- })).content.forEach((message, index, messages) => {
183
- const text = formatter(message, index, messages);
184
- process.stdout.write(`${text}\n`);
185
- });
186
- });
187
- }
188
- await program.parseAsync();
189
- await transport.close();
190
- },
191
- stop: async () => {}
192
- };
193
- };
194
- };
195
- //#endregion
196
17
  //#region src/handlers/auth.ts
197
18
  /**
198
19
  * Per-request bearer-token storage used by tool handlers to read the resolved
@@ -693,6 +514,6 @@ async function createSideloadResource(buffer, { name, contentType }) {
693
514
  return resource;
694
515
  }
695
516
  //#endregion
696
- export { MCP_REQUIRED_HEADERS, authMiddleware, authStorage, buildMcpExpressApp, cliProxy, createSideloadResource, errorToolResult, handleToolError, http, jsonToolResult, mcpCors, mcpTransport, oauthRoutes, parseResourceMessage, protectedResourceMetadata, sideloadResource, smartToolResult, startMcpServer, stdio };
517
+ export { MCP_REQUIRED_HEADERS, authMiddleware, authStorage, buildMcpExpressApp, createSideloadResource, errorToolResult, handleToolError, http, jsonToolResult, mcpCors, mcpTransport, oauthRoutes, parseResourceMessage, protectedResourceMetadata, sideloadResource, smartToolResult, startMcpServer, stdio };
697
518
 
698
519
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["randomUUID","registerTools"],"sources":["../src/util/result.ts","../src/adapter/cliProxy.ts","../src/handlers/auth.ts","../src/handlers/cors.ts","../src/handlers/metadata.ts","../src/handlers/oauth.ts","../src/handlers/sideload.ts","../src/handlers/transport.ts","../src/adapter/http.ts","../src/adapter/stdio.ts","../src/util/sideload.ts"],"sourcesContent":["import { EmbeddedResource, type CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { SilkweaveError } from '@silkweave/core'\nimport { randomUUID } from 'node:crypto'\n\nexport function smartToolResult(data: string | object | object[]): CallToolResult {\n const text = typeof data === 'string' ? data : JSON.stringify(data)\n const mimeType = typeof data === 'string' ? 'text/plain' : 'application/json'\n const ext = typeof data === 'string' ? 'txt' : 'json'\n if (text.length > 4096) {\n const uri = `mcp://toolResult/${randomUUID()}.${ext}`\n const buffer = Buffer.from(text)\n const blob = buffer.toString('base64')\n return {\n content: [\n { type: 'text', text: `Received resource ${uri} with ${buffer.byteLength} bytes` },\n { type: 'resource', resource: { uri, mimeType, blob } }\n ]\n }\n } else {\n return {\n content: [{ type: 'text' as const, text }]\n }\n }\n}\n\nexport function jsonToolResult(data: object, isError = false): CallToolResult {\n const result: CallToolResult = { content: [{ type: 'text' as const, text: JSON.stringify(data) }] }\n if (isError) { result.isError = true }\n return result\n}\n\nexport function errorToolResult({ code, name, message }: SilkweaveError): CallToolResult {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: JSON.stringify({ success: false, code, name, message })\n }]\n }\n}\n\nexport function handleToolError(error: unknown): CallToolResult {\n if (error instanceof SilkweaveError) {\n return jsonToolResult({ success: false, name: error.name, message: error.message, code: error.code }, true)\n } else if (error instanceof Error) {\n // Log the full error (incl. stack) to stderr only - never put the stack trace\n // on the wire, where it would leak server internals to the MCP client.\n console.error(error)\n return jsonToolResult({ success: false, name: error.name, message: error.message }, true)\n } else {\n // Likewise keep the raw thrown value server-side - only a generic message goes out.\n console.error('Unknown tool error:', error)\n return jsonToolResult({ success: false, name: 'Unknown error', message: 'An unknown error occurred' }, true)\n }\n}\n\nexport function parseResourceMessage({ resource }: EmbeddedResource) {\n const text = ('blob' in resource) ? Buffer.from(resource.blob, 'base64').toString('utf-8') : resource.text\n return text\n}\n","import { intro } from '@clack/prompts'\nimport { Client } from '@modelcontextprotocol/sdk/client'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { ContentBlock, LoggingMessageNotificationSchema, ProgressNotificationSchema, ToolResultContent } from '@modelcontextprotocol/sdk/types.js'\nimport { AdapterFactory } from '@silkweave/core'\nimport { createCLILogger } from '@silkweave/logger'\nimport { kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { randomUUID } from 'crypto'\nimport { parseResourceMessage } from '../util/result.js'\n\nexport type CLIFormatterFn = (message: ContentBlock, index: number, messages: ContentBlock[]) => string | undefined\n\nexport interface CliProxyOptions {\n url: URL\n formatter?: CLIFormatterFn\n}\n\ninterface JsonSchemaProperty {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | string\n description?: string\n default?: unknown\n enum?: unknown[]\n}\n\ninterface JsonSchemaObject {\n type?: 'object'\n properties?: Record<string, JsonSchemaProperty>\n required?: string[]\n}\n\nfunction coerce(value: unknown, type: JsonSchemaProperty['type']): unknown {\n if (value === undefined) { return undefined }\n if (type === 'number' || type === 'integer') {\n const n = Number(value)\n return Number.isNaN(n) ? value : n\n }\n return value\n}\n\nfunction addCliOption(command: Command, key: string, prop: JsonSchemaProperty) {\n const flag = kebabCase(key)\n const description = prop.description\n const defaultValue = prop.default\n const type = prop.type\n if (type === 'boolean') {\n command.option(`--${flag}`, description, defaultValue as boolean | undefined)\n command.option(`--no-${flag}`)\n return\n }\n if (type === 'number' || type === 'integer') {\n command.option(`--${flag} <number>`, description, defaultValue as string | undefined)\n return\n }\n if (type === 'string' || prop.enum) {\n command.option(`--${flag} <string>`, description, defaultValue as string | undefined)\n return\n }\n if (type === 'object' || type === 'array') {\n command.option(`--${flag} <json>`, description ?? '', JSON.parse, defaultValue as never)\n return\n }\n throw new Error(`Unsupported JSON Schema type for CLI option \"${key}\": ${type ?? 'undefined'}`)\n}\n\nconst defaultFormatter: CLIFormatterFn = (message) => {\n if (message.type === 'text' && !message.text.includes('mcp://toolResult/')) {\n return `${message.text}`\n } else if (message.type === 'resource') {\n return parseResourceMessage(message)\n } else {\n return JSON.stringify(message)\n }\n}\n\nexport const cliProxy: AdapterFactory<CliProxyOptions> = ({ url, formatter = defaultFormatter }) => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'cliProxy' })\n const program = new Command()\n .name(options.name)\n .description(options.description)\n .version(options.version)\n .option('-s, --silent', 'Silent mode, prevent log messages', false)\n\n return {\n context,\n start: async () => {\n const client = new Client({\n name: options.name,\n description: options.description,\n version: options.version\n })\n const transport = new StreamableHTTPClientTransport(url)\n await client.connect(transport)\n const { tools } = await client.listTools()\n for (const tool of tools) {\n const name = kebabCase(tool.name)\n const command = program.command(name)\n if (tool.description) { command.description(tool.description) }\n const schema = tool.inputSchema as JsonSchemaObject\n const properties = schema.properties ?? {}\n for (const key of Object.keys(properties)) {\n addCliOption(command, key, properties[key])\n }\n command.action(async (args: Record<string, unknown>) => {\n const { silent } = program.opts<{ silent: boolean }>()\n const logger = createCLILogger()\n if (!silent) {\n intro(`${options.name} - ${tool.name}`)\n client.setNotificationHandler(LoggingMessageNotificationSchema, ({ params: { level, data } }) => {\n logger[level](data)\n })\n client.setNotificationHandler(ProgressNotificationSchema, ({ params: { progress, total, message } }) => {\n logger.info({ progress, total, message })\n })\n }\n const input: Record<string, unknown> = {}\n for (const key of Object.keys(properties)) {\n const value = args[key]\n if (value !== undefined) { input[key] = coerce(value, properties[key]?.type) }\n }\n const response = await client.callTool({\n name: tool.name,\n arguments: input,\n _meta: { progressToken: randomUUID(), disposition: 'json' }\n }) as ToolResultContent\n response.content.forEach((message, index, messages) => {\n const text = formatter(message, index, messages)\n process.stdout.write(`${text}\\n`)\n })\n })\n }\n await program.parseAsync()\n await transport.close()\n },\n stop: async () => { /* noop */ }\n }\n }\n}\n","import { AuthConfig, AuthInfo, validateToken } from '@silkweave/auth'\nimport { SilkweaveContext } from '@silkweave/core'\nimport { type RequestHandler } from 'express'\nimport { AsyncLocalStorage } from 'node:async_hooks'\n\n/**\n * Per-request bearer-token storage used by tool handlers to read the resolved\n * `AuthInfo` for the currently-handled MCP call.\n */\nexport const authStorage = new AsyncLocalStorage<AuthInfo>()\n\n/**\n * Express middleware that validates the `Authorization: Bearer …` header via\n * the supplied `AuthConfig`. On success the resolved `AuthInfo` is placed in\n * `authStorage` for the duration of the downstream handler - `mcpTransport`'s\n * tool callbacks pick it up to populate the silkweave context's `auth` key.\n *\n * The middleware should NOT be applied to OAuth-discovery / token routes -\n * compose it only on the routes that require an authenticated caller (the MCP\n * transport itself, sideload, etc.).\n */\nexport function authMiddleware(auth: AuthConfig, context: SilkweaveContext): RequestHandler {\n return async (req, res, next) => {\n const result = await validateToken(req.headers.authorization, auth, context.fork({ request: req }))\n if (result.error) {\n for (const [key, value] of Object.entries(result.error.headers)) { res.header(key, value) }\n res.status(result.error.statusCode).json(result.error.body)\n return\n }\n if (result.auth) {\n authStorage.run(result.auth, () => { next() })\n } else {\n next()\n }\n }\n}\n","import cors, { CorsOptions } from 'cors'\nimport { type RequestHandler } from 'express'\n\n/** Headers required by the MCP protocol that must always be exposed when CORS is in use. */\nexport const MCP_REQUIRED_HEADERS = ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version']\n\n/**\n * CORS middleware preconfigured to expose the headers MCP clients need\n * (`Mcp-Session-Id`, `Last-Event-Id`, `Mcp-Protocol-Version`, `WWW-Authenticate`)\n * on top of any user-supplied options.\n *\n * Pass `false` to disable, omit / pass `true` for permissive defaults, or pass\n * a `CorsOptions` object to override.\n */\nexport function mcpCors(corsConfig: CorsOptions | boolean = true): RequestHandler | null {\n if (corsConfig === false) { return null }\n const userConfig = corsConfig === true ? {} : corsConfig\n const userExposed = userConfig.exposedHeaders\n const exposedHeaders = [\n ...MCP_REQUIRED_HEADERS,\n ...(Array.isArray(userExposed) ? userExposed : userExposed ? [userExposed] : [])\n ]\n return cors({ origin: '*', ...userConfig, exposedHeaders })\n}\n","import { AuthConfig, generateProtectedResourceMetadata } from '@silkweave/auth'\nimport { type RequestHandler } from 'express'\n\n/**\n * Handler for `GET /.well-known/oauth-protected-resource` (RFC 9728). Returns\n * the resource server's metadata pointing at the configured authorization\n * servers. Requires `auth.resourceUrl` and a non-empty `auth.authorizationServers`.\n */\nexport function protectedResourceMetadata(auth: AuthConfig): RequestHandler {\n if (!auth.resourceUrl || !auth.authorizationServers?.length) {\n throw new Error('@silkweave/mcp protectedResourceMetadata(): auth.resourceUrl and auth.authorizationServers are required')\n }\n const metadata = generateProtectedResourceMetadata(auth.resourceUrl, auth.authorizationServers)\n return (_req, res) => { res.json(metadata) }\n}\n","import { AuthConfig, OAuthRequest, OAuthResponse } from '@silkweave/auth'\nimport express, { type Request, type RequestHandler, type Response } from 'express'\n\nfunction toOAuthReq(req: Request): OAuthRequest {\n return {\n method: req.method,\n url: new URL(req.url, `${req.protocol}://${req.get('host')}`),\n headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),\n body: req.body as Record<string, string> | undefined\n }\n}\n\nfunction sendOAuth(res: Response, oauthRes: OAuthResponse) {\n for (const [key, value] of Object.entries(oauthRes.headers)) { res.header(key, value) }\n if (oauthRes.body) {\n res.status(oauthRes.status).send(typeof oauthRes.body === 'string' ? oauthRes.body : JSON.stringify(oauthRes.body))\n } else {\n res.status(oauthRes.status).end()\n }\n}\n\nexport interface OAuthRouteHandlers {\n /** `GET /.well-known/oauth-authorization-server` - RFC 8414 discovery. */\n wellKnownAuthServer: RequestHandler\n /** `GET /authorize` - start the OAuth flow. */\n authorize: RequestHandler\n /** `GET {callbackPath}` - provider callback. */\n callback: RequestHandler\n /** Path the provider should redirect to (defaults to `/auth/callback`). */\n callbackPath: string\n /** `POST /token` - exchange code / refresh token. Includes urlencoded body parser. */\n token: RequestHandler[]\n /** `POST /register` - dynamic client registration. Includes JSON body parser. */\n register: RequestHandler[]\n}\n\n/**\n * Build the OAuth 2.1 proxy route handlers (authorize, callback, token,\n * register, well-known) backed by the configured `auth.provider`. Returns the\n * handlers as individual `RequestHandler`s so callers can register them\n * wherever they like - under `/mcp`, at the server root, etc.\n *\n * `token` and `register` are returned as middleware arrays because the\n * appropriate body parser must run before the handler. Apply with\n * `app.post(path, ...token)`.\n */\nexport function oauthRoutes(auth: AuthConfig): OAuthRouteHandlers {\n if (!auth.provider) { throw new Error('@silkweave/mcp oauthRoutes(): auth.provider is required') }\n const provider = auth.provider\n const callbackPath = auth.callbackPath ?? '/auth/callback'\n\n return {\n callbackPath,\n wellKnownAuthServer: (_req, res) => { sendOAuth(res, provider.metadata()) },\n authorize: async (req, res) => { sendOAuth(res, await provider.authorize(toOAuthReq(req))) },\n callback: async (req, res) => { sendOAuth(res, await provider.callback(toOAuthReq(req))) },\n token: [\n express.urlencoded({ extended: false }),\n async (req, res) => { sendOAuth(res, await provider.token(toOAuthReq(req))) }\n ],\n register: [\n express.json(),\n async (req, res) => { sendOAuth(res, await provider.register(toOAuthReq(req))) }\n ]\n }\n}\n","import { type RequestHandler } from 'express'\nimport { readFile } from 'fs/promises'\nimport { type SideloadResource } from '../util/sideload.js'\n\nexport interface SideloadResourceOptions {\n /** Directory to read sideload resources from. Defaults to `resources/` (cwd-relative). */\n resourceDir?: string\n}\n\n/**\n * Handler for `GET /resource/:id` - serves a large MCP response that was\n * sideloaded to disk as a `{id}` payload with a `{id}.json` metadata sidecar.\n *\n * The route param `id` is provided by the host framework (Express, Nest, etc.).\n */\nexport function sideloadResource(options: SideloadResourceOptions = {}): RequestHandler {\n const { resourceDir = 'resources' } = options\n return async (req, res) => {\n const id = req.params['id']\n if (!id || typeof id !== 'string') { throw new Error('Invalid ID') }\n const resourceMeta: SideloadResource = JSON.parse(await readFile(`${resourceDir}/${id}.json`, 'utf-8'))\n const buffer = await readFile(`${resourceDir}/${id}`)\n res.status(200)\n res.header('Content-Type', resourceMeta.contentType)\n res.send(buffer)\n }\n}\n","import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { Action, ActionRun, isStreamingAction, runStreamingAction, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport { createLogger } from '@silkweave/logger'\nimport { capitalCase, pascalCase } from 'change-case'\nimport { randomUUID } from 'crypto'\nimport { type RequestHandler } from 'express'\nimport { handleToolError, jsonToolResult, smartToolResult } from '../util/result.js'\nimport { authStorage } from './auth.js'\n\n/**\n * Build the generic `request` context value (the same key REST/tRPC populate)\n * from the MCP SDK's `extra.requestInfo`, so transport-agnostic consumers - e.g.\n * `@silkweave/nestjs` `@UseGuards` guards reading\n * `switchToHttp().getRequest().headers` - work over MCP. There is no path\n * `params`/`query` on an MCP call, so those are empty stand-ins for graceful\n * degradation. Returns `undefined` when no HTTP request info is available.\n */\nfunction requestFromExtra(requestInfo: { headers?: unknown; url?: { toString(): string } } | undefined) {\n if (!requestInfo) { return undefined }\n return { headers: requestInfo.headers ?? {}, url: requestInfo.url?.toString(), params: {}, query: {} }\n}\n\nfunction registerTools(server: McpServer, actions: Action[], context: SilkweaveContext) {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: process.stderr,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: { progress, total, message, progressToken: extra._meta.progressToken }\n })\n }\n })\n const currentAuth = authStorage.getStore()\n const actionContext = context.fork({\n logger,\n extra,\n request: requestFromExtra(extra.requestInfo),\n ...(currentAuth ? { auth: currentAuth } : {})\n })\n // Client-sent `_meta.disposition` wins; otherwise fall back to the\n // action's configured default (`smart` when neither is set).\n const disposition = extra._meta?.disposition ?? action.disposition\n const progressToken = extra._meta?.progressToken\n try {\n let result: object | object[]\n if (isStreamingAction(action)) {\n result = await runStreamingAction(action, input, actionContext, progressToken\n ? async (chunk, index) => {\n await extra.sendNotification({\n method: 'notifications/progress',\n params: { progressToken, progress: index + 1, message: JSON.stringify(chunk) }\n })\n }\n : undefined)\n } else {\n result = await (action.run as ActionRun<object, object>)(input, actionContext)\n }\n if (action.toolResult) {\n const response = action.toolResult(result, actionContext)\n if (response) { return response }\n }\n return disposition === 'json' ? jsonToolResult(result) : smartToolResult(result)\n } catch (error) {\n return handleToolError(error)\n }\n })\n }\n}\n\nfunction createMcpServer(options: SilkweaveOptions, actions: Action[], context: SilkweaveContext): McpServer {\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n registerTools(server, actions, context)\n return server\n}\n\nfunction createSessionTransport(transports: Record<string, StreamableHTTPServerTransport>): StreamableHTTPServerTransport {\n const eventStore = new InMemoryEventStore()\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n enableJsonResponse: false,\n eventStore,\n onsessioninitialized: (sId) => {\n transports[sId] = transport\n }\n })\n transport.onerror = (error) => { console.error(error) }\n transport.onclose = () => {\n const sid = transport.sessionId\n if (sid && transports[sid]) { delete transports[sid] }\n }\n return transport\n}\n\nexport interface McpTransportHandlers {\n /** `POST /mcp` - initialize session or dispatch request to an existing one. */\n post: RequestHandler\n /** `GET /mcp` and `DELETE /mcp` - long-poll session stream / session termination. Also covers `GET /mcp/resource/:id`. */\n stream: RequestHandler\n}\n\n/**\n * Build the MCP Streamable HTTP transport route handlers.\n *\n * Sessions are kept in a per-call closure (one map per `mcpTransport()` call),\n * so the same handler object should be registered for all three transport\n * routes - `POST /mcp`, `GET /mcp`, `DELETE /mcp` - to share session state.\n */\nexport function mcpTransport(\n silkweaveOptions: SilkweaveOptions,\n context: SilkweaveContext,\n actions: Action[]\n): McpTransportHandlers {\n const transports: Record<string, StreamableHTTPServerTransport> = {}\n\n const post: RequestHandler = async (req, res) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n try {\n if (sessionId && transports[sessionId]) {\n await transports[sessionId].handleRequest(req, res, req.body)\n return\n }\n if (!isInitializeRequest(req.body)) {\n res.status(404).json({ jsonrpc: '2.0', error: { code: -32_000, message: 'Session not found' }, id: null })\n return\n }\n const transport = createSessionTransport(transports)\n await createMcpServer(silkweaveOptions, actions, context).connect(transport)\n await transport.handleRequest(req, res, req.body)\n } catch (error) {\n console.error('Error handling MCP request:', error)\n if (!res.headersSent) {\n res.status(500).json({ jsonrpc: '2.0', error: { code: -32_603, message: 'Internal server error' }, id: null })\n }\n }\n }\n\n const stream: RequestHandler = async (req, res) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n await transports[sessionId].handleRequest(req, res)\n }\n\n return { post, stream }\n}\n","import { createMcpExpressApp, type CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js'\nimport { AuthConfig } from '@silkweave/auth'\nimport { Action, AdapterFactory, createContext, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport { CorsOptions } from 'cors'\nimport express, { type Express } from 'express'\nimport { Server } from 'http'\nimport { authMiddleware } from '../handlers/auth.js'\nimport { mcpCors } from '../handlers/cors.js'\nimport { protectedResourceMetadata } from '../handlers/metadata.js'\nimport { oauthRoutes } from '../handlers/oauth.js'\nimport { sideloadResource } from '../handlers/sideload.js'\nimport { mcpTransport } from '../handlers/transport.js'\n\nexport interface StartMcpHttpOptions extends CreateMcpExpressAppOptions {\n host: string\n port: number\n auth?: AuthConfig\n /** CORS configuration. `false` to disable, omitted/`true` for permissive defaults, or a `CorsOptions` object. */\n cors?: CorsOptions | boolean\n /** Mount the `/resource/:id` sideload route. Default `true`. */\n sideloadResources?: boolean\n /** Directory the sideload route reads from. Default `'resources'`. */\n resourceDir?: string\n}\n\n/**\n * Build a fully-wired Express app that exposes the MCP Streamable HTTP\n * transport (plus OAuth / sideload / well-known routes when configured).\n *\n * Pass the resulting `app` to `app.listen(port, host)` yourself, or use the\n * top-level `startMcpServer()` / `http()` adapter conveniences.\n */\nexport function buildMcpExpressApp(\n silkweaveOptions: SilkweaveOptions,\n context: SilkweaveContext,\n actions: Action[],\n options: StartMcpHttpOptions\n): Express {\n const { host, auth, cors: corsConfig, sideloadResources = true, resourceDir, ...mcpAppOptions } = options\n const app = createMcpExpressApp({ ...mcpAppOptions, host })\n\n const corsHandler = mcpCors(corsConfig ?? true)\n if (corsHandler) { app.use(corsHandler) }\n\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n app.get('/.well-known/oauth-protected-resource', protectedResourceMetadata(auth))\n }\n\n let oauthPaths = new Set<string>()\n if (auth?.provider) {\n const oauth = oauthRoutes(auth)\n app.get('/.well-known/oauth-authorization-server', oauth.wellKnownAuthServer)\n app.get('/authorize', oauth.authorize)\n app.get(oauth.callbackPath, oauth.callback)\n app.post('/token', ...oauth.token)\n app.post('/register', ...oauth.register)\n oauthPaths = new Set(['/.well-known/oauth-authorization-server', '/authorize', oauth.callbackPath, '/token', '/register'])\n }\n\n if (auth) {\n const guard = authMiddleware(auth, context)\n app.use((req, res, next) => {\n if (req.path.startsWith('/.well-known/') || oauthPaths.has(req.path)) { return next() }\n return guard(req, res, next)\n })\n }\n\n if (sideloadResources) {\n app.get('/resource/:id', sideloadResource({ resourceDir }))\n }\n\n const transport = mcpTransport(silkweaveOptions, context, actions)\n app.post('/mcp', express.json(), transport.post)\n app.get('/mcp', transport.stream)\n app.delete('/mcp', transport.stream)\n app.get('/mcp/resource/:id', transport.stream)\n\n return app\n}\n\n/**\n * Spin up a standalone MCP Streamable HTTP server on `host:port` for the\n * given `actions`. Returns the underlying `Server` so callers can close it.\n *\n * Convenience for use cases that don't go through the `silkweave()` builder.\n */\nexport async function startMcpServer(\n silkweaveOptions: SilkweaveOptions,\n actions: Action[],\n options: StartMcpHttpOptions,\n context?: SilkweaveContext\n): Promise<Server> {\n const ctx = context ?? createContext({ adapter: 'http' })\n const app = buildMcpExpressApp(silkweaveOptions, ctx, actions, options)\n return new Promise<Server>((resolve, reject) => {\n const server = app.listen(options.port, options.host, (error) => {\n if (error) { reject(error); return }\n console.log(`MCP Streamable HTTP Server listening on http://${options.host}:${options.port}/mcp`)\n resolve(server)\n })\n })\n}\n\n/**\n * Silkweave adapter that owns its own HTTP server. Composes the MCP handler\n * primitives into a fully-wired Express app and listens on `host:port`.\n */\nexport const http: AdapterFactory<StartMcpHttpOptions> = (options) => {\n return (silkweaveOptions, baseContext) => {\n const context = baseContext.fork({ adapter: 'http' })\n let httpServer: Server | undefined\n return {\n context,\n start: async (actions) => {\n const app = buildMcpExpressApp(silkweaveOptions, context, actions, options)\n httpServer = await new Promise<Server>((resolve, reject) => {\n const s = app.listen(options.port, options.host, (error) => {\n if (error) { reject(error); return }\n console.log(`MCP Streamable HTTP Server listening on http://${options.host}:${options.port}/mcp`)\n resolve(s)\n })\n })\n },\n stop: async () => {\n if (!httpServer) { return }\n await new Promise<void>((resolve, reject) => {\n httpServer!.close((err) => err ? reject(err) : resolve())\n })\n httpServer = undefined\n }\n }\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Action, ActionRun, AdapterFactory, isStreamingAction, runStreamingAction, SilkweaveContext } from '@silkweave/core'\nimport { createLogger } from '@silkweave/logger'\nimport { capitalCase, pascalCase } from 'change-case'\nimport { handleToolError, smartToolResult } from '../util/result.js'\n\nfunction registerTools(server: McpServer, actions: Action[], context: SilkweaveContext) {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: false,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: { progress, total, message, progressToken: extra._meta.progressToken }\n })\n }\n })\n const actionContext = context.fork({ logger, extra })\n const progressToken = extra._meta?.progressToken\n try {\n let result: object | object[]\n if (isStreamingAction(action)) {\n result = await runStreamingAction(action, input, actionContext, progressToken\n ? async (chunk, index) => {\n await extra.sendNotification({\n method: 'notifications/progress',\n params: { progressToken, progress: index + 1, message: JSON.stringify(chunk) }\n })\n }\n : undefined)\n } else {\n result = await (action.run as ActionRun<object, object>)(input, actionContext)\n }\n return action.toolResult?.(result, actionContext) ?? smartToolResult(result)\n } catch (error) {\n return handleToolError(error)\n }\n })\n }\n}\n\nexport const stdio: AdapterFactory = () => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'stdio' })\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n return {\n context,\n start: async (actions) => {\n registerTools(server, actions, context)\n const transport = new StdioServerTransport()\n await server.connect(transport)\n },\n stop: async () => {\n await server?.close()\n }\n }\n }\n}\n","import { randomUUID } from 'crypto'\nimport { writeFile } from 'fs/promises'\n\nexport interface SideloadResource {\n id: string\n name: string\n contentType: string\n size: number\n}\n\nexport async function createSideloadResource(buffer: Buffer, { name, contentType }: Pick<SideloadResource, 'name' | 'contentType'>) {\n const id = randomUUID()\n const resource: SideloadResource = { id, name, contentType, size: buffer.length }\n await Promise.all([\n writeFile(`resources/${id}`, buffer),\n writeFile(`resources/${id}.json`, JSON.stringify(resource), 'utf-8')\n ])\n return resource\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["registerTools"],"sources":["../src/handlers/auth.ts","../src/handlers/cors.ts","../src/handlers/metadata.ts","../src/handlers/oauth.ts","../src/handlers/sideload.ts","../src/handlers/transport.ts","../src/adapter/http.ts","../src/adapter/stdio.ts","../src/util/sideload.ts"],"sourcesContent":["import { AuthConfig, AuthInfo, validateToken } from '@silkweave/auth'\nimport { SilkweaveContext } from '@silkweave/core'\nimport { type RequestHandler } from 'express'\nimport { AsyncLocalStorage } from 'node:async_hooks'\n\n/**\n * Per-request bearer-token storage used by tool handlers to read the resolved\n * `AuthInfo` for the currently-handled MCP call.\n */\nexport const authStorage = new AsyncLocalStorage<AuthInfo>()\n\n/**\n * Express middleware that validates the `Authorization: Bearer …` header via\n * the supplied `AuthConfig`. On success the resolved `AuthInfo` is placed in\n * `authStorage` for the duration of the downstream handler - `mcpTransport`'s\n * tool callbacks pick it up to populate the silkweave context's `auth` key.\n *\n * The middleware should NOT be applied to OAuth-discovery / token routes -\n * compose it only on the routes that require an authenticated caller (the MCP\n * transport itself, sideload, etc.).\n */\nexport function authMiddleware(auth: AuthConfig, context: SilkweaveContext): RequestHandler {\n return async (req, res, next) => {\n const result = await validateToken(req.headers.authorization, auth, context.fork({ request: req }))\n if (result.error) {\n for (const [key, value] of Object.entries(result.error.headers)) { res.header(key, value) }\n res.status(result.error.statusCode).json(result.error.body)\n return\n }\n if (result.auth) {\n authStorage.run(result.auth, () => { next() })\n } else {\n next()\n }\n }\n}\n","import cors, { CorsOptions } from 'cors'\nimport { type RequestHandler } from 'express'\n\n/** Headers required by the MCP protocol that must always be exposed when CORS is in use. */\nexport const MCP_REQUIRED_HEADERS = ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version']\n\n/**\n * CORS middleware preconfigured to expose the headers MCP clients need\n * (`Mcp-Session-Id`, `Last-Event-Id`, `Mcp-Protocol-Version`, `WWW-Authenticate`)\n * on top of any user-supplied options.\n *\n * Pass `false` to disable, omit / pass `true` for permissive defaults, or pass\n * a `CorsOptions` object to override.\n */\nexport function mcpCors(corsConfig: CorsOptions | boolean = true): RequestHandler | null {\n if (corsConfig === false) { return null }\n const userConfig = corsConfig === true ? {} : corsConfig\n const userExposed = userConfig.exposedHeaders\n const exposedHeaders = [\n ...MCP_REQUIRED_HEADERS,\n ...(Array.isArray(userExposed) ? userExposed : userExposed ? [userExposed] : [])\n ]\n return cors({ origin: '*', ...userConfig, exposedHeaders })\n}\n","import { AuthConfig, generateProtectedResourceMetadata } from '@silkweave/auth'\nimport { type RequestHandler } from 'express'\n\n/**\n * Handler for `GET /.well-known/oauth-protected-resource` (RFC 9728). Returns\n * the resource server's metadata pointing at the configured authorization\n * servers. Requires `auth.resourceUrl` and a non-empty `auth.authorizationServers`.\n */\nexport function protectedResourceMetadata(auth: AuthConfig): RequestHandler {\n if (!auth.resourceUrl || !auth.authorizationServers?.length) {\n throw new Error('@silkweave/mcp protectedResourceMetadata(): auth.resourceUrl and auth.authorizationServers are required')\n }\n const metadata = generateProtectedResourceMetadata(auth.resourceUrl, auth.authorizationServers)\n return (_req, res) => { res.json(metadata) }\n}\n","import { AuthConfig, OAuthRequest, OAuthResponse } from '@silkweave/auth'\nimport express, { type Request, type RequestHandler, type Response } from 'express'\n\nfunction toOAuthReq(req: Request): OAuthRequest {\n return {\n method: req.method,\n url: new URL(req.url, `${req.protocol}://${req.get('host')}`),\n headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])),\n body: req.body as Record<string, string> | undefined\n }\n}\n\nfunction sendOAuth(res: Response, oauthRes: OAuthResponse) {\n for (const [key, value] of Object.entries(oauthRes.headers)) { res.header(key, value) }\n if (oauthRes.body) {\n res.status(oauthRes.status).send(typeof oauthRes.body === 'string' ? oauthRes.body : JSON.stringify(oauthRes.body))\n } else {\n res.status(oauthRes.status).end()\n }\n}\n\nexport interface OAuthRouteHandlers {\n /** `GET /.well-known/oauth-authorization-server` - RFC 8414 discovery. */\n wellKnownAuthServer: RequestHandler\n /** `GET /authorize` - start the OAuth flow. */\n authorize: RequestHandler\n /** `GET {callbackPath}` - provider callback. */\n callback: RequestHandler\n /** Path the provider should redirect to (defaults to `/auth/callback`). */\n callbackPath: string\n /** `POST /token` - exchange code / refresh token. Includes urlencoded body parser. */\n token: RequestHandler[]\n /** `POST /register` - dynamic client registration. Includes JSON body parser. */\n register: RequestHandler[]\n}\n\n/**\n * Build the OAuth 2.1 proxy route handlers (authorize, callback, token,\n * register, well-known) backed by the configured `auth.provider`. Returns the\n * handlers as individual `RequestHandler`s so callers can register them\n * wherever they like - under `/mcp`, at the server root, etc.\n *\n * `token` and `register` are returned as middleware arrays because the\n * appropriate body parser must run before the handler. Apply with\n * `app.post(path, ...token)`.\n */\nexport function oauthRoutes(auth: AuthConfig): OAuthRouteHandlers {\n if (!auth.provider) { throw new Error('@silkweave/mcp oauthRoutes(): auth.provider is required') }\n const provider = auth.provider\n const callbackPath = auth.callbackPath ?? '/auth/callback'\n\n return {\n callbackPath,\n wellKnownAuthServer: (_req, res) => { sendOAuth(res, provider.metadata()) },\n authorize: async (req, res) => { sendOAuth(res, await provider.authorize(toOAuthReq(req))) },\n callback: async (req, res) => { sendOAuth(res, await provider.callback(toOAuthReq(req))) },\n token: [\n express.urlencoded({ extended: false }),\n async (req, res) => { sendOAuth(res, await provider.token(toOAuthReq(req))) }\n ],\n register: [\n express.json(),\n async (req, res) => { sendOAuth(res, await provider.register(toOAuthReq(req))) }\n ]\n }\n}\n","import { type RequestHandler } from 'express'\nimport { readFile } from 'fs/promises'\nimport { type SideloadResource } from '../util/sideload.js'\n\nexport interface SideloadResourceOptions {\n /** Directory to read sideload resources from. Defaults to `resources/` (cwd-relative). */\n resourceDir?: string\n}\n\n/**\n * Handler for `GET /resource/:id` - serves a large MCP response that was\n * sideloaded to disk as a `{id}` payload with a `{id}.json` metadata sidecar.\n *\n * The route param `id` is provided by the host framework (Express, Nest, etc.).\n */\nexport function sideloadResource(options: SideloadResourceOptions = {}): RequestHandler {\n const { resourceDir = 'resources' } = options\n return async (req, res) => {\n const id = req.params['id']\n if (!id || typeof id !== 'string') { throw new Error('Invalid ID') }\n const resourceMeta: SideloadResource = JSON.parse(await readFile(`${resourceDir}/${id}.json`, 'utf-8'))\n const buffer = await readFile(`${resourceDir}/${id}`)\n res.status(200)\n res.header('Content-Type', resourceMeta.contentType)\n res.send(buffer)\n }\n}\n","import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { Action, ActionRun, isStreamingAction, runStreamingAction, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport { createLogger } from '@silkweave/logger'\nimport { capitalCase, pascalCase } from 'change-case'\nimport { randomUUID } from 'crypto'\nimport { type RequestHandler } from 'express'\nimport { handleToolError, jsonToolResult, smartToolResult } from '../util/result.js'\nimport { authStorage } from './auth.js'\n\n/**\n * Build the generic `request` context value (the same key REST/tRPC populate)\n * from the MCP SDK's `extra.requestInfo`, so transport-agnostic consumers - e.g.\n * `@silkweave/nestjs` `@UseGuards` guards reading\n * `switchToHttp().getRequest().headers` - work over MCP. There is no path\n * `params`/`query` on an MCP call, so those are empty stand-ins for graceful\n * degradation. Returns `undefined` when no HTTP request info is available.\n */\nfunction requestFromExtra(requestInfo: { headers?: unknown; url?: { toString(): string } } | undefined) {\n if (!requestInfo) { return undefined }\n return { headers: requestInfo.headers ?? {}, url: requestInfo.url?.toString(), params: {}, query: {} }\n}\n\nfunction registerTools(server: McpServer, actions: Action[], context: SilkweaveContext) {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: process.stderr,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: { progress, total, message, progressToken: extra._meta.progressToken }\n })\n }\n })\n const currentAuth = authStorage.getStore()\n const actionContext = context.fork({\n logger,\n extra,\n request: requestFromExtra(extra.requestInfo),\n ...(currentAuth ? { auth: currentAuth } : {})\n })\n // Client-sent `_meta.disposition` wins; otherwise fall back to the\n // action's configured default (`smart` when neither is set).\n const disposition = extra._meta?.disposition ?? action.disposition\n const progressToken = extra._meta?.progressToken\n try {\n let result: object | object[]\n if (isStreamingAction(action)) {\n result = await runStreamingAction(action, input, actionContext, progressToken\n ? async (chunk, index) => {\n await extra.sendNotification({\n method: 'notifications/progress',\n params: { progressToken, progress: index + 1, message: JSON.stringify(chunk) }\n })\n }\n : undefined)\n } else {\n result = await (action.run as ActionRun<object, object>)(input, actionContext)\n }\n if (action.toolResult) {\n const response = action.toolResult(result, actionContext)\n if (response) { return response }\n }\n return disposition === 'json' ? jsonToolResult(result) : smartToolResult(result)\n } catch (error) {\n return handleToolError(error)\n }\n })\n }\n}\n\nfunction createMcpServer(options: SilkweaveOptions, actions: Action[], context: SilkweaveContext): McpServer {\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n registerTools(server, actions, context)\n return server\n}\n\nfunction createSessionTransport(transports: Record<string, StreamableHTTPServerTransport>): StreamableHTTPServerTransport {\n const eventStore = new InMemoryEventStore()\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n enableJsonResponse: false,\n eventStore,\n onsessioninitialized: (sId) => {\n transports[sId] = transport\n }\n })\n transport.onerror = (error) => { console.error(error) }\n transport.onclose = () => {\n const sid = transport.sessionId\n if (sid && transports[sid]) { delete transports[sid] }\n }\n return transport\n}\n\nexport interface McpTransportHandlers {\n /** `POST /mcp` - initialize session or dispatch request to an existing one. */\n post: RequestHandler\n /** `GET /mcp` and `DELETE /mcp` - long-poll session stream / session termination. Also covers `GET /mcp/resource/:id`. */\n stream: RequestHandler\n}\n\n/**\n * Build the MCP Streamable HTTP transport route handlers.\n *\n * Sessions are kept in a per-call closure (one map per `mcpTransport()` call),\n * so the same handler object should be registered for all three transport\n * routes - `POST /mcp`, `GET /mcp`, `DELETE /mcp` - to share session state.\n */\nexport function mcpTransport(\n silkweaveOptions: SilkweaveOptions,\n context: SilkweaveContext,\n actions: Action[]\n): McpTransportHandlers {\n const transports: Record<string, StreamableHTTPServerTransport> = {}\n\n const post: RequestHandler = async (req, res) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n try {\n if (sessionId && transports[sessionId]) {\n await transports[sessionId].handleRequest(req, res, req.body)\n return\n }\n if (!isInitializeRequest(req.body)) {\n res.status(404).json({ jsonrpc: '2.0', error: { code: -32_000, message: 'Session not found' }, id: null })\n return\n }\n const transport = createSessionTransport(transports)\n await createMcpServer(silkweaveOptions, actions, context).connect(transport)\n await transport.handleRequest(req, res, req.body)\n } catch (error) {\n console.error('Error handling MCP request:', error)\n if (!res.headersSent) {\n res.status(500).json({ jsonrpc: '2.0', error: { code: -32_603, message: 'Internal server error' }, id: null })\n }\n }\n }\n\n const stream: RequestHandler = async (req, res) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send('Invalid or missing session ID')\n return\n }\n await transports[sessionId].handleRequest(req, res)\n }\n\n return { post, stream }\n}\n","import { createMcpExpressApp, type CreateMcpExpressAppOptions } from '@modelcontextprotocol/sdk/server/express.js'\nimport { AuthConfig } from '@silkweave/auth'\nimport { Action, AdapterFactory, createContext, SilkweaveContext, SilkweaveOptions } from '@silkweave/core'\nimport { CorsOptions } from 'cors'\nimport express, { type Express } from 'express'\nimport { Server } from 'http'\nimport { authMiddleware } from '../handlers/auth.js'\nimport { mcpCors } from '../handlers/cors.js'\nimport { protectedResourceMetadata } from '../handlers/metadata.js'\nimport { oauthRoutes } from '../handlers/oauth.js'\nimport { sideloadResource } from '../handlers/sideload.js'\nimport { mcpTransport } from '../handlers/transport.js'\n\nexport interface StartMcpHttpOptions extends CreateMcpExpressAppOptions {\n host: string\n port: number\n auth?: AuthConfig\n /** CORS configuration. `false` to disable, omitted/`true` for permissive defaults, or a `CorsOptions` object. */\n cors?: CorsOptions | boolean\n /** Mount the `/resource/:id` sideload route. Default `true`. */\n sideloadResources?: boolean\n /** Directory the sideload route reads from. Default `'resources'`. */\n resourceDir?: string\n}\n\n/**\n * Build a fully-wired Express app that exposes the MCP Streamable HTTP\n * transport (plus OAuth / sideload / well-known routes when configured).\n *\n * Pass the resulting `app` to `app.listen(port, host)` yourself, or use the\n * top-level `startMcpServer()` / `http()` adapter conveniences.\n */\nexport function buildMcpExpressApp(\n silkweaveOptions: SilkweaveOptions,\n context: SilkweaveContext,\n actions: Action[],\n options: StartMcpHttpOptions\n): Express {\n const { host, auth, cors: corsConfig, sideloadResources = true, resourceDir, ...mcpAppOptions } = options\n const app = createMcpExpressApp({ ...mcpAppOptions, host })\n\n const corsHandler = mcpCors(corsConfig ?? true)\n if (corsHandler) { app.use(corsHandler) }\n\n if (auth?.authorizationServers?.length && auth.resourceUrl) {\n app.get('/.well-known/oauth-protected-resource', protectedResourceMetadata(auth))\n }\n\n let oauthPaths = new Set<string>()\n if (auth?.provider) {\n const oauth = oauthRoutes(auth)\n app.get('/.well-known/oauth-authorization-server', oauth.wellKnownAuthServer)\n app.get('/authorize', oauth.authorize)\n app.get(oauth.callbackPath, oauth.callback)\n app.post('/token', ...oauth.token)\n app.post('/register', ...oauth.register)\n oauthPaths = new Set(['/.well-known/oauth-authorization-server', '/authorize', oauth.callbackPath, '/token', '/register'])\n }\n\n if (auth) {\n const guard = authMiddleware(auth, context)\n app.use((req, res, next) => {\n if (req.path.startsWith('/.well-known/') || oauthPaths.has(req.path)) { return next() }\n return guard(req, res, next)\n })\n }\n\n if (sideloadResources) {\n app.get('/resource/:id', sideloadResource({ resourceDir }))\n }\n\n const transport = mcpTransport(silkweaveOptions, context, actions)\n app.post('/mcp', express.json(), transport.post)\n app.get('/mcp', transport.stream)\n app.delete('/mcp', transport.stream)\n app.get('/mcp/resource/:id', transport.stream)\n\n return app\n}\n\n/**\n * Spin up a standalone MCP Streamable HTTP server on `host:port` for the\n * given `actions`. Returns the underlying `Server` so callers can close it.\n *\n * Convenience for use cases that don't go through the `silkweave()` builder.\n */\nexport async function startMcpServer(\n silkweaveOptions: SilkweaveOptions,\n actions: Action[],\n options: StartMcpHttpOptions,\n context?: SilkweaveContext\n): Promise<Server> {\n const ctx = context ?? createContext({ adapter: 'http' })\n const app = buildMcpExpressApp(silkweaveOptions, ctx, actions, options)\n return new Promise<Server>((resolve, reject) => {\n const server = app.listen(options.port, options.host, (error) => {\n if (error) { reject(error); return }\n console.log(`MCP Streamable HTTP Server listening on http://${options.host}:${options.port}/mcp`)\n resolve(server)\n })\n })\n}\n\n/**\n * Silkweave adapter that owns its own HTTP server. Composes the MCP handler\n * primitives into a fully-wired Express app and listens on `host:port`.\n */\nexport const http: AdapterFactory<StartMcpHttpOptions> = (options) => {\n return (silkweaveOptions, baseContext) => {\n const context = baseContext.fork({ adapter: 'http' })\n let httpServer: Server | undefined\n return {\n context,\n start: async (actions) => {\n const app = buildMcpExpressApp(silkweaveOptions, context, actions, options)\n httpServer = await new Promise<Server>((resolve, reject) => {\n const s = app.listen(options.port, options.host, (error) => {\n if (error) { reject(error); return }\n console.log(`MCP Streamable HTTP Server listening on http://${options.host}:${options.port}/mcp`)\n resolve(s)\n })\n })\n },\n stop: async () => {\n if (!httpServer) { return }\n await new Promise<void>((resolve, reject) => {\n httpServer!.close((err) => err ? reject(err) : resolve())\n })\n httpServer = undefined\n }\n }\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Action, ActionRun, AdapterFactory, isStreamingAction, runStreamingAction, SilkweaveContext } from '@silkweave/core'\nimport { createLogger } from '@silkweave/logger'\nimport { capitalCase, pascalCase } from 'change-case'\nimport { handleToolError, smartToolResult } from '../util/result.js'\n\nfunction registerTools(server: McpServer, actions: Action[], context: SilkweaveContext) {\n for (const action of actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: false,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: { progress, total, message, progressToken: extra._meta.progressToken }\n })\n }\n })\n const actionContext = context.fork({ logger, extra })\n const progressToken = extra._meta?.progressToken\n try {\n let result: object | object[]\n if (isStreamingAction(action)) {\n result = await runStreamingAction(action, input, actionContext, progressToken\n ? async (chunk, index) => {\n await extra.sendNotification({\n method: 'notifications/progress',\n params: { progressToken, progress: index + 1, message: JSON.stringify(chunk) }\n })\n }\n : undefined)\n } else {\n result = await (action.run as ActionRun<object, object>)(input, actionContext)\n }\n return action.toolResult?.(result, actionContext) ?? smartToolResult(result)\n } catch (error) {\n return handleToolError(error)\n }\n })\n }\n}\n\nexport const stdio: AdapterFactory = () => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'stdio' })\n const server = new McpServer({\n name: options.name,\n description: options.description,\n version: options.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n return {\n context,\n start: async (actions) => {\n registerTools(server, actions, context)\n const transport = new StdioServerTransport()\n await server.connect(transport)\n },\n stop: async () => {\n await server?.close()\n }\n }\n }\n}\n","import { randomUUID } from 'crypto'\nimport { writeFile } from 'fs/promises'\n\nexport interface SideloadResource {\n id: string\n name: string\n contentType: string\n size: number\n}\n\nexport async function createSideloadResource(buffer: Buffer, { name, contentType }: Pick<SideloadResource, 'name' | 'contentType'>) {\n const id = randomUUID()\n const resource: SideloadResource = { id, name, contentType, size: buffer.length }\n await Promise.all([\n writeFile(`resources/${id}`, buffer),\n writeFile(`resources/${id}.json`, JSON.stringify(resource), 'utf-8')\n ])\n return resource\n}\n"],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { SilkweaveError } from "@silkweave/core";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/util/result.ts
4
+ function smartToolResult(data) {
5
+ const text = typeof data === "string" ? data : JSON.stringify(data);
6
+ const mimeType = typeof data === "string" ? "text/plain" : "application/json";
7
+ const ext = typeof data === "string" ? "txt" : "json";
8
+ if (text.length > 4096) {
9
+ const uri = `mcp://toolResult/${randomUUID()}.${ext}`;
10
+ const buffer = Buffer.from(text);
11
+ const blob = buffer.toString("base64");
12
+ return { content: [{
13
+ type: "text",
14
+ text: `Received resource ${uri} with ${buffer.byteLength} bytes`
15
+ }, {
16
+ type: "resource",
17
+ resource: {
18
+ uri,
19
+ mimeType,
20
+ blob
21
+ }
22
+ }] };
23
+ } else return { content: [{
24
+ type: "text",
25
+ text
26
+ }] };
27
+ }
28
+ function jsonToolResult(data, isError = false) {
29
+ const result = { content: [{
30
+ type: "text",
31
+ text: JSON.stringify(data)
32
+ }] };
33
+ if (isError) result.isError = true;
34
+ return result;
35
+ }
36
+ function errorToolResult({ code, name, message }) {
37
+ return {
38
+ isError: true,
39
+ content: [{
40
+ type: "text",
41
+ text: JSON.stringify({
42
+ success: false,
43
+ code,
44
+ name,
45
+ message
46
+ })
47
+ }]
48
+ };
49
+ }
50
+ function handleToolError(error) {
51
+ if (error instanceof SilkweaveError) return jsonToolResult({
52
+ success: false,
53
+ name: error.name,
54
+ message: error.message,
55
+ code: error.code
56
+ }, true);
57
+ else if (error instanceof Error) {
58
+ console.error(error);
59
+ return jsonToolResult({
60
+ success: false,
61
+ name: error.name,
62
+ message: error.message
63
+ }, true);
64
+ } else {
65
+ console.error("Unknown tool error:", error);
66
+ return jsonToolResult({
67
+ success: false,
68
+ name: "Unknown error",
69
+ message: "An unknown error occurred"
70
+ }, true);
71
+ }
72
+ }
73
+ function parseResourceMessage({ resource }) {
74
+ return "blob" in resource ? Buffer.from(resource.blob, "base64").toString("utf-8") : resource.text;
75
+ }
76
+ //#endregion
77
+ export { smartToolResult as a, parseResourceMessage as i, handleToolError as n, jsonToolResult as r, errorToolResult as t };
78
+
79
+ //# sourceMappingURL=result-BiFuFt5B.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-BiFuFt5B.mjs","names":[],"sources":["../src/util/result.ts"],"sourcesContent":["import { EmbeddedResource, type CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { SilkweaveError } from '@silkweave/core'\nimport { randomUUID } from 'node:crypto'\n\nexport function smartToolResult(data: string | object | object[]): CallToolResult {\n const text = typeof data === 'string' ? data : JSON.stringify(data)\n const mimeType = typeof data === 'string' ? 'text/plain' : 'application/json'\n const ext = typeof data === 'string' ? 'txt' : 'json'\n if (text.length > 4096) {\n const uri = `mcp://toolResult/${randomUUID()}.${ext}`\n const buffer = Buffer.from(text)\n const blob = buffer.toString('base64')\n return {\n content: [\n { type: 'text', text: `Received resource ${uri} with ${buffer.byteLength} bytes` },\n { type: 'resource', resource: { uri, mimeType, blob } }\n ]\n }\n } else {\n return {\n content: [{ type: 'text' as const, text }]\n }\n }\n}\n\nexport function jsonToolResult(data: object, isError = false): CallToolResult {\n const result: CallToolResult = { content: [{ type: 'text' as const, text: JSON.stringify(data) }] }\n if (isError) { result.isError = true }\n return result\n}\n\nexport function errorToolResult({ code, name, message }: SilkweaveError): CallToolResult {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: JSON.stringify({ success: false, code, name, message })\n }]\n }\n}\n\nexport function handleToolError(error: unknown): CallToolResult {\n if (error instanceof SilkweaveError) {\n return jsonToolResult({ success: false, name: error.name, message: error.message, code: error.code }, true)\n } else if (error instanceof Error) {\n // Log the full error (incl. stack) to stderr only - never put the stack trace\n // on the wire, where it would leak server internals to the MCP client.\n console.error(error)\n return jsonToolResult({ success: false, name: error.name, message: error.message }, true)\n } else {\n // Likewise keep the raw thrown value server-side - only a generic message goes out.\n console.error('Unknown tool error:', error)\n return jsonToolResult({ success: false, name: 'Unknown error', message: 'An unknown error occurred' }, true)\n }\n}\n\nexport function parseResourceMessage({ resource }: EmbeddedResource) {\n const text = ('blob' in resource) ? Buffer.from(resource.blob, 'base64').toString('utf-8') : resource.text\n return text\n}\n"],"mappings":";;;AAIA,SAAgB,gBAAgB,MAAkD;CAChF,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,KAAK;CACnE,MAAM,WAAW,OAAO,SAAS,WAAW,eAAe;CAC3D,MAAM,MAAM,OAAO,SAAS,WAAW,QAAQ;AAC/C,KAAI,KAAK,SAAS,MAAM;EACtB,MAAM,MAAM,oBAAoB,YAAY,CAAC,GAAG;EAChD,MAAM,SAAS,OAAO,KAAK,KAAK;EAChC,MAAM,OAAO,OAAO,SAAS,SAAS;AACtC,SAAO,EACL,SAAS,CACP;GAAE,MAAM;GAAQ,MAAM,qBAAqB,IAAI,QAAQ,OAAO,WAAW;GAAS,EAClF;GAAE,MAAM;GAAY,UAAU;IAAE;IAAK;IAAU;IAAM;GAAE,CACxD,EACF;OAED,QAAO,EACL,SAAS,CAAC;EAAE,MAAM;EAAiB;EAAM,CAAC,EAC3C;;AAIL,SAAgB,eAAe,MAAc,UAAU,OAAuB;CAC5E,MAAM,SAAyB,EAAE,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM,KAAK,UAAU,KAAK;EAAE,CAAC,EAAE;AACnG,KAAI,QAAW,QAAO,UAAU;AAChC,QAAO;;AAGT,SAAgB,gBAAgB,EAAE,MAAM,MAAM,WAA2C;AACvF,QAAO;EACL,SAAS;EACT,SAAS,CAAC;GACR,MAAM;GACN,MAAM,KAAK,UAAU;IAAE,SAAS;IAAO;IAAM;IAAM;IAAS,CAAC;GAC9D,CAAC;EACH;;AAGH,SAAgB,gBAAgB,OAAgC;AAC9D,KAAI,iBAAiB,eACnB,QAAO,eAAe;EAAE,SAAS;EAAO,MAAM,MAAM;EAAM,SAAS,MAAM;EAAS,MAAM,MAAM;EAAM,EAAE,KAAK;UAClG,iBAAiB,OAAO;AAGjC,UAAQ,MAAM,MAAM;AACpB,SAAO,eAAe;GAAE,SAAS;GAAO,MAAM,MAAM;GAAM,SAAS,MAAM;GAAS,EAAE,KAAK;QACpF;AAEL,UAAQ,MAAM,uBAAuB,MAAM;AAC3C,SAAO,eAAe;GAAE,SAAS;GAAO,MAAM;GAAiB,SAAS;GAA6B,EAAE,KAAK;;;AAIhH,SAAgB,qBAAqB,EAAE,YAA8B;AAEnE,QADc,UAAU,WAAY,OAAO,KAAK,SAAS,MAAM,SAAS,CAAC,SAAS,QAAQ,GAAG,SAAS"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silkweave/mcp",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Silkweave MCP Package",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.silkweave.dev",
@@ -23,23 +23,40 @@
23
23
  "@silkweave/source": "./src/index.ts",
24
24
  "types": "./build/index.d.mts",
25
25
  "default": "./build/index.mjs"
26
+ },
27
+ "./cli-proxy": {
28
+ "@silkweave/source": "./src/cliProxy.ts",
29
+ "types": "./build/cliProxy.d.mts",
30
+ "default": "./build/cliProxy.mjs"
26
31
  }
27
32
  },
28
33
  "dependencies": {
29
- "@clack/prompts": "^1.0.1",
30
34
  "@modelcontextprotocol/sdk": "^1.29.0",
31
35
  "change-case": "^5.4.4",
32
- "commander": "^13.1.0",
33
36
  "cors": "^2.8.6",
34
37
  "express": "^5.2.1",
35
38
  "zod": "^3.25.0",
36
- "@silkweave/auth": "2.6.0",
37
- "@silkweave/core": "2.6.0",
38
- "@silkweave/logger": "2.6.0"
39
+ "@silkweave/auth": "2.6.1",
40
+ "@silkweave/core": "2.6.1",
41
+ "@silkweave/logger": "2.6.1"
42
+ },
43
+ "peerDependencies": {
44
+ "@clack/prompts": "^1.0.1",
45
+ "commander": "^13.1.0"
46
+ },
47
+ "peerDependenciesMeta": {
48
+ "@clack/prompts": {
49
+ "optional": true
50
+ },
51
+ "commander": {
52
+ "optional": true
53
+ }
39
54
  },
40
55
  "devDependencies": {
56
+ "@clack/prompts": "^1.0.1",
41
57
  "@eslint/js": "^10.0.1",
42
58
  "@modelcontextprotocol/inspector": "^0.21.1",
59
+ "commander": "^13.1.0",
43
60
  "@stylistic/eslint-plugin": "^5.10.0",
44
61
  "@types/cors": "^2.8.19",
45
62
  "@types/express": "^5.0.6",