stitchkit 0.119.0 → 0.120.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +10 -7
  3. package/dist/entrypoints/agent-runtime/coding-tools.js +4 -4
  4. package/dist/entrypoints/agent-runtime/harness.js +4 -4
  5. package/dist/entrypoints/agent-runtime/realtime.js +3 -3
  6. package/dist/entrypoints/agent-runtime/sandbox.js +5 -5
  7. package/dist/entrypoints/agent-runtime/sqlite/bun.js +6 -6
  8. package/dist/entrypoints/agent-runtime/sqlite/node.js +6 -6
  9. package/dist/entrypoints/agent-runtime/testing.js +6 -6
  10. package/dist/entrypoints/agent-runtime.js +13 -11
  11. package/dist/entrypoints/application/diagnostic-journal.js +2 -2
  12. package/dist/entrypoints/application/directory-inbox.js +4 -4
  13. package/dist/entrypoints/application.js +6 -6
  14. package/dist/entrypoints/cli/publish.js +4 -4
  15. package/dist/entrypoints/cli.js +7 -7
  16. package/dist/entrypoints/contract.js +4 -4
  17. package/dist/entrypoints/files.js +3 -3
  18. package/dist/entrypoints/http.js +2 -2
  19. package/dist/entrypoints/index.js +2 -2
  20. package/dist/entrypoints/node.js +1 -1
  21. package/dist/entrypoints/process.js +1 -1
  22. package/dist/entrypoints/remote.js +1 -1
  23. package/dist/entrypoints/server.js +11 -11
  24. package/dist/entrypoints/telegram/screens.js +5 -5
  25. package/dist/entrypoints/telegram.js +7 -7
  26. package/dist/entrypoints/testing.js +2 -2
  27. package/dist/entrypoints/tools/agent.d.ts +9 -0
  28. package/dist/entrypoints/tools/agent.d.ts.map +1 -0
  29. package/dist/entrypoints/tools/agent.js +16 -0
  30. package/dist/entrypoints/tools/connections.js +4 -4
  31. package/dist/entrypoints/tools/mcp.js +104 -4
  32. package/dist/entrypoints/tools/toolkit.d.ts +9 -0
  33. package/dist/entrypoints/tools/toolkit.d.ts.map +1 -0
  34. package/dist/entrypoints/tools/toolkit.js +40 -0
  35. package/dist/entrypoints/tools.d.ts +0 -10
  36. package/dist/entrypoints/tools.d.ts.map +1 -1
  37. package/dist/entrypoints/tools.js +25 -69
  38. package/dist/{index-1k18qzqa.js → index-0qyrcjfs.js} +3 -3
  39. package/dist/index-1psbyyhj.js +21 -0
  40. package/dist/index-3prvb42w.js +30 -0
  41. package/dist/{index-ba7are04.js → index-3yb5kft5.js} +1 -1
  42. package/dist/index-568w258r.js +76 -0
  43. package/dist/{index-6a69xzrx.js → index-7zwtbak8.js} +5 -46
  44. package/dist/{index-fcqj44mb.js → index-8ryydawp.js} +4 -4
  45. package/dist/{index-fqd4yqwd.js → index-8xyf8h2k.js} +1 -1
  46. package/dist/{index-6f49krb5.js → index-aa50qwv4.js} +1 -1
  47. package/dist/{index-s20s2mad.js → index-bgcwxhxh.js} +16 -14
  48. package/dist/index-bph35vpy.js +77 -0
  49. package/dist/{index-ynrf908v.js → index-bz479f0x.js} +1 -1
  50. package/dist/{index-q968hy6y.js → index-e452syyh.js} +1 -1
  51. package/dist/index-h1j71dr1.js +48 -0
  52. package/dist/{index-mgb7r8b8.js → index-jswst0h3.js} +1 -1
  53. package/dist/{index-bbvc59gw.js → index-knmnj11j.js} +9 -180
  54. package/dist/{index-57gqaq8b.js → index-nyyam9ce.js} +1 -1
  55. package/dist/{index-s0qjs6ee.js → index-pq2m7t46.js} +9 -81
  56. package/dist/{index-yk4g8805.js → index-pq7rkwkk.js} +1 -30
  57. package/dist/{index-x8d9fdeg.js → index-qctbzmg9.js} +8 -4
  58. package/dist/{index-g444vfz2.js → index-r3db01kh.js} +1 -1
  59. package/dist/index-sb9dr3tq.js +14 -0
  60. package/dist/{index-rxcgp4b9.js → index-yb9n4pgj.js} +1 -1
  61. package/dist/{index-tvtacc9a.js → index-zyc64nbh.js} +1 -34
  62. package/llms/agent-runtime-harness.txt +4 -3
  63. package/llms/agent-runtime-sandbox.txt +1 -1
  64. package/llms/agent-runtime.2.txt +3 -2
  65. package/llms/agent-runtime.3.txt +4 -46
  66. package/llms/agent-runtime.4.txt +113 -0
  67. package/llms/agent-runtime.txt +11 -13
  68. package/llms/cli.txt +1 -1
  69. package/llms/stitchkit.txt +15 -9
  70. package/llms/testing.txt +4 -6
  71. package/llms/tools-agent.txt +24 -0
  72. package/llms/tools-mcp.txt +71 -6
  73. package/llms/tools-toolkit.txt +23 -0
  74. package/llms/tools.2.txt +6 -3
  75. package/llms/tools.3.txt +8 -77
  76. package/llms/tools.txt +8 -8
  77. package/llms/{upgrading-0.106.0-0.119.0.txt → upgrading-0.106.0-0.120.0.txt} +34 -3
  78. package/llms/upgrading.txt +1 -1
  79. package/llms-full.txt +231 -119
  80. package/llms.txt +9 -7
  81. package/package.json +10 -2
  82. package/dist/{index-arjmb6de.js → index-1jwsfkfz.js} +0 -0
  83. package/dist/{index-2dfvv1jg.js → index-2fc1k9k2.js} +0 -0
  84. package/dist/{index-qndsr7f0.js → index-5efrpfmj.js} +3 -3
  85. /package/dist/{index-cyxp8rbf.js → index-mtwh9hyp.js} +0 -0
  86. /package/dist/{index-f4njz9j0.js → index-qevqn3d3.js} +0 -0
package/llms-full.txt CHANGED
@@ -55,8 +55,10 @@ own, recorded as an ADR.
55
55
  | `stitchkit/primitives` | browser **and** server | evolving | generic values and declarations for lifecycle, access, audit, delivery and exports, exact money and rounding tables |
56
56
  | `stitchkit/server` | server (Bun) | stable | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
57
57
  | `stitchkit/node` | server (Node ≥ 22) | stable | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
58
- | `stitchkit/tools` | server | stable | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
58
+ | `stitchkit/tools` | server | stable | the transport-neutral tool layer — registry, tool names and manifest, runtime tools, native tools, the OAuth provider, the durability engine; loads no optional peer at runtime |
59
59
  | `stitchkit/tools/mcp` | server (Bun or Node) | evolving | the canonical MCP HTTP/stdio server, schemas and typed MCP presenters; only Zod and the MCP server SDK peers |
60
+ | `stitchkit/tools/agent` | server (Bun or Node) | evolving | `mountAgent` — a contract's operations as AI SDK tools; only Zod and the `ai` peer |
61
+ | `stitchkit/tools/toolkit` | server (Bun or Node) | evolving | `createToolkit` — one tool set served over MCP and to an AI SDK agent; the MCP server SDK and `ai` peers |
60
62
  | `stitchkit/tools/contract` | browser + server | evolving | the shapes a tool surface speaks — async-operation contract, snapshot and cancel schemas, view-file input/output — without the runtime that serves them |
61
63
  | `stitchkit/tools/invoker` | server | stable | peer-free `createToolInvoker` over the canonical contract tool runner |
62
64
  | `stitchkit/tools/connections` | server (Bun or Node) | evolving | consume external MCP servers and a bounded OpenAPI subset — typed reauthorization, a per-request host fence and per-call credentials |
@@ -82,13 +84,13 @@ own, recorded as an ADR.
82
84
  | `stitchkit/xlsx` | browser **and** server | evolving | a workbook from rows and typed columns, with no dependency; text never runs as a formula |
83
85
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
84
86
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
85
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 64 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
87
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 65 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
86
88
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
87
89
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
88
90
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
89
91
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
90
92
  | `stitchkit/react/keyboard/testing` | server (Bun or Node) | evolving | the keyboard layers and zones without a DOM — fakes for the window, elements and key events beside the two engines, to test the order of layers, `scope`/`inert` and the edges of a zone in milliseconds |
91
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 25 of the 64 minors since 0.56.2, most recently 0.115.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
93
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 25 of the 65 minors since 0.56.2, most recently 0.115.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
92
94
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
93
95
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
94
96
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -100,7 +102,7 @@ own, recorded as an ADR.
100
102
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
101
103
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
102
104
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
103
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 64 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
105
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 65 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
104
106
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
105
107
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
106
108
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -203,7 +205,10 @@ map — feature → packages:
203
205
  | `createServer` (Bun) | — (uses `Bun.serve`) |
204
206
  | `serveNode` (Node ≥ 22) | `srvx` (+ `@types/bun` dev) |
205
207
  | In-process contract tools (`stitchkit/tools/invoker`) | — |
206
- | MCP / agent adapters (`stitchkit/tools`) | `@modelcontextprotocol/server` `ai` |
208
+ | Tool layer — registry, tool names, runtime tools (`stitchkit/tools`) | — |
209
+ | MCP server (`stitchkit/tools/mcp`) | `@modelcontextprotocol/server` |
210
+ | AI SDK agent tools (`stitchkit/tools/agent`) | `ai` |
211
+ | MCP and agent toolkit (`stitchkit/tools/toolkit`) | `@modelcontextprotocol/server` `ai` |
207
212
  | Agent application runtime (`stitchkit/agent-runtime`) | `ai` |
208
213
  | Headless Agent harness (`stitchkit/agent-runtime/harness`) | `ai` |
209
214
  | Agent coding tools (`stitchkit/agent-runtime/coding-tools`) | — |
@@ -232,15 +237,16 @@ bun add socket.io @socket.io/bun-engine # e.g. the Socket.IO server on Bun
232
237
  ```
233
238
 
234
239
  Dynamic optional-peer adapters fail with an actionable error naming the package
235
- and install command. Static entrypoints such as `stitchkit/tools` fail during
240
+ and install command. Static entrypoints such as `stitchkit/tools/mcp` fail during
236
241
  ESM resolution by naming the exact missing package; the feature-to-peer matrix
237
242
  below is the canonical install command.
238
243
 
239
- The combined tools entry owns MCP and AI-agent adapters, so install both runtime
240
- peers before importing `stitchkit/tools`:
244
+ `stitchkit/tools` itself loads no optional peer. Install the peer of the adapter
245
+ you import — both for `stitchkit/tools/toolkit`:
241
246
 
242
247
  ```bash
243
- bun add @modelcontextprotocol/server@^2 ai@^7
248
+ bun add @modelcontextprotocol/server@^2 # stitchkit/tools/mcp
249
+ bun add ai@^7 # stitchkit/tools/agent
244
250
  ```
245
251
 
246
252
  Browser, HTTP-client and React entrypoints remain usable without either MCP
@@ -3936,10 +3942,10 @@ recursive calls without retaining request state. Every invocation gets a fresh
3936
3942
  tool-call context and runs the same extension resolution, input/output
3937
3943
  validation, lifecycle, hooks and output-strip reporter as mounted tools.
3938
3944
 
3939
- The dedicated entrypoint needs only the normal `stitchkit`/`zod` install. Use
3940
- the broader `stitchkit/tools` barrel when the same program also mounts MCP or AI
3941
- adapters and has installed their optional peers. Both imports reach the same
3942
- runner; this is dependency isolation, not a second execution implementation.
3945
+ The dedicated entrypoint needs only the normal `stitchkit`/`zod` install, and so does
3946
+ `stitchkit/tools`, which exports the same invoker beside the rest of the tool layer. Both
3947
+ imports reach the same runner; this is dependency isolation, not a second execution
3948
+ implementation.
3943
3949
 
3944
3950
  `invoke` returns the canonical discriminated `ToolResult`, not an AI SDK or MCP
3945
3951
  presentation envelope. `invokeOrThrow` returns validated data and throws the
@@ -3961,9 +3967,8 @@ get the view's defaults and projected answer, which is what `collectTools` and
3961
3967
  An MCP-only server imports `stitchkit/tools/mcp` and installs
3962
3968
  `stitchkit`, `zod` and `@modelcontextprotocol/server`. The leaf's runtime and strict
3963
3969
  NodeNext declarations require no `ai`. It exports the existing HTTP/stdio server,
3964
- schema policy, catalog and resource helpers; their implementation and security are shared
3965
- with the full `stitchkit/tools` barrel. Use that full barrel when the application also
3966
- needs its AI SDK features.
3970
+ schema policy, catalog and resource helpers, and it is the only entrypoint that does:
3971
+ `stitchkit/tools` loads no optional peer. AI SDK tools come from `stitchkit/tools/agent`.
3967
3972
 
3968
3973
  `createMcpHandler` builds a complete stateless Streamable-HTTP MCP endpoint on
3969
3974
  the official TypeScript SDK v2 server package. It owns server creation,
@@ -4687,7 +4692,8 @@ stitchkit ships the OAuth **protocol mechanics**; the app supplies only
4687
4692
  **identity and storage**. Three pieces wire it together:
4688
4693
 
4689
4694
  ```ts
4690
- import { createMcpHandler, createMcpHttpRoute, mountOAuthProvider, oauthProtectedResourceRoute } from 'stitchkit/tools'
4695
+ import { mountOAuthProvider, oauthProtectedResourceRoute } from 'stitchkit/tools'
4696
+ import { createMcpHandler, createMcpHttpRoute } from 'stitchkit/tools/mcp'
4691
4697
  import { createServer } from 'stitchkit/server'
4692
4698
 
4693
4699
  const resource = 'https://api.example.com/mcp'
@@ -4948,7 +4954,7 @@ see [Agent application runtime](./agent-runtime.md).
4948
4954
  `generateText` / `streamText`:
4949
4955
 
4950
4956
  ```ts
4951
- import { mountAgent } from 'stitchkit/tools'
4957
+ import { mountAgent } from 'stitchkit/tools/agent'
4952
4958
  import { generateText } from 'ai'
4953
4959
 
4954
4960
  const tools = mountAgent(usersService, { context: { userId: 'agent-1' } })
@@ -5032,7 +5038,9 @@ result. Optional presentation callbacks map that result to MCP content and AI
5032
5038
  SDK model output without coupling the handler to either SDK:
5033
5039
 
5034
5040
  ```ts
5035
- import { createMcpHandler, defineRuntimeTool, mountAgent } from 'stitchkit/tools'
5041
+ import { defineRuntimeTool } from 'stitchkit/tools'
5042
+ import { createMcpHandler } from 'stitchkit/tools/mcp'
5043
+ import { mountAgent } from 'stitchkit/tools/agent'
5036
5044
  import { z } from 'zod'
5037
5045
 
5038
5046
  const renderPreview = defineRuntimeTool({
@@ -5398,7 +5406,8 @@ hooks. The built-in `mountViewFile`, `mountWait`, `mountDownload` and
5398
5406
  media helper fetches with SSRF and path-traversal defenses:
5399
5407
 
5400
5408
  ```ts
5401
- import { createMcpHandler, mountViewFile } from 'stitchkit/tools'
5409
+ import { mountViewFile } from 'stitchkit/tools'
5410
+ import { createMcpHandler } from 'stitchkit/tools/mcp'
5402
5411
 
5403
5412
  const handleMcp = createMcpHandler({
5404
5413
  serverInfo: { name: 'my-app', version: '1.0.0' },
@@ -5506,16 +5515,16 @@ identical. Write the handler once; it serves every surface.
5506
5515
  > **Maturity: evolving.** This surface is still finding its shape and may be
5507
5516
  > redefined in any minor release — always with a `### ⚠️ Breaking changes` entry
5508
5517
  > and a migration section, never silently. If your application already owns the
5509
- > conversation loop, `mountAgent` from `stitchkit/tools` is the stable path.
5518
+ > conversation loop, `mountAgent` from `stitchkit/tools/agent` is the direct path.
5510
5519
 
5511
5520
  `stitchkit/agent-runtime` is the server-only, opinionated layer above
5512
5521
  `mountAgent`. Use it when the application wants Stitchkit to own conversation
5513
5522
  mechanics: durable acceptance, history projection, the AI SDK stream loop,
5514
5523
  checkpoints, keyed interruption, terminal commit and stable application events.
5515
5524
 
5516
- If the application already owns that loop, continue importing `mountAgent` from
5517
- `stitchkit/tools`. `stitchkit/tools` does not depend on this entrypoint at all;
5518
- this entrypoint uses the tool executor from it, but pulls no MCP peer, so
5525
+ If the application already owns that loop, import `mountAgent` from
5526
+ `stitchkit/tools/agent`. Neither `stitchkit/tools` nor `stitchkit/tools/agent` depends on
5527
+ this entrypoint; this entrypoint uses the tool executor, but pulls no MCP peer, so
5519
5528
  choosing `mountAgent` alone costs you nothing from here.
5520
5529
 
5521
5530
  UI and shared DTO code must import canonical records and delivery validation from
@@ -5539,12 +5548,8 @@ persistence, event sinks and every Node context dependency.
5539
5548
  bun add stitchkit ai zod
5540
5549
  ```
5541
5550
 
5542
- `mountAgent` from `stitchkit/tools` — used in the composition below — additionally
5543
- needs the MCP peer, which that entrypoint imports statically:
5544
-
5545
- ```sh
5546
- bun add @modelcontextprotocol/server
5547
- ```
5551
+ `mountAgent` from `stitchkit/tools/agent` — used in the composition below — needs no
5552
+ peer beyond `ai`.
5548
5553
 
5549
5554
  OpenRouter is isolated so other runtime users do not resolve its package:
5550
5555
 
@@ -5565,7 +5570,8 @@ import {
5565
5570
  defineModelRegistry,
5566
5571
  } from 'stitchkit/agent-runtime'
5567
5572
  import { openRouterProvider } from 'stitchkit/agent-runtime/openrouter'
5568
- import { composeToolLifecycle, mountAgent } from 'stitchkit/tools'
5573
+ import { composeToolLifecycle } from 'stitchkit/tools'
5574
+ import { mountAgent } from 'stitchkit/tools/agent'
5569
5575
 
5570
5576
  const protocol = defineAgentProtocol({
5571
5577
  context: z.object({ userId: z.string() }),
@@ -7279,7 +7285,8 @@ import {
7279
7285
  createAgentHarnessFileResources,
7280
7286
  createHeadlessAgentHarness,
7281
7287
  } from 'stitchkit/agent-runtime/harness';
7282
- import { composeToolLifecycle, mountAgent } from 'stitchkit/tools';
7288
+ import { composeToolLifecycle } from 'stitchkit/tools';
7289
+ import { mountAgent } from 'stitchkit/tools/agent';
7283
7290
 
7284
7291
  const resources = createAgentHarnessFileResources({
7285
7292
  roots: [{ id: 'guide', kind: 'instruction', path: instructionRoot }],
@@ -7303,8 +7310,8 @@ compose your authorization with the run's `toolFenceLifecycle` by `composeToolLi
7303
7310
  fence rejects a call from a run that no longer owns the conversation, and it must run exactly
7304
7311
  once. Every mount option remains available, including registry, runtime tools, extension,
7305
7312
  coercion, output stripping, hooks and durability, and the callback may be async. The same callback
7306
- still accepts arbitrary typed AI SDK tools and prepareStep. `stitchkit/tools` needs the same `ai` and
7307
- `@modelcontextprotocol/server` peers as any `mountAgent` use; the base harness stays AI-only.
7313
+ still accepts arbitrary typed AI SDK tools and prepareStep. `mountAgent` comes from `stitchkit/tools/agent`, which needs only the `ai` peer the
7314
+ harness already has; the base harness stays AI-only.
7308
7315
  The resource reader is explicitly selected: filtered allowlists do not gain tools merely
7309
7316
  because a loader exists. Root IDs, kinds, provenance and limits are unchanged.
7310
7317
 
@@ -8657,7 +8664,7 @@ Storage is process-durable, without a power-loss/fsync guarantee.
8657
8664
 
8658
8665
  ```ts
8659
8666
  import { createSandboxCodingTools } from 'stitchkit/agent-runtime/sandbox';
8660
- import { mountAgent } from 'stitchkit/tools';
8667
+ import { mountAgent } from 'stitchkit/tools/agent';
8661
8668
 
8662
8669
  const tools = mountAgent([], {
8663
8670
  runtimeTools: createSandboxCodingTools(handle, {
@@ -10040,7 +10047,7 @@ types; the package keeps its required dependencies separate from optional SDKs.
10040
10047
  CLI runtime tools use the one runtime-tool declaration: identity, input and output
10041
10048
  schemas, handler, and explicit CLI exposure. SDK presenters are the adapter's extension
10042
10049
  of that declaration (the fourth type argument of `RuntimeToolDefinitionWithOutput`, or
10043
- `defineRuntimeTool` in `stitchkit/tools`), which requires the corresponding peers. A typed
10050
+ `defineRuntimeTool` in `stitchkit/tools`), whose presenter types name the corresponding SDKs. A typed
10044
10051
  definition returned by `defineRuntimeTool` or `createRuntimeToolFactory` can be
10045
10052
  passed directly to both CLI and SDK mounts.
10046
10053
 
@@ -14917,8 +14924,9 @@ fixture's transitive dependency.
14917
14924
 
14918
14925
  That includes `stitchkit/tools/invoker`: a minimal packed consumer imports it
14919
14926
  without MCP/AI peers and executes validation, output projection and normalized
14920
- errors on Bun and Node. The broader `stitchkit/tools` barrel deliberately keeps
14921
- the adapter peer budget.
14927
+ errors on Bun and Node, and so does `stitchkit/tools`, which loads no optional peer at
14928
+ runtime. The adapters keep their peer budgets on their own subpaths:
14929
+ `stitchkit/tools/mcp`, `stitchkit/tools/agent` and `stitchkit/tools/toolkit`.
14922
14930
 
14923
14931
  Beside the matrix, one case is about the ARTIFACT rather than the inventory: a
14924
14932
  program that injects the Socket.IO peer loaders is bundled and started in a
@@ -15147,10 +15155,7 @@ signal and deadline. Bind its process lifecycle with the truthful close-only
15147
15155
  sibling from `stitchkit/tools`:
15148
15156
 
15149
15157
  ```ts
15150
- import {
15151
- bindStdioProcessSignals,
15152
- createStdioMcpServer,
15153
- } from 'stitchkit/tools'
15158
+ import { bindStdioProcessSignals, createStdioMcpServer } from 'stitchkit/tools/mcp'
15154
15159
 
15155
15160
  const stdio = await createStdioMcpServer(config)
15156
15161
  const binding = bindStdioProcessSignals(stdio, {
@@ -17144,6 +17149,37 @@ charts, no merged cells and no streaming: an application that needs them takes a
17144
17149
 
17145
17150
  # Upgrading stitchkit
17146
17151
 
17152
+ ## Released migration: 0.120.0
17153
+
17154
+ ### tools-barrel-subpaths
17155
+
17156
+ **Who must act:** code importing the MCP server, `mountAgent` or `createToolkit` from
17157
+ `stitchkit/tools`. Imports of the registry, tool names, manifest, runtime and native tools, the
17158
+ invoker, the OAuth provider and the durability engine stay where they are.
17159
+
17160
+ `stitchkit/tools` now loads no optional peer, so an application without
17161
+ `@modelcontextprotocol/server` and `ai` can import it. Move each adapter import to its subpath:
17162
+
17163
+ ```ts
17164
+ // before
17165
+ import { createMcpHandler, listToolNames, mountAgent } from 'stitchkit/tools'
17166
+ import { createToolkit } from 'stitchkit/tools'
17167
+ // after
17168
+ import { listToolNames } from 'stitchkit/tools'
17169
+ import { createMcpHandler } from 'stitchkit/tools/mcp'
17170
+ import { mountAgent } from 'stitchkit/tools/agent'
17171
+ import { createToolkit } from 'stitchkit/tools/toolkit'
17172
+ ```
17173
+
17174
+ | Names | New subpath | Peers it needs |
17175
+ |-------|-------------|----------------|
17176
+ | `createMcpHandler`, `createMcpHttpRoute`, `buildMcpServer`, `mountMcp`, `mountMcpResource`, `validateMcpSchemas`, `createStdioMcpServer`, `bindStdioProcessSignals`, `inlineMcpAppBundle`, `mcpCatalogMeta`, `readMcpCatalogStamp`, `EXT_APPS_BUNDLE_PLACEHOLDER`, `MCP_CATALOG_META_KEY`, `RESOURCE_MIME_TYPE` and their config types, `McpServer`, `IncompatibleSchemaPolicy`, `McpSchemaValidationConfig` | `stitchkit/tools/mcp` | `@modelcontextprotocol/server` |
17177
+ | `mountAgent`, `AgentMountConfig`, `AgentContext` | `stitchkit/tools/agent` | `ai` |
17178
+ | `createToolkit`, `Toolkit` | `stitchkit/tools/toolkit` | `@modelcontextprotocol/server`, `ai` |
17179
+
17180
+ The move is mechanical: `bunx stitchkit upgrade --from 0.119.0` lists every import it touches, and
17181
+ `tsc` names any name still imported from `stitchkit/tools`. Behaviour is unchanged.
17182
+
17147
17183
  ## Released migration: 0.119.0
17148
17184
 
17149
17185
  ### factory-default-exposure
@@ -23813,8 +23849,8 @@ Separate optional evolving Bun/OpenTUI package over a caller-composed headless h
23813
23849
 
23814
23850
  | Export | Kind | Summary |
23815
23851
  |--------|------|---------|
23816
- | `defineAgentTui` | function | typed config for title/theme/status rows, model catalog, context, commands, runtime bundle and optional host-evidenced recovery policy; the default never requeues acquired effects |
23817
- | `runAgentTui` | function | start one fresh durable conversation and terminal controller, recover durable work and publish its authenticated local session; `initialConversationId` is an explicit resume override |
23852
+ | `defineAgentTui` | function | typed config for title, `theme` (a `TerminalPalette` override) and `themeMode`, status rows, model catalog, context, commands, runtime bundle and optional host-evidenced recovery policy; the default never requeues acquired effects |
23853
+ | `runAgentTui` | function | start one fresh durable conversation and terminal controller, recover durable work and publish its authenticated local session; `initialConversationId` is an explicit resume override; it closes the session and exits the process on Ctrl-C and every signal OpenTUI catches unless `exitSignals: []` |
23818
23854
  | `defineTuiCommand` / `resolveTuiCommand` | function | typed composable slash-command registry; unknown slash input remains an ordinary model prompt |
23819
23855
  | `createAgentTuiController` | function | single admission, selection, approval, interruption and conversation-switch owner over the harness |
23820
23856
  | `startAgentTuiSessionHost` / `createAgentTuiClient` | function | authenticated mode-`0600` Unix-socket host/client for status, submit and interrupt through that controller |
@@ -23823,7 +23859,7 @@ Separate optional evolving Bun/OpenTUI package over a caller-composed headless h
23823
23859
  | `defaultAgentTuiStatusLine` / `AgentTuiStatusLineFormatter` | function / _type_ | terminal-native default rows and a host formatter over model capacity, durable snapshot, activity, workspace and local identities; `statusLine: false` hides the rows |
23824
23860
  | `createAgentTuiDiagnosticRecorder` / `AgentTuiDiagnosticEventSchema` | function / schema | bounded per-session metadata journal that rejects prompt, reasoning, tool-input and provider-cause payloads before disk admission |
23825
23861
 
23826
- The `stitchkit-agent` binary loads `stitchkit.agent.ts` by default and also exposes `sessions`,
23862
+ The `stitchkit-agent` binary runs React's production build unless `NODE_ENV` says otherwise and loads `stitchkit.agent.ts` by default and also exposes `sessions`,
23827
23863
  `status`, `send` and `interrupt`. `--workspace` addresses a host outside the caller's cwd,
23828
23864
  `send --idempotency-key` accepts caller-owned retry identity, and `interrupt` defaults to the
23829
23865
  active run returned by `status`. Session descriptors and sockets are local control credentials,
@@ -23846,6 +23882,65 @@ Renderer-neutral state only. This entrypoint imports neither React/OpenTUI nor t
23846
23882
  | `createTerminalCommandPalette` / `terminalCommandMatches` | function | bounded command filtering and keyboard selection over a collision-validated registry |
23847
23883
  | `resolveExactTerminalCommand` / `validateTerminalCommands` | function | exact dispatch and fail-closed name/alias validation |
23848
23884
  | `createTerminalOperationState` / `reduceTerminalOperationState` | function | confirmation and single-pending-operation lifecycle |
23885
+ | `createTerminalTable` / `reduceTerminalTable` / `projectTerminalTable` | function | live table: typed columns, rows validated on entry, sort with key tie-break and missing values last, tree expansion pruned to present rows, filter on displayed text, selection kept across data; a row's `tone` and a column's `tone(value, row)` colour state |
23886
+ | `layoutTerminalTableColumns` / `formatTerminalTableCell` / `visibleTerminalTableRows` / `terminalTableTreePrefix` | function | fixed and flexible column widths, `—` for missing values, the virtualized window, tree indentation |
23887
+ | `createTerminalList` / `reduceTerminalList` / `visibleTerminalListLines` | function | picker with sections, fuzzy query with title highlight ranges, multi-select, disabled items and "more above/below" counts |
23888
+ | `createTerminalForm` / `reduceTerminalForm` / `readTerminalForm` / `terminalFormFieldsFromJsonSchema` | function | typed fields (text, secret, number, integer, boolean, choice, JSON) from a JSON Schema, relative text edits, validation on leave and submit |
23889
+ | `createTerminalTabs` / `reduceTerminalTabs` | function | tabs with badges, wrap-around movement, digit selection and reconcile that keeps the selected tab |
23890
+ | `createTerminalNavigation` / `reduceTerminalNavigation` / `terminalBreadcrumbs` | function | screen stack keeping each level's state, root never popped |
23891
+ | `createTerminalFocus` / `reduceTerminalFocus` | function | focus ring plus layers that take the keyboard and give it back |
23892
+ | `createTerminalNotices` / `reduceTerminalNotices` / `nextTerminalNoticeExpiry` | function | bounded toasts on a caller clock, replaced by id |
23893
+ | `createTerminalTimeSeries` / `appendTerminalSample` / `sampleTerminalTimeSeries` | function | time window bounded by duration and sample count, value-in-force sampling with explicit gaps |
23894
+ | `terminalBrailleChart` / `terminalSparkline` / `terminalTimeAxis` / `terminalChartScale` | function | multi-series braille line or area chart as toned runs, sparkline, time axis |
23895
+ | `terminalMeter` / `layoutTerminalMeterGrid` | function | eighth-block bar toned by thresholds, unmeasured as muted; column-major core grid |
23896
+ | `terminalProgress` / `terminalSpinnerFrame` / `terminalIndeterminateBlock` / `formatTerminalDuration` | function | ratio, rate and ETA only when knowable; spinner frames; indeterminate bar; elapsed time |
23897
+ | `defineTerminalKeymap` / `matchTerminalKey` / `fitTerminalKeyHints` | function | conflict-checked bindings that both answer keys and draw a footer fitted to the width |
23898
+ | `terminalTableKeymap` / `terminalTableKey` / `terminalTabsKeymap` / `terminalTabsKey` | function | htop-style table bindings and tab bindings as keymaps |
23899
+ | `matchTerminalSearch` / `searchTerminalItems` / `terminalHighlightRuns` | function | multi-word fuzzy match with ranges, stable ranking, highlight runs |
23900
+ | `sanitizeTerminalText` / `terminalTextWidth` / `truncateTerminalText` / `fitTerminalText` / `wrapTerminalText` | function | strip escape and control sequences; measure, cut, pad and wrap by terminal cells |
23901
+ | `terminalTextEdit` / `applyTerminalTextEdit` | function | one-line edits as relative actions, so fast input is never lost |
23902
+ | `terminalJsonLines` / `layoutTerminalDetails` | function | toned, sanitized JSON lines; aligned key/value pairs |
23903
+ | `terminalPalettes` / `resolveTerminalPalette` / `TerminalPalette` / `TerminalTone` | value / function / _type_ | one semantic palette (surfaces plus `primary`, `muted`, `accent`, `success`, `warning`, `danger`) for dark and light terminals |
23904
+ | `terminalLabelsEn` / `terminalLabelsRu` / `TerminalLabels` | value / _type_ | every word the widgets draw |
23905
+
23906
+ ### `stitchkit-tui/widgets`
23907
+
23908
+ OpenTUI React widgets over the core state. React, `@opentui/core` and `@opentui/react` are peers;
23909
+ this entrypoint never loads `stitchkit`.
23910
+
23911
+ | Export | Kind | Summary |
23912
+ |--------|------|---------|
23913
+ | `TerminalAppShell` / `TerminalPanel` / `TerminalStatusBar` / `TerminalKeyHints` | component | breadcrumbs, status lines, body, fitted key hints and toast overlay; titled rounded panels with a focus frame |
23914
+ | `TerminalTable` | component | virtualized live table with header sort marks, tree, filter line and htop keys; row and cell tones in the palette, bold or dim where colour is missing |
23915
+ | `terminalToneAttributes` | function | the text attribute that carries a tone without colour: `danger` and `warning` bold, `muted` dim |
23916
+ | `TerminalList` | component | sections, fuzzy search line with highlights, `›` cursor, meta, badges, multi-select, description |
23917
+ | `runTerminalApp` / `RunTerminalAppOptions` / `RunningTerminalApp` | function / _type_ | start an application: renderer, theme and labels providers, the error boundary, and an exit with 128 + signal after `onClose` on Ctrl-C and every signal OpenTUI catches — a closed window leaves no orphan |
23918
+ | `TerminalErrorBoundary` / `TERMINAL_EXIT_SIGNALS` / `TerminalExitSignal` | component / value / _type_ | draws a render error and its stack in place of the screen, where OpenTUI's own boundary renders nothing under production React |
23919
+ | `TerminalForm` | component | fields edited in place, cycling choices, masked secrets, inline errors; a form without fields says so and submits `{}` on Enter |
23920
+ | `TerminalTextView` / `TerminalJsonView` | component | pager over sanitized wrapped text or toned JSON |
23921
+ | `TerminalMeter` / `TerminalMeterGrid` / `TerminalChart` / `TerminalSparkline` | component | htop meters and core grid; btop braille charts with axis |
23922
+ | `TerminalTabs` / `TerminalDialog` / `TerminalSpinner` / `TerminalProgressBar` / `TerminalAsyncView` / `TerminalDetails` / `TerminalNotices` / `TerminalHelp` | component | views, confirmation, loading, progress, async states, details, toasts, key help |
23923
+ | `TerminalThemeProvider` / `useTerminalPalette` / `useTerminalThemeMode` | component / hook | palette from the terminal's reported background (`auto`) or a fixed mode |
23924
+ | `TerminalLabelsProvider` / `TerminalFocusProvider` / `useTerminalFocused` | component / hook | product language and shared focus |
23925
+
23926
+ The `stitchkit-tui-gallery` binary shows every widget live.
23927
+
23928
+ ### `stitchkit-tui/build`
23929
+
23930
+ Build-time only; imports Bun and no React.
23931
+
23932
+ | Export | Kind | Summary |
23933
+ |--------|------|---------|
23934
+ | `compileTerminalApp` / `CompileTerminalAppOptions` | function / _type_ | one standalone executable for any Bun compile target, from any machine, with React's production build defined |
23935
+ | `terminalNativePlugin` / `TerminalNativePluginOptions` | function / _type_ | the `Bun.build` plugin behind it: the target's `@opentui/core-<os>-<arch>` at the pinned version from the registry, verified against `bun.lock`; other platforms' packages throw; musl refused |
23936
+ | `terminalNativeTarget` / `TerminalNativeTarget` | function / _type_ | the native package a compile target needs |
23937
+
23938
+ ### `stitchkit-tui/testing`
23939
+
23940
+ | Export | Kind | Summary |
23941
+ |--------|------|---------|
23942
+ | `renderTerminalTest` / `TerminalTestScreen` / `TerminalTestOptions` | function / _type_ | a screen inside the kit's providers on a test terminal; `press`, `type`, `burst`, `advance`, `waitForText`, `resize` run inside React's `act` and wait out a lone Esc |
23943
+ | `TerminalTestKey` / `TerminalTestModifiers` | _type_ | the mock input's key names and modifiers |
23849
23944
 
23850
23945
  ## `stitchkit/agent-runtime/sqlite/node`
23851
23946
 
@@ -23955,57 +24050,25 @@ SDK, `ai`, or other optional tool peers, so it is safe in a thin CLI bundle.
23955
24050
 
23956
24051
  ## `stitchkit/tools`
23957
24052
 
23958
- Server-only. Turns contracts into MCP and AI-agent tools. MCP server surfaces
23959
- need the `@modelcontextprotocol/server` v2 peer; MCP hosts/tests use the separate
23960
- `@modelcontextprotocol/client` package. Agent surfaces need the `ai` peer.
23961
-
23962
- Framework-owned MCP tools advertise the exact declared output schema and return
23963
- the validated value unchanged as `structuredContent`, including arrays, scalars
23964
- and `null`. Tools without an output contract advertise and return no structured
23965
- payload.
24053
+ Server-only, and imported without any optional peer: the transport-neutral tool layer —
24054
+ the registry, tool names and manifest, runtime tools, native tools, the invoker, the OAuth
24055
+ provider and the durability engine. An application that serves its operations over HTTP and
24056
+ CLI lists its tool names here with neither MCP nor the AI SDK installed. The adapters that
24057
+ need a peer have their own subpaths: [`stitchkit/tools/mcp`](#stitchkittoolsmcp) (the MCP
24058
+ server SDK), [`stitchkit/tools/agent`](#stitchkittoolsagent) (the `ai` peer) and
24059
+ [`stitchkit/tools/toolkit`](#stitchkittoolstoolkit) (both). → ADR 0284.
23966
24060
 
23967
24061
  | Export | Kind | Summary |
23968
24062
  |--------|------|---------|
23969
- | `createMcpHandler` | function | a stateless dual-era Streamable-HTTP MCP handler — [guide](../guide/mcp-and-agents.md#mcp--createmcphandler) |
23970
- | `createMcpHttpRoute` | function | framework-owned `RawRoute` adapter for an MCP HTTP handler |
23971
- | `createStdioMcpServer` | function | a complete stdio MCP server — [guide](../guide/mcp-and-agents.md#mcp-over-stdio--createstdiomcpserver) |
23972
- | `bindStdioProcessSignals` | function | explicitly bind OS signals to one close-only stdio handle — [guide](../guide/testing-and-deployment.md#stdio-process-signals) |
23973
- | `buildMcpServer` | function | build an `McpServer` from contract/runtime surfaces; no-auth configs omit the second argument |
23974
- | `mountMcp` | function | add contract tools to an existing `McpServer` — [guide](../guide/mcp-and-agents.md#mountmcp) |
23975
- | `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service; failed executions reject through the SDK tool-error channel with a safe typed envelope, while successful output is never classified by field name — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
23976
24063
  | `defineRuntimeTool` | function | define one validated pathless operation for explicit MCP, Agent and/or CLI surfaces — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
23977
24064
  | `createRuntimeToolFactory` | function | bind shared identity and Zod-validated per-call context for runtime tools — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
23978
- | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use peer-free `stitchkit/tools/invoker`, or the full `stitchkit/tools` adapter barrel — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
23979
- | `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
24065
+ | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use `stitchkit/tools/invoker` or `stitchkit/tools`, both peer-free — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
23980
24066
  | `mountViewFile` | function | a native multimodal "view file" MCP tool |
23981
24067
  | `resolveMedia` | function | resolve a media reference for a tool result |
23982
- | `validateMcpSchemas` | function | object-shaped assertion over the exact advertised schema surface — compatibility, typed properties and portable formats ([guide](../guide/mcp-and-agents.md#mcp-schema-validation-profile)) |
23983
24068
  | `listToolNames` | function | every contract/runtime tool name with origin, identity and transports — for stable snapshots — [guide](../guide/mcp-and-agents.md#pinning-tool-names--listtoolnames) |
23984
24069
  | `listContractToolNames` | function | the same listing straight from contracts — no handlers or stub services needed |
23985
24070
  | `describeToolCatalog` | function | inspect the exact model-facing names, source identities, schema byte sizes and deferred state; an explicit total byte budget fails closed |
23986
24071
  | `ToolCatalogConfig` / `ToolCatalogEntry` | _type_ | catalog source, transport, optional explicit schema budget and one inspectable result row |
23987
- | `McpHandlerConfig` | _type_ | server surface plus stateless HTTP transport config |
23988
- | `McpHttpConfig` | _type_ | HTTP auth, protected-resource, legacy-era and security options |
23989
- | `McpHttpHandler` | _type_ | framework-owned `{ fetch(request), close() }` lifecycle |
23990
- | `McpHttpSecurityConfig` | _type_ | Fetch-boundary Host and Origin allowlists |
23991
- | `McpLegacyPolicy` | _type_ | `'serve' \| 'reject'` protocol-era compatibility policy |
23992
- | `McpStdioHandle` | _type_ | closeable official stdio transport handle |
23993
- | `StdioMcpServerConfig` | _type_ | config for `createStdioMcpServer` |
23994
- | `StdioCloseTarget` | _type_ | minimal close-only target accepted by `bindStdioProcessSignals` |
23995
- | `StdioProcessSignalsOptions` | _type_ | signal source, close callbacks and phased error reporting |
23996
- | `StdioProcessSignalsBinding` | _type_ | close-only signal binding with observed `promise` and listener `close()` |
23997
- | `StdioProcessSignalsErrorPhase` | _type_ | `'prepare' \| 'close' \| 'complete'` reporting phase |
23998
- | `McpServerBuildConfig` | _type_ | shared config for `buildMcpServer` |
23999
- | `McpServerSharedConfig` | _type_ | transport-neutral options shared by direct and finite surface configs |
24000
- | `McpServer` | _type_ | official split-SDK server instance accepted by raw extension points |
24001
- | `DirectMcpSurfaceConfig` | _type_ | static or identity-dynamic `services` / `runtimeTools` source |
24002
- | `FiniteMcpSurfaceConfig` | _type_ | bounded `surfaces` registry plus typed selector |
24003
- | `McpSurfaceDefinition` | _type_ | one immutable `{ services, runtimeTools }` MCP surface |
24004
- | `McpSurfaceRegistry` | _type_ | finite keyed surface registry for eager preparation |
24005
- | `StdioAuthConfig` | _type_ | startup identity composed into `StdioMcpServerConfig` |
24006
- | `McpMountConfig` | _type_ | config for `mountMcp` |
24007
- | `McpSchemaValidationConfig` | _type_ | shared `{ policy, requireTypedProperties, allowUntyped, requirePortableFormats, allowFormats }` profile |
24008
- | `ValidateMcpSchemasConfig` | _type_ | standalone validation profile plus `services`, `extend`, flattening and logger |
24009
24072
  | `RuntimeToolDefinition` | _type_ | heterogeneous registration of pathless operations in `runtimeTools: [...]`; an inline handler is contextually typed by the parsed object, a definition constructed with its own schema registers unchanged, and the runner validates input before the handler |
24010
24073
  | `RuntimeToolDefinitionBase` | _type_ | common name, identity, input, exposure and MCP metadata fields |
24011
24074
  | `RuntimeToolDefinitionWithOutput` | _type_ | the one neutral construction: identity, schemas and a handler typed from them; the fourth type argument names the adapter's `present` extension (`RuntimeToolPresenters<…>` here, `RuntimeMcpToolPresenters<…>` on `stitchkit/tools/mcp`, none by default) |
@@ -24031,11 +24094,8 @@ payload.
24031
24094
  | `CimdCacheEvent` | _type_ | observable CIMD cache hit, miss, revalidation and eviction event |
24032
24095
  | `createSecureClientMetadataFetcher` | function | production HTTPS, DNS/IP-pinned CIMD fetcher |
24033
24096
  | `RuntimeAgentModelOutput` | _type_ | AI SDK model-facing text/JSON/content output returned by `present.agent` |
24034
- | `AgentMountConfig` | _type_ | config for `mountAgent` |
24035
24097
  | `AgentToolRegistry` / `AgentToolRegistryBuilder` / `AgentToolRegistryInput` | _type_ | the composed runtime surface and its builder: declared defaults, `replace`/`disable` by name, and the exact `{ tools, names }` a mount receives |
24036
24098
  | `defineToolRegistry` | function | compose runtime tools over one declared default set; an unknown `replace`/`disable` name is refused instead of silently leaving the default in place |
24037
- | `AgentContext` | _type_ | the context merged into agent tool handlers |
24038
- | `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
24039
24099
  | `ToolExtend` | _type_ | extra-args extension for `mountMcp` / `mountAgent` |
24040
24100
  | `ToolLifecycle` | _type_ | `beforeHandle` / `afterHandle` gate for tool calls — [guide](../guide/mcp-and-agents.md#guarding-tools--lifecycle) |
24041
24101
  | `ToolExecutionControlReason` | _type_ | internal managed-execution stop reason: stale run or requested interruption |
@@ -24067,7 +24127,6 @@ payload.
24067
24127
  | `NonPortableFormat` | _type_ | one `{ path, format }` portability finding |
24068
24128
  | `PORTABLE_JSON_SCHEMA_FORMATS` | constant | portable-format baseline used by MCP validation |
24069
24129
  | `ToolNameEntry` | _type_ | one `listToolNames` row — `{ kind, name, service, method, transports }` |
24070
- | `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
24071
24130
  | `McpMediaContent` | _type_ | a multimodal MCP content item |
24072
24131
 
24073
24132
  ### Native tools
@@ -24171,6 +24230,77 @@ mountAgent(services, { durability: (toolCallId) => myLedgerFor(toolCallId) });
24171
24230
  | `AgentToolError` | class | the model-safe envelope a failed agent tool throws |
24172
24231
  | `isAgentToolError` | function | brand check for it — a consumer running its own loop no longer parses the message |
24173
24232
 
24233
+ ### Introspection & internals
24234
+
24235
+ Advanced building blocks — the shared machinery the mounts are built on.
24236
+
24237
+ | Export | Kind | Summary |
24238
+ |--------|------|---------|
24239
+ | `collectTools` | function | resolve a service's methods to mountable tools (the shared resolver) |
24240
+ | `createToolLogger` | function | a ready `afterToolCall` that logs every tool call — [guide](../guide/mcp-and-agents.md#logging-tool-calls--createtoollogger) |
24241
+ | `summarizeTransports` | function | mixed contract/runtime operation counts and per-source breakdown for a boot-time summary |
24242
+ | `buildToolManifest` | function | transport-aware searchable `{ name, description, inputSchema }` rows from a mixed surface |
24243
+ | `ToolLoggerConfig` | _type_ | config for `createToolLogger` |
24244
+ | `ToolCallRecord` | _type_ | the structured record `createToolLogger` passes to `onRecord` |
24245
+ | `TransportSummary` | _type_ | `{ contractServices, runtimeTools, totals, sources }` from `summarizeTransports` |
24246
+ | `TransportCounts` | _type_ | per-transport counts (`{ HTTP, MCP, AGENT, CLI }`) |
24247
+ | `ToolSurfaceProjection` | _type_ | the one readonly `{ services?, runtimeTools? }` container shared by full, MCP-only and introspection surfaces (`buildToolManifest`, `listToolNames`, `summarizeTransports` take `ToolSurfaceProjection<RuntimeToolDefinition>`) |
24248
+ | `ToolManifestConfig` | _type_ | mixed surface plus required model-facing `transport` and presentation options |
24249
+ | `coerceJsonArgs` | function | coerce JSON-stringified array/object tool arguments, including object guards restored from JSON Schema; arbitrary transform pipes stay untouched; throws a `ZodError` naming the field when a union that keeps a string member receives a string that parses to an array its array member accepts |
24250
+ | `flattenToolJsonSchema` | function | project structurally identifiable discriminated unions into conservative object joins; scalar collisions retain provable types, object/array collisions retain structural alternatives, and field descriptions retain discriminator labels plus availability/requiredness hints; the projection never executes validation |
24251
+ | `ToolPresentationSchema` | _type_ | immutable model-facing JSON Schema document shared by tool transports |
24252
+ | `MountableTool` | _type_ | one operation with separate executable CLI argument schema and model-facing presentation schema |
24253
+ | `ToolManifestEntry` | _type_ | one `buildToolManifest` row |
24254
+
24255
+ ---
24256
+
24257
+ ## `stitchkit/tools/mcp`
24258
+
24259
+ Server-only, and the one place the MCP server is exported. Its runtime and strict NodeNext
24260
+ declarations require Zod and the `@modelcontextprotocol/server` v2 peer, with no AI SDK peer;
24261
+ MCP hosts and tests use the separate `@modelcontextprotocol/client` package.
24262
+
24263
+ Framework-owned MCP tools advertise the exact declared output schema and return
24264
+ the validated value unchanged as `structuredContent`, including arrays, scalars
24265
+ and `null`. Tools without an output contract advertise and return no structured
24266
+ payload. See [MCP guide](../guide/mcp-and-agents.md#mcp--createmcphandler).
24267
+
24268
+ | Export | Kind | Purpose |
24269
+ |--------|------|---------|
24270
+ | `createMcpHandler` | function | a stateless dual-era Streamable-HTTP MCP handler — [guide](../guide/mcp-and-agents.md#mcp--createmcphandler) |
24271
+ | `createMcpHttpRoute` | function | framework-owned `RawRoute` adapter for an MCP HTTP handler |
24272
+ | `createStdioMcpServer` | function | a complete stdio MCP server — [guide](../guide/mcp-and-agents.md#mcp-over-stdio--createstdiomcpserver) |
24273
+ | `bindStdioProcessSignals` | function | explicitly bind OS signals to one close-only stdio handle — [guide](../guide/testing-and-deployment.md#stdio-process-signals) |
24274
+ | `buildMcpServer` | function | build an `McpServer` from contract/runtime surfaces; no-auth configs omit the second argument |
24275
+ | `mountMcp` | function | add contract tools to an existing `McpServer` — [guide](../guide/mcp-and-agents.md#mountmcp) |
24276
+ | `validateMcpSchemas` | function | object-shaped assertion over the exact advertised schema surface — compatibility, typed properties and portable formats ([guide](../guide/mcp-and-agents.md#mcp-schema-validation-profile)) |
24277
+ | `McpHandlerConfig` | _type_ | server surface plus stateless HTTP transport config |
24278
+ | `McpHttpConfig` | _type_ | HTTP auth, protected-resource, legacy-era and security options |
24279
+ | `McpHttpHandler` | _type_ | framework-owned `{ fetch(request), close() }` lifecycle |
24280
+ | `McpHttpSecurityConfig` | _type_ | Fetch-boundary Host and Origin allowlists |
24281
+ | `McpLegacyPolicy` | _type_ | `'serve' \| 'reject'` protocol-era compatibility policy |
24282
+ | `McpStdioHandle` | _type_ | closeable official stdio transport handle |
24283
+ | `StdioMcpServerConfig` | _type_ | config for `createStdioMcpServer` |
24284
+ | `StdioCloseTarget` | _type_ | minimal close-only target accepted by `bindStdioProcessSignals` |
24285
+ | `StdioProcessSignalsOptions` | _type_ | signal source, close callbacks and phased error reporting |
24286
+ | `StdioProcessSignalsBinding` | _type_ | close-only signal binding with observed `promise` and listener `close()` |
24287
+ | `StdioProcessSignalsErrorPhase` | _type_ | `'prepare' \| 'close' \| 'complete'` reporting phase |
24288
+ | `McpServerBuildConfig` | _type_ | shared config for `buildMcpServer` |
24289
+ | `McpServerSharedConfig` | _type_ | transport-neutral options shared by direct and finite surface configs |
24290
+ | `McpServer` | _type_ | official split-SDK server instance accepted by raw extension points |
24291
+ | `DirectMcpSurfaceConfig` | _type_ | static or identity-dynamic `services` / `runtimeTools` source |
24292
+ | `FiniteMcpSurfaceConfig` | _type_ | bounded `surfaces` registry plus typed selector |
24293
+ | `McpSurfaceDefinition` | _type_ | one immutable `{ services, runtimeTools }` MCP surface |
24294
+ | `McpSurfaceRegistry` | _type_ | finite keyed surface registry for eager preparation |
24295
+ | `StdioAuthConfig` | _type_ | startup identity composed into `StdioMcpServerConfig` |
24296
+ | `McpMountConfig` | _type_ | config for `mountMcp` |
24297
+ | `McpSchemaValidationConfig` | _type_ | shared `{ policy, requireTypedProperties, allowUntyped, requirePortableFormats, allowFormats }` profile |
24298
+ | `ValidateMcpSchemasConfig` | _type_ | standalone validation profile plus `services`, `extend`, flattening and logger |
24299
+ | `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
24300
+ | `RuntimeToolDefinitionWithOutput` / `RuntimeToolDefinitionWithoutOutput` | _type_ | the one neutral construction, shared with `stitchkit/cli` and `stitchkit/tools`; MCP-only presenters are its fourth type argument, `RuntimeMcpToolPresenters<z.output<typeof output>>` |
24301
+ | `RuntimeToolDefinition` | _type_ | heterogeneous registration; the canonical runner validates input/output before invocation |
24302
+ | `RuntimeMcpToolPresenters` / `RuntimeMcpPresentation` | _type_ | official SDK content without framework-owned `structuredContent` or `isError`; one presenter owner shared with the full SDK surface |
24303
+
24174
24304
  ### Catalog stamp
24175
24305
 
24176
24306
  Every advertised tool and every tool result carries the fingerprint of the catalog it came
@@ -24204,44 +24334,26 @@ Interactive MCP resources — [ADR 0019](../decisions/0019-generic-native-tools.
24204
24334
  | `McpAppResourceMeta` | _type_ | resource `_meta` for an MCP App |
24205
24335
  | `McpAppCsp` | _type_ | the widget content-security policy |
24206
24336
 
24207
- ### Introspection & internals
24337
+ ## `stitchkit/tools/agent`
24208
24338
 
24209
- Advanced building blocks — the shared machinery the mounts are built on.
24339
+ Server-only. A contract's operations as Vercel AI SDK tools; needs Zod and the `ai`
24340
+ peer, not the MCP server SDK. → ADR 0284.
24210
24341
 
24211
24342
  | Export | Kind | Summary |
24212
24343
  |--------|------|---------|
24213
- | `collectTools` | function | resolve a service's methods to mountable tools (the shared resolver) |
24214
- | `createToolLogger` | function | a ready `afterToolCall` that logs every tool call — [guide](../guide/mcp-and-agents.md#logging-tool-calls--createtoollogger) |
24215
- | `summarizeTransports` | function | mixed contract/runtime operation counts and per-source breakdown for a boot-time summary |
24216
- | `buildToolManifest` | function | transport-aware searchable `{ name, description, inputSchema }` rows from a mixed surface |
24217
- | `ToolLoggerConfig` | _type_ | config for `createToolLogger` |
24218
- | `ToolCallRecord` | _type_ | the structured record `createToolLogger` passes to `onRecord` |
24219
- | `TransportSummary` | _type_ | `{ contractServices, runtimeTools, totals, sources }` from `summarizeTransports` |
24220
- | `TransportCounts` | _type_ | per-transport counts (`{ HTTP, MCP, AGENT, CLI }`) |
24221
- | `ToolSurfaceProjection` | _type_ | the one readonly `{ services?, runtimeTools? }` container shared by full, MCP-only and introspection surfaces (`buildToolManifest`, `listToolNames`, `summarizeTransports` take `ToolSurfaceProjection<RuntimeToolDefinition>`) |
24222
- | `ToolManifestConfig` | _type_ | mixed surface plus required model-facing `transport` and presentation options |
24223
- | `coerceJsonArgs` | function | coerce JSON-stringified array/object tool arguments, including object guards restored from JSON Schema; arbitrary transform pipes stay untouched; throws a `ZodError` naming the field when a union that keeps a string member receives a string that parses to an array its array member accepts |
24224
- | `flattenToolJsonSchema` | function | project structurally identifiable discriminated unions into conservative object joins; scalar collisions retain provable types, object/array collisions retain structural alternatives, and field descriptions retain discriminator labels plus availability/requiredness hints; the projection never executes validation |
24225
- | `ToolPresentationSchema` | _type_ | immutable model-facing JSON Schema document shared by tool transports |
24226
- | `MountableTool` | _type_ | one operation with separate executable CLI argument schema and model-facing presentation schema |
24227
- | `ToolManifestEntry` | _type_ | one `buildToolManifest` row |
24228
-
24229
- ---
24344
+ | `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service; failed executions reject through the SDK tool-error channel with a safe typed envelope, while successful output is never classified by field name — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
24345
+ | `AgentMountConfig` | _type_ | config for `mountAgent` |
24346
+ | `AgentContext` | _type_ | the context merged into agent tool handlers |
24230
24347
 
24231
- ## `stitchkit/tools/mcp`
24348
+ ## `stitchkit/tools/toolkit`
24232
24349
 
24233
- A server-only leaf over the same MCP owner as `stitchkit/tools`. Its runtime and strict
24234
- NodeNext declarations require Zod and `@modelcontextprotocol/server`, with no AI SDK peer.
24235
- HTTP/stdio factories, mounts, schema policy, catalog and resource helpers keep their canonical
24236
- behavior and names. See [MCP guide](../guide/mcp-and-agents.md#mcp--createmcphandler).
24350
+ Server-only. One context-typed tool set served over MCP and to an AI SDK agent, so it
24351
+ needs both the `@modelcontextprotocol/server` and `ai` peers. → ADR 0284.
24237
24352
 
24238
- | Export | Kind | Purpose |
24353
+ | Export | Kind | Summary |
24239
24354
  |--------|------|---------|
24240
- | `createMcpHandler` / `createMcpHttpRoute` / `buildMcpServer` / `mountMcp` | function | the shared authenticated HTTP handler, raw-route adapter, SDK server and contract mount |
24241
- | `createStdioMcpServer` / `bindStdioProcessSignals` | function | the shared stdio server and bounded process cleanup |
24242
- | `RuntimeToolDefinitionWithOutput` / `RuntimeToolDefinitionWithoutOutput` | _type_ | the one neutral construction, shared with `stitchkit/cli` and `stitchkit/tools`; MCP-only presenters are its fourth type argument, `RuntimeMcpToolPresenters<z.output<typeof output>>` |
24243
- | `RuntimeToolDefinition` | _type_ | heterogeneous registration; the canonical runner validates input/output before invocation |
24244
- | `RuntimeMcpToolPresenters` / `RuntimeMcpPresentation` | _type_ | official SDK content without framework-owned `structuredContent` or `isError`; one presenter owner shared with the full SDK surface |
24355
+ | `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
24356
+ | `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
24245
24357
 
24246
24358
  ## `stitchkit/tools/connections`
24247
24359