@fgv/ts-extras-mcp 5.1.0-34

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.
Files changed (107) hide show
  1. package/.rush/temp/5d207610a84e494acaefe7ed13447cda74ddf7da.tar.log +90 -0
  2. package/.rush/temp/chunked-rush-logs/ts-extras-mcp.build.chunks.jsonl +9 -0
  3. package/.rush/temp/operation/build/all.log +9 -0
  4. package/.rush/temp/operation/build/log-chunks.jsonl +9 -0
  5. package/.rush/temp/operation/build/state.json +3 -0
  6. package/.rush/temp/shrinkwrap-deps.json +734 -0
  7. package/CHANGELOG.json +4 -0
  8. package/README.md +133 -0
  9. package/config/api-extractor.json +38 -0
  10. package/config/jest.config.json +13 -0
  11. package/config/rig.json +6 -0
  12. package/dist/index.js +49 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/packlets/mcp/adapter.js +122 -0
  15. package/dist/packlets/mcp/adapter.js.map +1 -0
  16. package/dist/packlets/mcp/index.js +33 -0
  17. package/dist/packlets/mcp/index.js.map +1 -0
  18. package/dist/packlets/mcp/model.js +23 -0
  19. package/dist/packlets/mcp/model.js.map +1 -0
  20. package/dist/packlets/mcp/operations.js +119 -0
  21. package/dist/packlets/mcp/operations.js.map +1 -0
  22. package/dist/packlets/mcp/sdk.js +67 -0
  23. package/dist/packlets/mcp/sdk.js.map +1 -0
  24. package/dist/packlets/mcp/session.js +109 -0
  25. package/dist/packlets/mcp/session.js.map +1 -0
  26. package/dist/packlets/mcp/transports.js +96 -0
  27. package/dist/packlets/mcp/transports.js.map +1 -0
  28. package/dist/test/unit/endToEnd.test.js +220 -0
  29. package/dist/test/unit/endToEnd.test.js.map +1 -0
  30. package/dist/test/unit/index.test.js +41 -0
  31. package/dist/test/unit/index.test.js.map +1 -0
  32. package/dist/test/unit/mcp.test.js +381 -0
  33. package/dist/test/unit/mcp.test.js.map +1 -0
  34. package/dist/test/unit/sdk.test.js +68 -0
  35. package/dist/test/unit/sdk.test.js.map +1 -0
  36. package/dist/ts-extras-mcp.d.ts +290 -0
  37. package/dist/tsdoc-metadata.json +11 -0
  38. package/eslint.config.js +15 -0
  39. package/etc/ts-extras-mcp.api.md +104 -0
  40. package/lib/index.d.ts +28 -0
  41. package/lib/index.d.ts.map +1 -0
  42. package/lib/index.js +65 -0
  43. package/lib/index.js.map +1 -0
  44. package/lib/packlets/mcp/adapter.d.ts +33 -0
  45. package/lib/packlets/mcp/adapter.d.ts.map +1 -0
  46. package/lib/packlets/mcp/adapter.js +125 -0
  47. package/lib/packlets/mcp/adapter.js.map +1 -0
  48. package/lib/packlets/mcp/index.d.ts +10 -0
  49. package/lib/packlets/mcp/index.d.ts.map +1 -0
  50. package/lib/packlets/mcp/index.js +57 -0
  51. package/lib/packlets/mcp/index.js.map +1 -0
  52. package/lib/packlets/mcp/model.d.ts +155 -0
  53. package/lib/packlets/mcp/model.d.ts.map +1 -0
  54. package/lib/packlets/mcp/model.js +24 -0
  55. package/lib/packlets/mcp/model.js.map +1 -0
  56. package/lib/packlets/mcp/operations.d.ts +36 -0
  57. package/lib/packlets/mcp/operations.d.ts.map +1 -0
  58. package/lib/packlets/mcp/operations.js +123 -0
  59. package/lib/packlets/mcp/operations.js.map +1 -0
  60. package/lib/packlets/mcp/sdk.d.ts +91 -0
  61. package/lib/packlets/mcp/sdk.d.ts.map +1 -0
  62. package/lib/packlets/mcp/sdk.js +72 -0
  63. package/lib/packlets/mcp/sdk.js.map +1 -0
  64. package/lib/packlets/mcp/session.d.ts +43 -0
  65. package/lib/packlets/mcp/session.d.ts.map +1 -0
  66. package/lib/packlets/mcp/session.js +115 -0
  67. package/lib/packlets/mcp/session.js.map +1 -0
  68. package/lib/packlets/mcp/transports.d.ts +49 -0
  69. package/lib/packlets/mcp/transports.d.ts.map +1 -0
  70. package/lib/packlets/mcp/transports.js +102 -0
  71. package/lib/packlets/mcp/transports.js.map +1 -0
  72. package/lib/test/unit/endToEnd.test.d.ts +13 -0
  73. package/lib/test/unit/endToEnd.test.d.ts.map +1 -0
  74. package/lib/test/unit/endToEnd.test.js +222 -0
  75. package/lib/test/unit/endToEnd.test.js.map +1 -0
  76. package/lib/test/unit/index.test.d.ts +2 -0
  77. package/lib/test/unit/index.test.d.ts.map +1 -0
  78. package/lib/test/unit/index.test.js +76 -0
  79. package/lib/test/unit/index.test.js.map +1 -0
  80. package/lib/test/unit/mcp.test.d.ts +2 -0
  81. package/lib/test/unit/mcp.test.d.ts.map +1 -0
  82. package/lib/test/unit/mcp.test.js +416 -0
  83. package/lib/test/unit/mcp.test.js.map +1 -0
  84. package/lib/test/unit/sdk.test.d.ts +2 -0
  85. package/lib/test/unit/sdk.test.d.ts.map +1 -0
  86. package/lib/test/unit/sdk.test.js +70 -0
  87. package/lib/test/unit/sdk.test.js.map +1 -0
  88. package/package.json +86 -0
  89. package/rush-logs/ts-extras-mcp.build.cache.log +3 -0
  90. package/rush-logs/ts-extras-mcp.build.log +9 -0
  91. package/src/index.ts +50 -0
  92. package/src/packlets/mcp/adapter.ts +152 -0
  93. package/src/packlets/mcp/index.ts +34 -0
  94. package/src/packlets/mcp/model.ts +204 -0
  95. package/src/packlets/mcp/operations.ts +138 -0
  96. package/src/packlets/mcp/sdk.ts +148 -0
  97. package/src/packlets/mcp/session.ts +137 -0
  98. package/src/packlets/mcp/transports.ts +111 -0
  99. package/src/test/unit/endToEnd.test.ts +254 -0
  100. package/src/test/unit/index.test.ts +43 -0
  101. package/src/test/unit/mcp.test.ts +473 -0
  102. package/src/test/unit/sdk.test.ts +73 -0
  103. package/temp/build/lint/_eslint-5eVG3S6w.json +54 -0
  104. package/temp/build/typescript/ts_8nwakTlr.json +1 -0
  105. package/temp/ts-extras-mcp.api.json +1662 -0
  106. package/temp/ts-extras-mcp.api.md +104 -0
  107. package/tsconfig.json +12 -0
@@ -0,0 +1,290 @@
1
+ /**
2
+ * `@fgv/ts-extras-mcp` — a Result-integration boundary over `@modelcontextprotocol/sdk` that
3
+ * connects to MCP (Model Context Protocol) servers, discovers their tools, and adapts each into
4
+ * an `AiAssist.IAiClientTool` so it drops directly into `AiAssist.executeClientToolTurn` —
5
+ * making any MCP server's tools callable across all four cloud providers with no per-provider work.
6
+ *
7
+ * Mirrors the discipline of `@fgv/ts-extras-webauthn` / `@fgv/ts-extras-transformers`: thin
8
+ * `Result<T>` conversion over a well-maintained upstream SDK, with no opinionated orchestration
9
+ * above the boundary.
10
+ *
11
+ * **In scope (slice 1, Node):** transport factories (`createStdioTransport`,
12
+ * `createHttpTransport`), session lifecycle (`connectMcpSession`, `closeMcpSession`), tool
13
+ * discovery + invocation (`listMcpTools`, `callMcpTool`), and the headline adapter
14
+ * (`adaptMcpTools`) which gracefully degrades on tools whose `inputSchema` is outside the
15
+ * supported JSON Schema subset (surfacing them on `skipped` and warning NOISILY).
16
+ *
17
+ * **Explicitly NOT in scope (deferred — see README / docs/FUTURE.md):**
18
+ * - Browser sibling `@fgv/ts-web-extras-mcp`
19
+ * - MCP resources / prompts / sampling features
20
+ * - OAuth / managed auth (static headers only at v0.1)
21
+ * - Multimodal tool-result passthrough (text-block projection only)
22
+ * - Cross-server tool-name namespacing (duplicate names already fail loudly in
23
+ * `executeClientToolTurn`)
24
+ *
25
+ * @packageDocumentation
26
+ */
27
+
28
+ import { AiAssist } from '@fgv/ts-extras';
29
+ import { JsonObject } from '@fgv/ts-json-base';
30
+ import { JsonValue } from '@fgv/ts-json-base';
31
+ import { Logging } from '@fgv/ts-utils';
32
+ import { Result } from '@fgv/ts-utils';
33
+
34
+ /**
35
+ * Discovers an MCP server's tools and adapts each into an `AiAssist.IAiClientTool` that drops
36
+ * directly into `AiAssist.executeClientToolTurn`.
37
+ *
38
+ * @remarks
39
+ * **Constraint 1 — graceful degradation with NOISY warnings.** A tool whose `inputSchema` is
40
+ * outside the JSON Schema subset supported by `JsonSchema.fromJson` is NOT adapted (the model
41
+ * must never be offered a tool whose args we can't validate). Instead it is:
42
+ * 1. excluded from {@link IAdaptMcpToolsResult.tools};
43
+ * 2. surfaced structurally on {@link IAdaptMcpToolsResult.skipped} with the tool name, the
44
+ * JSON-pointer reason, and the raw failing schema; and
45
+ * 3. logged as a NOISY `warning` (name + reason + raw schema) when an `options.logger` is
46
+ * supplied — so pointing this at a new server immediately reveals every subset feature to
47
+ * extend, with the schema in hand.
48
+ *
49
+ * The whole catalog never fails on a single bad schema; the only failure mode is an upstream
50
+ * `listMcpTools` error.
51
+ *
52
+ * @param session - A connected session from `connectMcpSession`.
53
+ * @param options - Optional logger for the NOISY skip warnings.
54
+ * @returns `Success` with `{ tools, skipped }`, or `Failure` only if tool discovery fails.
55
+ * @public
56
+ */
57
+ export declare function adaptMcpTools(session: IMcpSession, options?: IAdaptMcpToolsOptions): Promise<Result<IAdaptMcpToolsResult>>;
58
+
59
+ /**
60
+ * Calls a named tool on a connected MCP server.
61
+ *
62
+ * @remarks
63
+ * The SDK `CallToolResult` is projected to {@link IMcpToolCallResult} (text-block concatenation;
64
+ * non-text blocks summarized). A result flagged `isError: true` is mapped to `Result.fail` with
65
+ * the projected content — it is never swallowed, so `executeClientToolTurn` routes it back to the
66
+ * model as a provider-native error tool-result.
67
+ *
68
+ * @param session - A session from `connectMcpSession`.
69
+ * @param name - The tool name to invoke.
70
+ * @param args - The tool arguments (a JSON object).
71
+ * @returns `Success` with the projected content, or `Failure` on tool error / transport error /
72
+ * foreign handle.
73
+ * @public
74
+ */
75
+ export declare function callMcpTool(session: IMcpSession, name: string, args: JsonObject): Promise<Result<IMcpToolCallResult>>;
76
+
77
+ /**
78
+ * Closes an MCP session, tearing down the transport (and any spawned subprocess).
79
+ *
80
+ * @param session - A session from {@link connectMcpSession}.
81
+ * @returns `Success(true)`, or `Failure` if the handle is foreign or the close call throws.
82
+ * @public
83
+ */
84
+ export declare function closeMcpSession(session: IMcpSession): Promise<Result<true>>;
85
+
86
+ /**
87
+ * Connects to an MCP server over the given transport and performs the initialize handshake.
88
+ *
89
+ * @param params - Transport plus optional client identity and logger.
90
+ * @returns `Success` with an opaque {@link IMcpSession}, or `Failure` if the transport handle is
91
+ * foreign or the connection/handshake fails.
92
+ * @public
93
+ */
94
+ export declare function connectMcpSession(params: IConnectMcpSessionParams): Promise<Result<IMcpSession>>;
95
+
96
+ /**
97
+ * Creates a Streamable-HTTP MCP transport for the given endpoint URL.
98
+ *
99
+ * @param params - The endpoint URL and optional static headers.
100
+ * @returns `Success` with an opaque transport handle, or `Failure` if the URL is invalid or the
101
+ * SDK constructor throws.
102
+ * @public
103
+ */
104
+ export declare function createHttpTransport(params: IMcpHttpTransportParams): Result<IMcpTransport>;
105
+
106
+ /**
107
+ * Creates a stdio MCP transport that speaks MCP over the stdin/stdout of a spawned subprocess.
108
+ *
109
+ * @remarks
110
+ * **Security — trust boundary.** The transport spawns `params.command` (with `params.args`) as a
111
+ * child process. Never source the command or arguments from untrusted input; treat them with the
112
+ * same care as any shell-out. See the package README's security note.
113
+ *
114
+ * @param params - The command, arguments, environment, and working directory.
115
+ * @returns `Success` with an opaque transport handle, or `Failure` if the SDK constructor throws
116
+ * (e.g. an empty command).
117
+ * @public
118
+ */
119
+ export declare function createStdioTransport(params: IMcpStdioTransportParams): Result<IMcpTransport>;
120
+
121
+ /**
122
+ * Options for {@link adaptMcpTools}.
123
+ * @public
124
+ */
125
+ export declare interface IAdaptMcpToolsOptions {
126
+ /**
127
+ * Logger for the NOISY per-tool skip warnings. When a tool is skipped, a `warning` is emitted
128
+ * including the tool name, the JSON-pointer reason, and the raw failing schema. When omitted,
129
+ * skips are still surfaced structurally on {@link IAdaptMcpToolsResult.skipped}.
130
+ */
131
+ readonly logger?: Logging.ILogger;
132
+ }
133
+
134
+ /**
135
+ * The result of {@link adaptMcpTools}: cleanly-adapted client tools plus the structurally-surfaced
136
+ * set of tools that could not be adapted (graceful degradation, Constraint 1).
137
+ * @public
138
+ */
139
+ export declare interface IAdaptMcpToolsResult {
140
+ /** Tools adapted into `IAiClientTool` — safe to hand to `AiAssist.executeClientToolTurn`. */
141
+ readonly tools: ReadonlyArray<AiAssist.IAiClientTool>;
142
+ /** Tools excluded because their `inputSchema` is outside the supported JSON Schema subset. */
143
+ readonly skipped: ReadonlyArray<IMcpSkippedTool>;
144
+ }
145
+
146
+ /**
147
+ * Parameters for {@link connectMcpSession}.
148
+ * @public
149
+ */
150
+ export declare interface IConnectMcpSessionParams {
151
+ /** A transport produced by {@link createStdioTransport} / {@link createHttpTransport}. */
152
+ readonly transport: IMcpTransport;
153
+ /** Client name advertised to the server during the initialize handshake. Default `'@fgv/ts-extras-mcp'`. */
154
+ readonly clientName?: string;
155
+ /** Client version advertised to the server. Default the package version. */
156
+ readonly clientVersion?: string;
157
+ /** Optional logger for connection diagnostics. */
158
+ readonly logger?: Logging.ILogger;
159
+ }
160
+
161
+ /**
162
+ * Parameters for {@link createHttpTransport}. The transport connects to a Streamable-HTTP MCP
163
+ * endpoint.
164
+ * @public
165
+ */
166
+ export declare interface IMcpHttpTransportParams {
167
+ /** Absolute `http`/`https` URL of the MCP server endpoint. */
168
+ readonly url: string;
169
+ /** Optional static headers (e.g. an `Authorization` bearer token). OAuth/managed auth is out of scope at v0.1. */
170
+ readonly headers?: Record<string, string>;
171
+ }
172
+
173
+ /**
174
+ * Server identity reported during the MCP initialize handshake.
175
+ * @public
176
+ */
177
+ export declare interface IMcpServerInfo {
178
+ /** Server-advertised name. */
179
+ readonly name: string;
180
+ /** Server-advertised version. */
181
+ readonly version: string;
182
+ }
183
+
184
+ /**
185
+ * Opaque handle to a connected MCP session. Pass it to {@link listMcpTools},
186
+ * {@link callMcpTool}, {@link adaptMcpTools}, and {@link closeMcpSession}.
187
+ * @public
188
+ */
189
+ export declare interface IMcpSession {
190
+ /** Client name advertised during the handshake. */
191
+ readonly clientName: string;
192
+ /** Client version advertised during the handshake. */
193
+ readonly clientVersion: string;
194
+ /** Server identity reported by the handshake, when the server provided one. */
195
+ readonly serverInfo: IMcpServerInfo | undefined;
196
+ }
197
+
198
+ /**
199
+ * A tool that was discovered but could NOT be adapted into an `AiAssist.IAiClientTool`,
200
+ * because its `inputSchema` is outside the JSON Schema subset supported by
201
+ * `JsonSchema.fromJson`. Surfaced structurally so callers/the probe can enumerate exactly which
202
+ * subset features a server needs (with the raw schema in hand to extend `fromJson` later).
203
+ * @public
204
+ */
205
+ export declare interface IMcpSkippedTool {
206
+ /** The tool's name. */
207
+ readonly name: string;
208
+ /** Why the tool was skipped — the JSON-pointer reason from `JsonSchema.fromJson`, or a structural reason. */
209
+ readonly reason: string;
210
+ /** The raw failing input schema, verbatim, in hand for additively widening `JsonSchema.fromJson`. */
211
+ readonly schema: JsonValue;
212
+ }
213
+
214
+ /**
215
+ * Parameters for {@link createStdioTransport}. The transport spawns `command` as a
216
+ * subprocess and speaks MCP over its stdin/stdout.
217
+ *
218
+ * @remarks
219
+ * **Security:** stdio transport executes a consumer-supplied command. Treat `command`/`args`
220
+ * as a trust boundary — never source them from untrusted input. See the package README.
221
+ *
222
+ * @public
223
+ */
224
+ export declare interface IMcpStdioTransportParams {
225
+ /** Executable to spawn (e.g. `'npx'`, `'node'`, an absolute path). */
226
+ readonly command: string;
227
+ /** Arguments passed to the command. */
228
+ readonly args?: ReadonlyArray<string>;
229
+ /** Environment variables for the spawned process. When omitted, the SDK's safe default set is used. */
230
+ readonly env?: Record<string, string>;
231
+ /** Working directory for the spawned process. */
232
+ readonly cwd?: string;
233
+ }
234
+
235
+ /**
236
+ * Successful projection of an MCP `CallToolResult` produced by {@link callMcpTool}.
237
+ *
238
+ * @remarks
239
+ * `content` is the text concatenation of the result's `text` blocks; non-text blocks
240
+ * (image / audio / resource) are projected to a one-line `[<type> block]` summary
241
+ * (multimodal passthrough is out of scope at v0.1). A result with `isError: true` is mapped
242
+ * to `Result.fail(content)` rather than returned here, so it is never silently swallowed.
243
+ *
244
+ * @public
245
+ */
246
+ export declare interface IMcpToolCallResult {
247
+ /** The projected text content of the tool result. */
248
+ readonly content: string;
249
+ }
250
+
251
+ /**
252
+ * A tool descriptor discovered from an MCP server via {@link listMcpTools}.
253
+ * @public
254
+ */
255
+ export declare interface IMcpToolDescriptor {
256
+ /** Tool name (unique within a server). */
257
+ readonly name: string;
258
+ /** Human-readable description, when the server provided one. */
259
+ readonly description: string | undefined;
260
+ /**
261
+ * The tool's declared input schema as raw JSON. Per the MCP spec this is normally a JSON
262
+ * Schema object; carried verbatim so {@link adaptMcpTools} can run it through
263
+ * `JsonSchema.fromJson` (and surface it on {@link IMcpSkippedTool} when it is outside the
264
+ * supported subset).
265
+ */
266
+ readonly inputSchema: JsonValue;
267
+ }
268
+
269
+ /**
270
+ * Opaque handle to an MCP transport produced by {@link createStdioTransport} or
271
+ * {@link createHttpTransport}. Hand it to {@link connectMcpSession}; do not construct directly.
272
+ * @public
273
+ */
274
+ export declare interface IMcpTransport {
275
+ /** Which transport kind this handle wraps. */
276
+ readonly transportKind: 'stdio' | 'http';
277
+ }
278
+
279
+ /**
280
+ * Lists every tool a connected MCP server advertises, following the SDK's `nextCursor`
281
+ * pagination until the full catalog is accumulated.
282
+ *
283
+ * @param session - A session from `connectMcpSession`.
284
+ * @returns `Success` with the full tool catalog, or `Failure` on a foreign handle or a
285
+ * transport/protocol error.
286
+ * @public
287
+ */
288
+ export declare function listMcpTools(session: IMcpSession): Promise<Result<ReadonlyArray<IMcpToolDescriptor>>>;
289
+
290
+ export { }
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.58.7"
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,15 @@
1
+ // ESLint 9 flat config
2
+ const nodeProfile = require('@rushstack/eslint-config/flat/profile/node');
3
+ const packletsPlugin = require('@rushstack/eslint-config/flat/mixins/packlets');
4
+ const tsdocPlugin = require('@rushstack/eslint-config/flat/mixins/tsdoc');
5
+
6
+ module.exports = [
7
+ ...nodeProfile,
8
+ packletsPlugin,
9
+ ...tsdocPlugin,
10
+ {
11
+ rules: {
12
+ '@rushstack/packlets/mechanics': 'warn'
13
+ }
14
+ }
15
+ ];
@@ -0,0 +1,104 @@
1
+ ## API Report File for "@fgv/ts-extras-mcp"
2
+
3
+ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4
+
5
+ ```ts
6
+
7
+ import { AiAssist } from '@fgv/ts-extras';
8
+ import { JsonObject } from '@fgv/ts-json-base';
9
+ import { JsonValue } from '@fgv/ts-json-base';
10
+ import { Logging } from '@fgv/ts-utils';
11
+ import { Result } from '@fgv/ts-utils';
12
+
13
+ // @public
14
+ export function adaptMcpTools(session: IMcpSession, options?: IAdaptMcpToolsOptions): Promise<Result<IAdaptMcpToolsResult>>;
15
+
16
+ // @public
17
+ export function callMcpTool(session: IMcpSession, name: string, args: JsonObject): Promise<Result<IMcpToolCallResult>>;
18
+
19
+ // @public
20
+ export function closeMcpSession(session: IMcpSession): Promise<Result<true>>;
21
+
22
+ // @public
23
+ export function connectMcpSession(params: IConnectMcpSessionParams): Promise<Result<IMcpSession>>;
24
+
25
+ // @public
26
+ export function createHttpTransport(params: IMcpHttpTransportParams): Result<IMcpTransport>;
27
+
28
+ // @public
29
+ export function createStdioTransport(params: IMcpStdioTransportParams): Result<IMcpTransport>;
30
+
31
+ // @public
32
+ export interface IAdaptMcpToolsOptions {
33
+ readonly logger?: Logging.ILogger;
34
+ }
35
+
36
+ // @public
37
+ export interface IAdaptMcpToolsResult {
38
+ readonly skipped: ReadonlyArray<IMcpSkippedTool>;
39
+ readonly tools: ReadonlyArray<AiAssist.IAiClientTool>;
40
+ }
41
+
42
+ // @public
43
+ export interface IConnectMcpSessionParams {
44
+ readonly clientName?: string;
45
+ readonly clientVersion?: string;
46
+ readonly logger?: Logging.ILogger;
47
+ readonly transport: IMcpTransport;
48
+ }
49
+
50
+ // @public
51
+ export interface IMcpHttpTransportParams {
52
+ readonly headers?: Record<string, string>;
53
+ readonly url: string;
54
+ }
55
+
56
+ // @public
57
+ export interface IMcpServerInfo {
58
+ readonly name: string;
59
+ readonly version: string;
60
+ }
61
+
62
+ // @public
63
+ export interface IMcpSession {
64
+ readonly clientName: string;
65
+ readonly clientVersion: string;
66
+ readonly serverInfo: IMcpServerInfo | undefined;
67
+ }
68
+
69
+ // @public
70
+ export interface IMcpSkippedTool {
71
+ readonly name: string;
72
+ readonly reason: string;
73
+ readonly schema: JsonValue;
74
+ }
75
+
76
+ // @public
77
+ export interface IMcpStdioTransportParams {
78
+ readonly args?: ReadonlyArray<string>;
79
+ readonly command: string;
80
+ readonly cwd?: string;
81
+ readonly env?: Record<string, string>;
82
+ }
83
+
84
+ // @public
85
+ export interface IMcpToolCallResult {
86
+ readonly content: string;
87
+ }
88
+
89
+ // @public
90
+ export interface IMcpToolDescriptor {
91
+ readonly description: string | undefined;
92
+ readonly inputSchema: JsonValue;
93
+ readonly name: string;
94
+ }
95
+
96
+ // @public
97
+ export interface IMcpTransport {
98
+ readonly transportKind: 'stdio' | 'http';
99
+ }
100
+
101
+ // @public
102
+ export function listMcpTools(session: IMcpSession): Promise<Result<ReadonlyArray<IMcpToolDescriptor>>>;
103
+
104
+ ```
package/lib/index.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@fgv/ts-extras-mcp` — a Result-integration boundary over `@modelcontextprotocol/sdk` that
3
+ * connects to MCP (Model Context Protocol) servers, discovers their tools, and adapts each into
4
+ * an `AiAssist.IAiClientTool` so it drops directly into `AiAssist.executeClientToolTurn` —
5
+ * making any MCP server's tools callable across all four cloud providers with no per-provider work.
6
+ *
7
+ * Mirrors the discipline of `@fgv/ts-extras-webauthn` / `@fgv/ts-extras-transformers`: thin
8
+ * `Result<T>` conversion over a well-maintained upstream SDK, with no opinionated orchestration
9
+ * above the boundary.
10
+ *
11
+ * **In scope (slice 1, Node):** transport factories (`createStdioTransport`,
12
+ * `createHttpTransport`), session lifecycle (`connectMcpSession`, `closeMcpSession`), tool
13
+ * discovery + invocation (`listMcpTools`, `callMcpTool`), and the headline adapter
14
+ * (`adaptMcpTools`) which gracefully degrades on tools whose `inputSchema` is outside the
15
+ * supported JSON Schema subset (surfacing them on `skipped` and warning NOISILY).
16
+ *
17
+ * **Explicitly NOT in scope (deferred — see README / docs/FUTURE.md):**
18
+ * - Browser sibling `@fgv/ts-web-extras-mcp`
19
+ * - MCP resources / prompts / sampling features
20
+ * - OAuth / managed auth (static headers only at v0.1)
21
+ * - Multimodal tool-result passthrough (text-block projection only)
22
+ * - Cross-server tool-name namespacing (duplicate names already fail loudly in
23
+ * `executeClientToolTurn`)
24
+ *
25
+ * @packageDocumentation
26
+ */
27
+ export * from './packlets/mcp';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,cAAc,gBAAgB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
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.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
35
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ /**
39
+ * `@fgv/ts-extras-mcp` — a Result-integration boundary over `@modelcontextprotocol/sdk` that
40
+ * connects to MCP (Model Context Protocol) servers, discovers their tools, and adapts each into
41
+ * an `AiAssist.IAiClientTool` so it drops directly into `AiAssist.executeClientToolTurn` —
42
+ * making any MCP server's tools callable across all four cloud providers with no per-provider work.
43
+ *
44
+ * Mirrors the discipline of `@fgv/ts-extras-webauthn` / `@fgv/ts-extras-transformers`: thin
45
+ * `Result<T>` conversion over a well-maintained upstream SDK, with no opinionated orchestration
46
+ * above the boundary.
47
+ *
48
+ * **In scope (slice 1, Node):** transport factories (`createStdioTransport`,
49
+ * `createHttpTransport`), session lifecycle (`connectMcpSession`, `closeMcpSession`), tool
50
+ * discovery + invocation (`listMcpTools`, `callMcpTool`), and the headline adapter
51
+ * (`adaptMcpTools`) which gracefully degrades on tools whose `inputSchema` is outside the
52
+ * supported JSON Schema subset (surfacing them on `skipped` and warning NOISILY).
53
+ *
54
+ * **Explicitly NOT in scope (deferred — see README / docs/FUTURE.md):**
55
+ * - Browser sibling `@fgv/ts-web-extras-mcp`
56
+ * - MCP resources / prompts / sampling features
57
+ * - OAuth / managed auth (static headers only at v0.1)
58
+ * - Multimodal tool-result passthrough (text-block projection only)
59
+ * - Cross-server tool-name namespacing (duplicate names already fail loudly in
60
+ * `executeClientToolTurn`)
61
+ *
62
+ * @packageDocumentation
63
+ */
64
+ __exportStar(require("./packlets/mcp"), exports);
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,iDAA+B","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/**\n * `@fgv/ts-extras-mcp` — a Result-integration boundary over `@modelcontextprotocol/sdk` that\n * connects to MCP (Model Context Protocol) servers, discovers their tools, and adapts each into\n * an `AiAssist.IAiClientTool` so it drops directly into `AiAssist.executeClientToolTurn` —\n * making any MCP server's tools callable across all four cloud providers with no per-provider work.\n *\n * Mirrors the discipline of `@fgv/ts-extras-webauthn` / `@fgv/ts-extras-transformers`: thin\n * `Result<T>` conversion over a well-maintained upstream SDK, with no opinionated orchestration\n * above the boundary.\n *\n * **In scope (slice 1, Node):** transport factories (`createStdioTransport`,\n * `createHttpTransport`), session lifecycle (`connectMcpSession`, `closeMcpSession`), tool\n * discovery + invocation (`listMcpTools`, `callMcpTool`), and the headline adapter\n * (`adaptMcpTools`) which gracefully degrades on tools whose `inputSchema` is outside the\n * supported JSON Schema subset (surfacing them on `skipped` and warning NOISILY).\n *\n * **Explicitly NOT in scope (deferred — see README / docs/FUTURE.md):**\n * - Browser sibling `@fgv/ts-web-extras-mcp`\n * - MCP resources / prompts / sampling features\n * - OAuth / managed auth (static headers only at v0.1)\n * - Multimodal tool-result passthrough (text-block projection only)\n * - Cross-server tool-name namespacing (duplicate names already fail loudly in\n * `executeClientToolTurn`)\n *\n * @packageDocumentation\n */\n\nexport * from './packlets/mcp';\n"]}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The headline adapter — discovers an MCP server's tools and adapts each into an
3
+ * `AiAssist.IAiClientTool`, gracefully degrading (Constraint 1) on any tool whose `inputSchema`
4
+ * is outside the JSON Schema subset that `JsonSchema.fromJson` supports.
5
+ * @packageDocumentation
6
+ */
7
+ import { type Result } from '@fgv/ts-utils';
8
+ import { type IAdaptMcpToolsOptions, type IAdaptMcpToolsResult, type IMcpSession } from './model';
9
+ /**
10
+ * Discovers an MCP server's tools and adapts each into an `AiAssist.IAiClientTool` that drops
11
+ * directly into `AiAssist.executeClientToolTurn`.
12
+ *
13
+ * @remarks
14
+ * **Constraint 1 — graceful degradation with NOISY warnings.** A tool whose `inputSchema` is
15
+ * outside the JSON Schema subset supported by `JsonSchema.fromJson` is NOT adapted (the model
16
+ * must never be offered a tool whose args we can't validate). Instead it is:
17
+ * 1. excluded from {@link IAdaptMcpToolsResult.tools};
18
+ * 2. surfaced structurally on {@link IAdaptMcpToolsResult.skipped} with the tool name, the
19
+ * JSON-pointer reason, and the raw failing schema; and
20
+ * 3. logged as a NOISY `warning` (name + reason + raw schema) when an `options.logger` is
21
+ * supplied — so pointing this at a new server immediately reveals every subset feature to
22
+ * extend, with the schema in hand.
23
+ *
24
+ * The whole catalog never fails on a single bad schema; the only failure mode is an upstream
25
+ * `listMcpTools` error.
26
+ *
27
+ * @param session - A connected session from `connectMcpSession`.
28
+ * @param options - Optional logger for the NOISY skip warnings.
29
+ * @returns `Success` with `{ tools, skipped }`, or `Failure` only if tool discovery fails.
30
+ * @public
31
+ */
32
+ export declare function adaptMcpTools(session: IMcpSession, options?: IAdaptMcpToolsOptions): Promise<Result<IAdaptMcpToolsResult>>;
33
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/packlets/mcp/adapter.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,eAAe,CAAC;AAIrD,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAGjB,MAAM,SAAS,CAAC;AA+DjB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAuBvC"}