@fgv/ts-extras-mcp 5.1.0-55 → 5.1.0-56

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 (2) hide show
  1. package/CAPABILITIES.md +48 -0
  2. package/package.json +16 -15
@@ -0,0 +1,48 @@
1
+ # `@fgv/ts-extras-mcp` — MCP → ai-assist client-tools bridge (Node)
2
+
3
+ > **This file is authoritative for what ``@fgv/ts-extras-mcp`` provides and what not to hand-roll.**
4
+ > `README.md`, where present, is getting-started material. The always-loaded index at
5
+ > [`.ai/instructions/LIBRARY_CAPABILITIES.md`](../../.ai/instructions/LIBRARY_CAPABILITIES.md)
6
+ > routes here; it never duplicates this content.
7
+
8
+
9
+ ---
10
+
11
+ [libraries/ts-extras-mcp](https://github.com/ErikFortune/fgv/tree/release/libraries/ts-extras-mcp)
12
+
13
+ A Result-integration boundary over [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) (`^1.29.0`, a direct dependency) that connects to an MCP (Model Context Protocol) server, discovers its tools, and **adapts each into an `AiAssist.IAiClientTool`** (from `@fgv/ts-extras`) so it drops directly into `AiAssist.executeClientToolTurn` — making any MCP server's tools callable across all four cloud providers with no per-provider work. All SDK imports are isolated to one file so the announced SDK v2 rename is a one-file change.
14
+
15
+ | Function | Return |
16
+ |---|---|
17
+ | `createStdioTransport({ command, args?, env?, cwd? })` | `Result<IMcpTransport>` |
18
+ | `createHttpTransport({ url, headers? })` | `Result<IMcpTransport>` |
19
+ | `connectMcpSession({ transport, clientName?, clientVersion?, logger? })` | `Promise<Result<IMcpSession>>` |
20
+ | `closeMcpSession(session)` | `Promise<Result<true>>` |
21
+ | `listMcpTools(session)` | `Promise<Result<ReadonlyArray<IMcpToolDescriptor>>>` (follows the SDK's `nextCursor` for the full catalog) |
22
+ | `callMcpTool(session, name, args)` | `Promise<Result<IMcpToolCallResult>>` (text-block projection; `isError: true` → `Result.fail`, never swallowed) |
23
+ | `adaptMcpTools(session, { logger? })` | `Promise<Result<{ tools: ReadonlyArray<AiAssist.IAiClientTool>; skipped: ReadonlyArray<IMcpSkippedTool> }>>` |
24
+
25
+ **Graceful degradation (load-bearing):** `adaptMcpTools` never fails the whole catalog over one bad schema. A tool whose `inputSchema` is outside the `JsonSchema.fromJson` subset (`$ref`/`oneOf`/`pattern`/a *general* union `type` — the nullable spelling `[<type>, 'null']` is in the subset and adapts fine/…) is **excluded** from `tools` (the model is never offered a tool whose args we can't validate), **surfaced structurally** on `skipped` (name + JSON-pointer reason + raw failing schema), and — when a `logger` is supplied — **NOISY-warned** with all three. The `samples/testbed` `mcp-probe` scenario points it at any MCP server and prints a compatibility report (configure via `MCP_PROBE_URL` or `MCP_PROBE_COMMAND`).
26
+
27
+ **Explicitly NOT in scope:** browser sibling (`@fgv/ts-web-extras-mcp`), MCP resources / prompts / sampling, OAuth/managed auth (static headers only), multimodal tool-result passthrough, cross-server tool-name namespacing. The headline follow-on lever — additively widening `JsonSchema.fromJson`'s subset (`$ref`/`$defs`, `pattern`) in `@fgv/ts-json-base` — is a separate stream commissioned from what the probe surfaces. **Security:** `createStdioTransport` spawns a consumer-supplied command as a subprocess — a trust boundary; never source the command from untrusted input.
28
+
29
+ ---
30
+
31
+ ---
32
+
33
+ ## Decision shortcuts
34
+
35
+ - **Making an MCP server's tools callable from an ai-assist tool-use conversation?** → `@fgv/ts-extras-mcp` (Node). `connectMcpSession` → `adaptMcpTools(session, { logger })` → hand `result.tools` (`AiAssist.IAiClientTool[]`) to `AiAssist.executeClientToolTurn({ ..., clientTools: result.tools })`. `adaptMcpTools` gracefully degrades: tools whose `inputSchema` is outside the `JsonSchema.fromJson` subset land in `result.skipped` (name + JSON-pointer reason + raw schema) and NOISY-warn rather than failing the catalog. Transports: `createStdioTransport({ command, args })` (spawns a subprocess — trust boundary) or `createHttpTransport({ url, headers })`. Use the `samples/testbed` `mcp-probe` scenario (`MCP_PROBE_URL` / `MCP_PROBE_COMMAND`) to get a compatibility report for any server. **Don't hand-roll an MCP client or a JSON-Schema→client-tool adapter.**
36
+
37
+ ---
38
+
39
+ ## Recent additions
40
+
41
+ *Newest first. **Generated** — see the repo index; do not hand-edit inside the markers.*
42
+
43
+ <!-- BEGIN GENERATED: recent-additions -->
44
+
45
+ - **2026-08-22** — **Shipped:** `nullable: true` on every factory — the spelling OpenAI strict mode accepts for an absent-able field, where `optional(...)` is unsendable. ([#655](https://github.com/ErikFortune/fgv/pull/655))
46
+ - **2026-06-06** — Shipped `@fgv/ts-extras-mcp` (Node) — the MCP → ai-assist client-tools bridge: connect to an MCP server, discover its tools, and `adaptMcpTools` each into an `AiAssist.IAiClientTool` that drops into `executeClientToolTurn`. ([#469](https://github.com/ErikFortune/fgv/pull/469))
47
+
48
+ <!-- END GENERATED: recent-additions -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-extras-mcp",
3
- "version": "5.1.0-55",
3
+ "version": "5.1.0-56",
4
4
  "description": "Result-integration boundary over @modelcontextprotocol/sdk: connect to MCP servers, discover tools, and adapt them into @fgv/ts-extras ai-assist client tools",
5
5
  "main": "lib/index.js",
6
6
  "types": "dist/ts-extras-mcp.d.ts",
@@ -22,6 +22,7 @@
22
22
  "dist",
23
23
  "CHANGELOG.json",
24
24
  "README.md",
25
+ "CAPABILITIES.md",
25
26
  "LICENSE",
26
27
  "!lib/test",
27
28
  "!dist/test",
@@ -52,11 +53,11 @@
52
53
  "devDependencies": {
53
54
  "@microsoft/api-extractor": "^7.55.2",
54
55
  "@rushstack/eslint-config": "4.6.4",
55
- "@rushstack/heft": "1.2.7",
56
- "@rushstack/heft-jest-plugin": "1.2.6",
57
- "@rushstack/heft-node-rig": "2.11.27",
56
+ "@rushstack/heft": "1.3.0",
57
+ "@rushstack/heft-jest-plugin": "2.0.17",
58
+ "@rushstack/heft-node-rig": "2.11.50",
58
59
  "@types/heft-jest": "1.0.6",
59
- "@types/jest": "^29.5.14",
60
+ "@types/jest": "^30.0.0",
60
61
  "@types/node": "^20.14.9",
61
62
  "@typescript-eslint/eslint-plugin": "^8.52.0",
62
63
  "@typescript-eslint/parser": "^8.52.0",
@@ -66,21 +67,21 @@
66
67
  "eslint-plugin-node": "^11.1.0",
67
68
  "eslint-plugin-promise": "^7.2.1",
68
69
  "eslint-plugin-tsdoc": "~0.5.2",
69
- "jest": "^29.7.0",
70
+ "jest": "^30.5.2",
70
71
  "rimraf": "^6.1.2",
71
- "ts-jest": "^29.4.6",
72
+ "ts-jest": "^29.4.12",
72
73
  "ts-node": "^10.9.2",
73
74
  "typescript": "5.9.3",
74
- "@fgv/heft-dual-rig": "5.1.0-55",
75
- "@fgv/ts-extras": "5.1.0-55",
76
- "@fgv/ts-utils-jest": "5.1.0-55",
77
- "@fgv/ts-json-base": "5.1.0-55",
78
- "@fgv/ts-utils": "5.1.0-55"
75
+ "@fgv/heft-dual-rig": "5.1.0-56",
76
+ "@fgv/ts-utils": "5.1.0-56",
77
+ "@fgv/ts-json-base": "5.1.0-56",
78
+ "@fgv/ts-utils-jest": "5.1.0-56",
79
+ "@fgv/ts-extras": "5.1.0-56"
79
80
  },
80
81
  "peerDependencies": {
81
- "@fgv/ts-extras": "5.1.0-55",
82
- "@fgv/ts-json-base": "5.1.0-55",
83
- "@fgv/ts-utils": "5.1.0-55"
82
+ "@fgv/ts-utils": "5.1.0-56",
83
+ "@fgv/ts-extras": "5.1.0-56",
84
+ "@fgv/ts-json-base": "5.1.0-56"
84
85
  },
85
86
  "scripts": {
86
87
  "build": "heft build --clean",