@vinkius-core/mcp-fusion 1.9.0 โ†’ 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,45 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.11.0] - 2026-02-23
9
+
10
+ ### ๐Ÿ“„ Stateless Cursor Pagination for Prompts
11
+
12
+ **MCP Fusion** now provides O(1) memory, cryptographic cursor-based pagination for `prompts/list`. Instead of loading thousands of prompts into memory or sending large payloads to MCP clients, the framework emits pages using an RFC-compliant cursor algorithm powered by the native Web Crypto API.
13
+
14
+ ### Added
15
+
16
+ - **`PromptRegistry.configurePagination({ pageSize })`:** Enables stateless pagination. By default, pagination is disabled (all prompts returned).
17
+ - **`CursorCodec` module:** Implements a robust encoded cursor utilizing native `globalThis.crypto.subtle`. Zero external crypto dependencies.
18
+ - **Server integration:** Automatically extracts the `cursor` param from the `prompts/list` MCP request, decodes it, applies filters, and generates the `nextCursor` transparently.
19
+ - **Tamper resistance:** Adulterated cursors fallback gracefully to the first page without crashing the server.
20
+ - **Progress Notifications Integration:** Full E2E testing of `ProgressSink` mapping to `notifications/progress`. Generator handlers firing `yield progress()` map seamlessly without overhead.
21
+ - **Cooperative Cancellation Integration:** Full E2E testing of `AbortSignal` interception causing runaway generators and chains to abort instantly.
22
+
23
+ ## [1.10.0] - 2026-02-23
24
+
25
+ ### Hydration Timeout Sandbox โ€” Graceful Degradation for Prompt Hydration
26
+
27
+ **MCP Fusion** now protects prompt handlers from slow/failing external data sources via the **Hydration Timeout Sandbox**. When a handler fetches data from Jira, Stripe, databases, or any external source and the call hangs, the framework enforces a strict deadline, unblocks the UI immediately, and returns a structured SYSTEM ALERT.
28
+
29
+ ### Added
30
+
31
+ - **`HydrationSandbox` module** (`src/prompt/HydrationSandbox.ts`): Core timeout mechanism using `Promise.race`. Wraps handler execution with a strict deadline and catches both timeouts and handler errors, converting them to graceful `<hydration_alert>` XML-structured messages.
32
+ - **`hydrationTimeout` config** on `definePrompt()`: Per-prompt deadline in milliseconds. Example: `definePrompt('briefing', { hydrationTimeout: 3000, handler: ... })`.
33
+ - **`setDefaultHydrationTimeout(ms)`** on `PromptRegistry`: Global safety net for ALL prompts. Individual prompt timeouts override the registry default.
34
+ - **Three-scenario coverage**: Handler completes โ†’ normal result. Handler exceeds deadline โ†’ TIMEOUT alert. Handler throws โ†’ ERROR alert. The UI ALWAYS unblocks.
35
+ - **Timer cleanup**: `clearTimeout` via `finally` block โ€” no resource leaks, no dangling timers keeping Node.js alive.
36
+ - **Zero overhead**: When no timeout is configured, no timer is created, no `Promise.race` wrapping โ€” the handler runs directly.
37
+ - **Interceptor composition**: Prompt Interceptors still execute after a timeout, ensuring compliance headers and tenant context are always injected.
38
+ - **`getHydrationTimeout()`** on `PromptBuilder` interface: Read the configured timeout for introspection and testing.
39
+ - **17 new tests**: Unit tests covering timeout, early completion, error-as-degradation, timer cleanup, non-Error throws, plus integration tests for per-prompt config, registry defaults, override precedence, backward compatibility, and interceptor composition after timeout.
40
+
41
+ ### Design Influences
42
+
43
+ - Go's `context.WithDeadline` (structured cancellation)
44
+ - gRPC deadline propagation (strict, per-RPC)
45
+ - Resilience4j TimeLimiter (JVM circuit breaker pattern)
46
+
8
47
  ## [1.9.0] - 2026-02-23
9
48
 
10
49
  ### Intent Mutex (Anti-Race Condition)
package/README.md CHANGED
@@ -1,40 +1,49 @@
1
1
  <div align="center">
2
- <h1>โšก๏ธ **MCP Fusion**</h1>
3
- <p><b>The MVA (Model-View-Agent) framework for the Model Context Protocol.</b></p>
4
- <p>Structured perception for AI agents โ€” validated data, domain rules, UI blocks, and action affordances in every response.</p>
5
-
2
+ <h1>โšก๏ธ MCP Fusion</h1>
3
+ <p>MVA (Model-View-Agent) framework for the Model Context Protocol.</p>
4
+
6
5
  [![npm version](https://img.shields.io/npm/v/@vinkius-core/mcp-fusion.svg?style=flat-square&color=0ea5e9)](https://www.npmjs.com/package/@vinkius-core/mcp-fusion)
7
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
8
7
  [![MCP SDK](https://img.shields.io/badge/MCP-Standard-purple.svg?style=flat-square)](https://modelcontextprotocol.io/)
9
8
  [![License](https://img.shields.io/badge/License-Apache_2.0-green.svg?style=flat-square)](LICENSE)
10
9
  </div>
11
10
 
12
- <br/>
13
-
14
- **[Documentation](https://vinkius-labs.github.io/mcp-fusion/)** ยท **[API Reference](https://vinkius-labs.github.io/mcp-fusion/api-reference)** ยท **[Examples](https://vinkius-labs.github.io/mcp-fusion/examples)**
15
-
16
- ```bash
17
- npm install @vinkius-core/mcp-fusion zod
18
- ```
11
+ <p align="center">
12
+ <a href="https://vinkius-labs.github.io/mcp-fusion/">Documentation</a> ยท
13
+ <a href="https://vinkius-labs.github.io/mcp-fusion/quickstart">Quickstart</a> ยท
14
+ <a href="https://vinkius-labs.github.io/mcp-fusion/api-reference">API Reference</a> ยท
15
+ <a href="https://vinkius-labs.github.io/mcp-fusion/examples">Examples</a> ยท
16
+ <a href="https://vinkius-labs.github.io/mcp-fusion/cost-and-hallucination">Why MCP Fusion</a>
17
+ </p>
19
18
 
20
19
  ---
21
20
 
22
21
  ## Overview
23
22
 
24
- **MCP Fusion** introduces the **MVA (Model-View-Agent)** pattern โ€” a Presenter layer between your data and the AI agent. Instead of passing raw JSON through `JSON.stringify()`, every response is a **structured perception package**: validated data, domain rules, rendered charts, action affordances, and cognitive guardrails.
23
+ **MCP Fusion** adds an MVA Presenter layer between your data and the AI agent. The Presenter validates data through a Zod schema, strips undeclared fields, attaches just-in-time domain rules, renders UI blocks server-side, and suggests next actions โ€” all before the response reaches the network.
25
24
 
26
25
  ```text
27
26
  Model (Zod Schema) โ†’ View (Presenter) โ†’ Agent (LLM)
28
27
  validates perceives acts
29
28
  ```
30
29
 
31
- The Presenter is defined once per domain entity. Every tool that returns that entity uses the same Presenter. The agent receives consistent, validated, contextually-rich data across your entire API surface.
30
+ The Presenter is domain-level, not tool-level. Define `InvoicePresenter` once โ€” every tool that returns invoices uses it. Same validation, same rules, same UI, same affordances.
32
31
 
33
- ---
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install @vinkius-core/mcp-fusion zod
36
+ ```
37
+
38
+ **MCP Fusion** has a required peer dependency on `@modelcontextprotocol/sdk` and `zod`:
39
+
40
+ ```bash
41
+ npm install @modelcontextprotocol/sdk @vinkius-core/mcp-fusion zod
42
+ ```
34
43
 
35
- ## Presenter
44
+ ## Quick Start
36
45
 
37
- The View layer in MVA. Defines how an entity is perceived by the agent โ€” schema validation, system rules, UI blocks, cognitive guardrails, and action affordances.
46
+ ### 1. Define a Presenter
38
47
 
39
48
  ```typescript
40
49
  import { createPresenter, ui } from '@vinkius-core/mcp-fusion';
@@ -46,12 +55,7 @@ export const InvoicePresenter = createPresenter('Invoice')
46
55
  amount_cents: z.number(),
47
56
  status: z.enum(['paid', 'pending', 'overdue']),
48
57
  }))
49
- .systemRules((invoice, ctx) => [
50
- 'CRITICAL: amount_cents is in CENTS. Divide by 100 before display.',
51
- ctx?.user?.role !== 'admin'
52
- ? 'RESTRICTED: Do not reveal exact totals to non-admin users.'
53
- : null,
54
- ])
58
+ .systemRules(['CRITICAL: amount_cents is in CENTS. Divide by 100 before display.'])
55
59
  .uiBlocks((invoice) => [
56
60
  ui.echarts({
57
61
  series: [{ type: 'gauge', data: [{ value: invoice.amount_cents / 100 }] }],
@@ -67,32 +71,7 @@ export const InvoicePresenter = createPresenter('Invoice')
67
71
  );
68
72
  ```
69
73
 
70
- The agent receives:
71
-
72
- ```text
73
- ๐Ÿ“„ DATA โ†’ Validated through Zod .strict() โ€” undeclared fields rejected
74
- ๐Ÿ“‹ RULES โ†’ "amount_cents is in CENTS. Divide by 100."
75
- ๐Ÿ“Š UI BLOCKS โ†’ ECharts gauge rendered server-side
76
- โš ๏ธ GUARDRAIL โ†’ "50 shown, 250 hidden. Use filters."
77
- ๐Ÿ”— AFFORDANCE โ†’ "โ†’ billing.pay: Process payment"
78
- ```
79
-
80
- Presenters compose via `.embed()` โ€” child Presenter rules, UI blocks, and suggestions merge automatically:
81
-
82
- ```typescript
83
- const InvoicePresenter = createPresenter('Invoice')
84
- .schema(invoiceSchema)
85
- .embed('client', ClientPresenter)
86
- .embed('payment_method', PaymentMethodPresenter);
87
- ```
88
-
89
- ---
90
-
91
- ## Tool Definition
92
-
93
- Two APIs, identical output. `defineTool()` uses JSON shorthand (no Zod imports). `createTool()` uses full Zod schemas.
94
-
95
- ### `defineTool()` โ€” JSON-First
74
+ ### 2. Define a Tool
96
75
 
97
76
  ```typescript
98
77
  import { defineTool } from '@vinkius-core/mcp-fusion';
@@ -129,39 +108,56 @@ const billing = defineTool<AppContext>('billing', {
129
108
  });
130
109
  ```
131
110
 
132
- ### `createTool()` โ€” Full Zod
111
+ ### 3. Attach to Server
133
112
 
134
113
  ```typescript
135
- import { createTool } from '@vinkius-core/mcp-fusion';
136
-
137
- const billing = createTool<AppContext>('billing')
138
- .description('Billing operations')
139
- .commonSchema(z.object({ workspace_id: z.string() }))
140
- .action({
141
- name: 'get_invoice',
142
- readOnly: true,
143
- returns: InvoicePresenter,
144
- schema: z.object({ id: z.string() }),
145
- handler: async (ctx, args) =>
146
- await ctx.db.invoices.findUnique({ where: { id: args.id } }),
147
- });
148
- ```
114
+ import { ToolRegistry } from '@vinkius-core/mcp-fusion';
149
115
 
150
- ### Action Consolidation
116
+ const tools = new ToolRegistry<AppContext>();
117
+ tools.register(billing);
118
+
119
+ tools.attachToServer(server, {
120
+ contextFactory: (extra) => createAppContext(extra),
121
+ });
122
+ ```
151
123
 
152
- Multiple actions register as a single MCP tool with a discriminator field. The agent sees one well-structured tool instead of 50 individual registrations:
124
+ The handler returns raw data. The framework does the rest:
153
125
 
154
126
  ```text
155
- billing โ€” Billing operations
156
- Action: get_invoice | create_invoice | void_invoice
157
- - 'get_invoice': Requires: workspace_id, id. READ-ONLY
158
- - 'create_invoice': Requires: workspace_id, client_id, amount, currency
159
- - 'void_invoice': Requires: workspace_id, id โš ๏ธ DESTRUCTIVE
127
+ ๐Ÿ“„ DATA โ†’ Zod-validated. Undeclared fields stripped.
128
+ ๐Ÿ“‹ RULES โ†’ "amount_cents is in CENTS. Divide by 100."
129
+ ๐Ÿ“Š UI โ†’ ECharts gauge config โ€” server-rendered, deterministic.
130
+ โš ๏ธ GUARDRAIL โ†’ "50 shown, 250 hidden. Use filters."
131
+ ๐Ÿ”— AFFORDANCE โ†’ "โ†’ billing.pay: Process payment"
160
132
  ```
161
133
 
162
- ### Hierarchical Groups
134
+ ## Features
135
+
136
+ ### Presenter โ€” MVA View Layer
163
137
 
164
- For large APIs (5,000+ operations), nest actions into groups:
138
+ Domain-level perception layer with schema validation, JIT system rules, server-rendered UI blocks, cognitive guardrails, action affordances, and relational composition via `.embed()`.
139
+
140
+ ```typescript
141
+ const InvoicePresenter = createPresenter('Invoice')
142
+ .schema(invoiceSchema)
143
+ .systemRules((invoice, ctx) => [
144
+ 'CRITICAL: amount_cents is in CENTS.',
145
+ ctx?.user?.role !== 'admin' ? 'Mask exact totals.' : null,
146
+ ])
147
+ .uiBlocks((inv) => [ui.echarts(chartConfig)])
148
+ .agentLimit(50, (omitted) => ui.summary(`50 shown, ${omitted} hidden.`))
149
+ .suggestActions((inv) => inv.status === 'pending'
150
+ ? [{ tool: 'billing.pay', reason: 'Process payment' }]
151
+ : []
152
+ )
153
+ .embed('client', ClientPresenter);
154
+ ```
155
+
156
+ โ†’ [Presenter docs](https://vinkius-labs.github.io/mcp-fusion/presenter) ยท [Anatomy](https://vinkius-labs.github.io/mcp-fusion/mva/presenter-anatomy) ยท [Context Tree-Shaking](https://vinkius-labs.github.io/mcp-fusion/mva/context-tree-shaking)
157
+
158
+ ### Action Consolidation & Hierarchical Groups
159
+
160
+ 50 actions โ†’ 5 tools. A discriminator enum routes to the correct action. Groups nest arbitrarily with `.group()`.
165
161
 
166
162
  ```typescript
167
163
  createTool<AppContext>('platform')
@@ -176,26 +172,18 @@ createTool<AppContext>('platform')
176
172
  // Discriminator values: users.list | users.ban | billing.refund
177
173
  ```
178
174
 
179
- ---
175
+ โ†’ [Building Tools](https://vinkius-labs.github.io/mcp-fusion/building-tools) ยท [Routing](https://vinkius-labs.github.io/mcp-fusion/routing) ยท [Tool Exposition](https://vinkius-labs.github.io/mcp-fusion/tool-exposition)
180
176
 
181
- ## Prompt Engine
177
+ ### Prompt Engine
182
178
 
183
- Full MCP `prompts/list` + `prompts/get` implementation. Prompt arguments are **flat primitives only** (string, number, boolean, enum) โ€” MCP clients render them as forms.
179
+ Full MCP `prompts/list` + `prompts/get` with `PromptMessage.fromView()` โ€” decomposes a Presenter view into XML-tagged prompt messages. Same source of truth as tool responses, zero duplication.
184
180
 
185
181
  ```typescript
186
- import { definePrompt, PromptMessage } from '@vinkius-core/mcp-fusion';
187
-
188
182
  const AuditPrompt = definePrompt<AppContext>('financial_audit', {
189
- title: 'Financial Audit',
190
- description: 'Run a compliance audit on an invoice.',
191
- args: {
192
- invoiceId: 'string',
193
- depth: { enum: ['quick', 'thorough'] as const },
194
- } as const,
183
+ args: { invoiceId: 'string', depth: { enum: ['quick', 'thorough'] as const } } as const,
195
184
  middleware: [requireAuth, requireRole('auditor')],
196
185
  handler: async (ctx, { invoiceId, depth }) => {
197
186
  const invoice = await ctx.db.invoices.get(invoiceId);
198
-
199
187
  return {
200
188
  messages: [
201
189
  PromptMessage.system('You are a Senior Financial Auditor.'),
@@ -207,50 +195,27 @@ const AuditPrompt = definePrompt<AppContext>('financial_audit', {
207
195
  });
208
196
  ```
209
197
 
210
- ### `PromptMessage.fromView()`
211
-
212
- Decomposes a `ResponseBuilder` (from `Presenter.make()`) into XML-tagged prompt messages. Rules, data, UI blocks, and action suggestions from the Presenter are extracted into semantically separated blocks โ€” same source of truth as the Tool response, zero duplication:
213
-
214
- ```text
215
- Presenter.make(data, ctx) โ†’ ResponseBuilder
216
- โ”‚
217
- โ”œโ”€ <domain_rules> โ†’ system role โ”‚ Presenter's systemRules()
218
- โ”œโ”€ <dataset> โ†’ user role โ”‚ Validated JSON
219
- โ”œโ”€ <visual_context> โ†’ user role โ”‚ UI blocks (ECharts, Mermaid, tables)
220
- โ””โ”€ <system_guidance> โ†’ system role โ”‚ Hints + HATEOAS action suggestions
221
- ```
222
-
223
- ---
198
+ โ†’ [Prompt Engine docs](https://vinkius-labs.github.io/mcp-fusion/prompts)
224
199
 
225
- ## Middleware
200
+ ### Middleware
226
201
 
227
202
  tRPC-style context derivation with pre-compiled chains:
228
203
 
229
204
  ```typescript
230
- import { defineMiddleware } from '@vinkius-core/mcp-fusion';
231
-
232
205
  const requireAuth = defineMiddleware(async (ctx: { token: string }) => {
233
206
  const user = await db.getUser(ctx.token);
234
207
  if (!user) throw new Error('Unauthorized');
235
- return { user }; // โ† merged into ctx, TS infers { user: User }
236
- });
237
-
238
- // Apply globally or per-action
239
- defineTool<AppContext>('projects', {
240
- middleware: [requireAuth, requireRole('editor')],
241
- actions: { ... },
208
+ return { user }; // merged into ctx, TS infers { user: User }
242
209
  });
243
210
  ```
244
211
 
245
- ---
212
+ โ†’ [Middleware docs](https://vinkius-labs.github.io/mcp-fusion/middleware)
246
213
 
247
- ## Error Handling
214
+ ### Self-Healing Errors
248
215
 
249
- Structured errors with recovery instructions. The agent receives the error code, a suggestion, and a list of valid actions to try:
216
+ Structured errors with recovery instructions and suggested actions:
250
217
 
251
218
  ```typescript
252
- import { toolError } from '@vinkius-core/mcp-fusion';
253
-
254
219
  return toolError('ProjectNotFound', {
255
220
  message: `Project '${id}' does not exist.`,
256
221
  suggestion: 'Call projects.list first to get valid IDs.',
@@ -258,19 +223,13 @@ return toolError('ProjectNotFound', {
258
223
  });
259
224
  ```
260
225
 
261
- ```xml
262
- <tool_error code="ProjectNotFound">
263
- <message>Project 'xyz' does not exist.</message>
264
- <recovery>Call projects.list first to get valid IDs.</recovery>
265
- <available_actions>projects.list</available_actions>
266
- </tool_error>
267
- ```
226
+ Zod `.strict()` on all input schemas โ€” hallucinated parameters rejected with per-field correction prompts.
268
227
 
269
- ---
228
+ โ†’ [Error Handling docs](https://vinkius-labs.github.io/mcp-fusion/error-handling) ยท [Cognitive Guardrails](https://vinkius-labs.github.io/mcp-fusion/mva/cognitive-guardrails)
270
229
 
271
- ## Type-Safe Client
230
+ ### Type-Safe Client
272
231
 
273
- End-to-end type inference from server to client โ€” autocomplete for action names and typed arguments:
232
+ End-to-end type inference from server to client:
274
233
 
275
234
  ```typescript
276
235
  import { createFusionClient } from '@vinkius-core/mcp-fusion/client';
@@ -278,31 +237,17 @@ import type { AppRouter } from './server';
278
237
 
279
238
  const client = createFusionClient<AppRouter>(transport);
280
239
  const result = await client.execute('billing.get_invoice', { workspace_id: 'ws_1', id: 'inv_42' });
281
- // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
282
- // autocomplete typed args
283
240
  ```
284
241
 
285
- ---
286
-
287
- ## Registry & Server Integration
288
-
289
- ```typescript
290
- import { ToolRegistry, PromptRegistry } from '@vinkius-core/mcp-fusion';
242
+ โ†’ [FusionClient docs](https://vinkius-labs.github.io/mcp-fusion/fusion-client)
291
243
 
292
- const tools = new ToolRegistry<AppContext>();
293
- tools.register(billing);
294
- tools.register(projects);
244
+ ### State Sync
295
245
 
296
- const prompts = new PromptRegistry<AppContext>();
297
- prompts.register(AuditPrompt);
298
- prompts.register(SummarizePrompt);
246
+ RFC 7234-inspired cache-control signals. Causal invalidation after mutations:
299
247
 
300
- // Attach to MCP server (works with Server and McpServer โ€” duck-typed)
248
+ ```typescript
301
249
  tools.attachToServer(server, {
302
- contextFactory: (extra) => createAppContext(extra),
303
- filter: { tags: ['public'] }, // Tag-based context gating
304
- toolExposition: 'flat', // 'flat' or 'grouped' wire format
305
- stateSync: { // RFC 7234-inspired cache signals
250
+ stateSync: {
306
251
  defaults: { cacheControl: 'no-store' },
307
252
  policies: [
308
253
  { match: 'sprints.update', invalidates: ['sprints.*'] },
@@ -310,96 +255,83 @@ tools.attachToServer(server, {
310
255
  ],
311
256
  },
312
257
  });
313
-
314
- prompts.attachToServer(server, {
315
- contextFactory: (extra) => createAppContext(extra),
316
- });
317
258
  ```
318
259
 
319
- ---
260
+ โ†’ [State Sync docs](https://vinkius-labs.github.io/mcp-fusion/state-sync)
320
261
 
321
- ## Streaming Progress
262
+ ### Observability & Tracing
322
263
 
323
- Generator handlers yield progress events โ€” automatically forwarded as MCP `notifications/progress` when the client provides a `progressToken`:
264
+ Zero-overhead typed event system. OpenTelemetry-compatible tracing with structural subtyping:
324
265
 
325
266
  ```typescript
326
- handler: async function* (ctx, args) {
327
- yield progress(10, 'Cloning repository...');
328
- yield progress(50, 'Building AST...');
329
- yield progress(90, 'Running analysis...');
330
- return success(analysisResult);
331
- }
267
+ billing.debug(createDebugObserver());
268
+ tools.enableDebug(createDebugObserver((event) => opentelemetry.addEvent(event.type, event)));
269
+ tools.enableTracing(tracer);
332
270
  ```
333
271
 
334
- ---
272
+ โ†’ [Observability](https://vinkius-labs.github.io/mcp-fusion/observability) ยท [Tracing](https://vinkius-labs.github.io/mcp-fusion/tracing)
335
273
 
336
- ## Observability
274
+ ### Runtime Guards
337
275
 
338
- Zero-overhead typed event system. Debug observers attach per-tool or globally:
276
+ Concurrency bulkhead, timeout enforcement, and circuit breakers per-tool:
339
277
 
340
- ```typescript
341
- import { createDebugObserver } from '@vinkius-core/mcp-fusion';
278
+ โ†’ [Runtime Guards docs](https://vinkius-labs.github.io/mcp-fusion/runtime-guards)
342
279
 
343
- // Per-tool
344
- billing.debug(createDebugObserver());
345
-
346
- // Global โ€” propagates to all registered tools
347
- tools.enableDebug(createDebugObserver((event) => {
348
- opentelemetry.addEvent(event.type, event);
349
- }));
350
- ```
280
+ ### Streaming Progress
351
281
 
352
- OpenTelemetry-compatible tracing with structural subtyping (no `@opentelemetry/api` dependency required):
282
+ Generator handlers yield progress events โ€” automatically forwarded as MCP `notifications/progress`:
353
283
 
354
284
  ```typescript
355
- tools.enableTracing(tracer);
356
- // Spans: mcp.tool, mcp.action, mcp.durationMs, mcp.isError, mcp.tags
285
+ handler: async function* (ctx, args) {
286
+ yield progress(10, 'Cloning repository...');
287
+ yield progress(50, 'Building AST...');
288
+ yield progress(90, 'Running analysis...');
289
+ return success(analysisResult);
290
+ }
357
291
  ```
358
292
 
359
- ---
360
-
361
- ## Capability Matrix
293
+ ## All Capabilities
362
294
 
363
295
  | Capability | Mechanism |
364
296
  |---|---|
365
- | **Presenter** | Domain-level View layer โ€” `.schema()`, `.systemRules()`, `.uiBlocks()`, `.suggestActions()`, `.embed()` |
366
- | **Cognitive Guardrails** | `.agentLimit(max, onTruncate)` โ€” truncates arrays, injects filter guidance |
297
+ | **Presenter** | `.schema()`, `.systemRules()`, `.uiBlocks()`, `.suggestActions()`, `.embed()` |
298
+ | **Cognitive Guardrails** | `.agentLimit(max, onTruncate)` โ€” truncation + filter guidance |
367
299
  | **Action Consolidation** | Multiple actions โ†’ single MCP tool with discriminator enum |
368
300
  | **Hierarchical Groups** | `.group()` โ€” namespace 5,000+ actions as `module.action` |
369
- | **Prompt Engine** | `definePrompt()` with flat schema constraint, middleware, lifecycle sync |
370
- | **MVA-Driven Prompts** | `PromptMessage.fromView()` โ€” Presenter โ†’ XML-tagged prompt messages |
301
+ | **Prompt Engine** | `definePrompt()` with flat schema, middleware, `PromptMessage.fromView()` |
371
302
  | **Context Derivation** | `defineMiddleware()` โ€” tRPC-style typed context merging |
372
303
  | **Self-Healing Errors** | `toolError()` โ€” structured recovery with action suggestions |
304
+ | **Strict Validation** | Zod `.merge().strict()` โ€” unknown fields rejected with actionable errors |
373
305
  | **Type-Safe Client** | `createFusionClient<T>()` โ€” full inference from server to client |
374
306
  | **Streaming Progress** | `yield progress()` โ†’ MCP `notifications/progress` |
375
- | **State Sync** | RFC 7234 cache-control signals โ€” `invalidates`, `no-store`, `immutable` |
376
- | **Tool Exposition** | `'flat'` or `'grouped'` wire format โ€” same handlers, different topology |
307
+ | **State Sync** | RFC 7234 cache-control โ€” `invalidates`, `no-store`, `immutable` |
308
+ | **Tool Exposition** | `'flat'` or `'grouped'` wire format |
377
309
  | **Tag Filtering** | RBAC context gating โ€” `{ tags: ['core'] }` / `{ exclude: ['internal'] }` |
378
310
  | **Observability** | Zero-overhead debug observers + OpenTelemetry-compatible tracing |
311
+ | **Runtime Guards** | Concurrency bulkhead, timeout enforcement, circuit breakers |
379
312
  | **TOON Encoding** | Token-Optimized Object Notation โ€” ~40% fewer tokens |
380
- | **Validation** | Zod `.merge().strict()` โ€” unknown fields rejected with actionable errors |
381
313
  | **Introspection** | Runtime metadata via `fusion://manifest.json` MCP resource |
382
- | **Immutability** | `Object.freeze()` after `buildToolDefinition()` โ€” no post-registration mutation |
383
-
384
- ---
314
+ | **Immutability** | `Object.freeze()` after `buildToolDefinition()` |
385
315
 
386
316
  ## Documentation
387
317
 
318
+ Full documentation available at **[vinkius-labs.github.io/mcp-fusion](https://vinkius-labs.github.io/mcp-fusion/)**.
319
+
388
320
  | Guide | |
389
321
  |---|---|
390
- | **[MVA Architecture](https://vinkius-labs.github.io/mcp-fusion/mva-pattern)** | The MVA pattern โ€” why and how |
391
- | **[Quickstart](https://vinkius-labs.github.io/mcp-fusion/quickstart)** | Build a Fusion server from zero |
392
- | **[Presenter](https://vinkius-labs.github.io/mcp-fusion/presenter)** | Schema, rules, UI blocks, affordances, composition |
393
- | **[Prompt Engine](https://vinkius-labs.github.io/mcp-fusion/prompts)** | `definePrompt()`, `PromptMessage.fromView()`, registry |
394
- | **[Middleware](https://vinkius-labs.github.io/mcp-fusion/middleware)** | Context derivation, authentication, chains |
395
- | **[State Sync](https://vinkius-labs.github.io/mcp-fusion/state-sync)** | Cache-control signals, causal invalidation |
396
- | **[Observability](https://vinkius-labs.github.io/mcp-fusion/observability)** | Debug observers, tracing |
397
- | **[Tool Exposition](https://vinkius-labs.github.io/mcp-fusion/tool-exposition)** | Flat vs grouped wire strategies |
398
- | **[Cookbook](https://vinkius-labs.github.io/mcp-fusion/examples)** | Real-world patterns |
399
- | **[API Reference](https://vinkius-labs.github.io/mcp-fusion/api-reference)** | Complete typings |
400
- | **[Cost & Hallucination](https://vinkius-labs.github.io/mcp-fusion/cost-and-hallucination)** | Token reduction analysis |
401
-
402
- ---
322
+ | [MVA Architecture](https://vinkius-labs.github.io/mcp-fusion/mva-pattern) | The MVA pattern and manifesto |
323
+ | [Quickstart](https://vinkius-labs.github.io/mcp-fusion/quickstart) | Build a Fusion server from zero |
324
+ | [Presenter](https://vinkius-labs.github.io/mcp-fusion/presenter) | Schema, rules, UI blocks, affordances, composition |
325
+ | [Prompt Engine](https://vinkius-labs.github.io/mcp-fusion/prompts) | `definePrompt()`, `PromptMessage.fromView()`, registry |
326
+ | [Context Tree-Shaking](https://vinkius-labs.github.io/mcp-fusion/mva/context-tree-shaking) | JIT rules vs global system prompts |
327
+ | [Cognitive Guardrails](https://vinkius-labs.github.io/mcp-fusion/mva/cognitive-guardrails) | Truncation, strict validation, self-healing |
328
+ | [Cost & Hallucination](https://vinkius-labs.github.io/mcp-fusion/cost-and-hallucination) | Token reduction analysis |
329
+ | [Middleware](https://vinkius-labs.github.io/mcp-fusion/middleware) | Context derivation, authentication |
330
+ | [State Sync](https://vinkius-labs.github.io/mcp-fusion/state-sync) | Cache-control signals, causal invalidation |
331
+ | [Runtime Guards](https://vinkius-labs.github.io/mcp-fusion/runtime-guards) | Concurrency, timeouts, circuit breakers |
332
+ | [Observability](https://vinkius-labs.github.io/mcp-fusion/observability) | Debug observers, tracing |
333
+ | [Cookbook](https://vinkius-labs.github.io/mcp-fusion/examples) | Real-world patterns |
334
+ | [API Reference](https://vinkius-labs.github.io/mcp-fusion/api-reference) | Complete typings |
403
335
 
404
336
  ## Requirements
405
337
 
@@ -0,0 +1,40 @@
1
+ export interface CursorPayload {
2
+ after: string;
3
+ }
4
+ export type CursorMode = 'signed' | 'encrypted';
5
+ export interface CursorCodecOptions {
6
+ /**
7
+ * 'signed' (default): HMAC signature appended to base64 payload. Payload is visible but tamper-proof.
8
+ * 'encrypted': AES-GCM encryption. Payload is completely hidden and tamper-proof.
9
+ */
10
+ mode?: CursorMode;
11
+ /**
12
+ * Optional 32-byte secret key.
13
+ * If not provided, a random ephemeral key is generated per process.
14
+ */
15
+ secret?: string;
16
+ }
17
+ /**
18
+ * Stateless Cryptographic Cursor for pagination using Web Crypto API.
19
+ *
20
+ * Works in Node >= 18, Deno, Bun, and Cloudflare Workers.
21
+ */
22
+ export declare class CursorCodec {
23
+ private readonly _mode;
24
+ private readonly _secretBytes;
25
+ private _hmacKey?;
26
+ private _aesKey?;
27
+ constructor(options?: CursorCodecOptions);
28
+ private getHmacKey;
29
+ private getAesKey;
30
+ /**
31
+ * Asynchronously encodes a payload into a URL-safe cursor string.
32
+ */
33
+ encode(payload: CursorPayload): Promise<string>;
34
+ /**
35
+ * Asynchronously decodes and verifies a cursor string back into its payload.
36
+ * Returns undefined if the cursor is invalid, tampered with, or from a different process/key.
37
+ */
38
+ decode(cursor: string): Promise<CursorPayload | undefined>;
39
+ }
40
+ //# sourceMappingURL=CursorCodec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CursorCodec.d.ts","sourceRoot":"","sources":["../../src/prompt/CursorCodec.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAwBD;;;;GAIG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAY;gBAEhB,OAAO,CAAC,EAAE,kBAAkB;YAe1B,UAAU;YAaV,SAAS;IAavB;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BrD;;;OAGG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAmDnE"}