@vinkius-core/mcp-fusion 1.5.0 โ†’ 1.6.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
@@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file.
4
4
 
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
+ ## [1.6.0] - 2026-02-23
8
+
9
+ ### ๐Ÿ”— MVA-Driven Prompts โ€” `PromptMessage.fromView()`
10
+
11
+ Bridge the Presenter layer into the Prompt Engine with zero duplication. `PromptMessage.fromView()` decomposes a `ResponseBuilder` into XML-tagged prompt messages (`<domain_rules>`, `<dataset>`, `<visual_context>`, `<system_guidance>`) โ€” same source of truth as the Tool response.
12
+
13
+ ### Added
14
+
15
+ - **`PromptMessage.fromView(builder)`:** Static method that decomposes a `ResponseBuilder` into `PromptMessagePayload[]`. Extracts rules, validated data, UI blocks, hints, and action suggestions into semantically separated XML-tagged blocks optimized for frontier LLMs.
16
+ - **`ResponseBuilder` introspection getters:** `getData()`, `getRules()`, `getUiBlocks()`, `getHints()`, `getSuggestions()` โ€” read-only access to internal layers without calling `.build()`.
17
+
18
+ ### Documentation
19
+
20
+ - **`prompts.md`:** New H2 section "MVA-Driven Prompts โ€” `fromView()`" with Before/After comparison, decomposition architecture diagram, XML tag table, composability example.
21
+ - **`presenter.md`:** New section "Using Presenters in Prompts" with cross-reference to Prompt Engine docs. Added Prompt Engine link to Next Steps.
22
+ - **`api-reference.md`:** New Prompt Engine section with `definePrompt`, `PromptMessage` (all methods), `PromptMessage.fromView()` decomposition table, `PromptRegistry` methods, and Prompt types.
23
+ - **VitePress sidebar:** Prompts section expanded from 1 to 5 items. Reference section expanded from 1 to 12 anchor-linked entries.
24
+ - **README.md:** Complete rewrite โ€” engineering-focused documentation matching Prisma/tRPC style. Every section: 1-line technical description + code + output.
25
+ - **llms.txt:** Prompt Engine and MVA-Driven Prompts sections with examples. Public API expanded with 11 Prompt entries and 5 Prompt types.
26
+
27
+ ### Test Suite
28
+
29
+ - **14 new tests** in `PromptMessageFromView.test.ts` covering rules decomposition, data extraction (JSON fencing), UI blocks, hints, suggestions, full composition, Presenter integration, and edge cases.
30
+ - **Test count:** 1,356 tests across 61 files, all passing.
31
+
32
+ ## [1.5.0] - 2026-02-23
33
+
34
+ ### ๐Ÿ’ฌ Prompt Engine โ€” 100% MCP Spec Compliance
35
+
36
+ Full implementation of MCP `prompts/list` and `prompts/get` handlers with `definePrompt()`, `PromptMessage`, `PromptRegistry`, schema-informed coercion, middleware, tag-based filtering, and lifecycle sync (`notifications/prompts/list_changed`).
37
+
38
+ ### Added
39
+
40
+ - **`definePrompt(name, config)`:** JSON-first prompt builder with flat schema constraint (primitives only โ€” string, number, boolean, enum).
41
+ - **`PromptMessage`:** Factory methods โ€” `.system()`, `.user()`, `.assistant()`, `.image()`, `.audio()`, `.resource()`.
42
+ - **`PromptRegistry<TContext>`:** Registration, tag-based RBAC filtering, `routeGet()` handler routing, `notifyChanged()` lifecycle sync, `attachToServer()`.
43
+ - **Schema-informed coercion:** Automatic string โ†’ number/boolean conversion based on declared schema types.
44
+ - **Flat schema constraint enforcement:** Nested objects/arrays rejected at definition time with actionable errors.
45
+ - **Middleware support:** Same `defineMiddleware()` chain as Tools โ€” auth, RBAC, context derivation.
7
46
 
8
47
  ## [1.4.0] - 2026-02-23
9
48
 
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <div align="center">
2
2
  <h1>โšก๏ธ mcp-fusion</h1>
3
- <p><b>The first framework for building MCP servers that agents actually understand.</b></p>
4
- <p>Not another SDK wrapper. A fundamentally new architecture for the Model Context Protocol.</p>
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
5
 
6
6
  [![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
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
@@ -11,148 +11,35 @@
11
11
 
12
12
  <br/>
13
13
 
14
- **[๐Ÿ“– Documentation & Guides](https://vinkius-labs.github.io/mcp-fusion/)** ยท **[๐Ÿ’ฐ Cost & Hallucination](https://vinkius-labs.github.io/mcp-fusion/cost-and-hallucination)** ยท **[๐Ÿณ Cookbook & Examples](https://vinkius-labs.github.io/mcp-fusion/examples)**
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
15
 
16
- <br/>
17
-
18
- ## The Problem: Every MCP Server Today Is Built Wrong
19
-
20
- Look at any MCP server on GitHub. They all look like this:
21
-
22
- ```typescript
23
- // โŒ What every MCP server looks like today
24
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
25
- const { name, arguments: args } = request.params;
26
-
27
- switch (name) {
28
- case 'get_invoice':
29
- const invoice = await db.invoices.findUnique(args.id);
30
- return { content: [{ type: 'text', text: JSON.stringify(invoice) }] };
31
- // โ†‘ Raw JSON. The AI has no idea
32
- // that amount_cents is in cents,
33
- // what actions are available next,
34
- // or which fields are sensitive.
35
- case 'list_invoices':
36
- // ...50 more cases
37
- }
38
- });
16
+ ```bash
17
+ npm install @vinkius-core/mcp-fusion zod
39
18
  ```
40
19
 
41
- **This is the state of the art in 2025.** Raw JSON output. Manual switch/case routing. No validation. No domain context. No guardrails. The AI sees `{ amount_cents: 45000 }` and guesses โ€” often wrong โ€” whether it's dollars, cents, or yen.
42
-
43
- The result:
44
- - ๐ŸŽฏ **Parameter hallucination** โ€” The AI invents field names that don't exist
45
- - ๐Ÿ’€ **Data misinterpretation** โ€” `45000` cents displayed as $45,000 instead of $450
46
- - ๐Ÿ”€ **Action blindness** โ€” The AI doesn't know what to do next, so it hallucinates tool names
47
- - ๐Ÿ”“ **No security** โ€” Internal fields leak to the LLM context
48
-
49
20
  ---
50
21
 
51
- <div align="center">
52
-
53
- ### ๐Ÿง  The Revolution: MVA (Model-View-Agent)
54
-
55
- **MVC was designed for humans. Agents are not humans.**
22
+ ## Overview
56
23
 
57
- The AI industry builds agents on MVC, REST, and patterns made for browsers.<br/>
58
- None of them were designed for an autonomous consumer that **hallucinates when given ambiguous data.**
59
-
60
- **mcp-fusion** introduces **MVA** โ€” a foundational architecture where the<br/>**Presenter** replaces the human-centric View with an **agent-centric perception layer.**
61
-
62
- </div>
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.
63
25
 
64
26
  ```text
65
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
66
- โ”‚ โšก Model-View-Agent (MVA) โ”‚
67
- โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
68
- โ”‚ โ”‚
69
- โ”‚ Model โ†’ View โ†’ Agent โ”‚
70
- โ”‚ Zod Schema Presenter LLM โ”‚
71
- โ”‚ (validates) (perceives) (acts) โ”‚
72
- โ”‚ โ”‚
73
- โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
74
- โ”‚ โ”‚ ๐Ÿ“„ Validated Data โ”‚ โ”‚
75
- โ”‚ โ”‚ ๐Ÿ“‹ Domain Rules โ€” "CENTS. Divide by 100." โ”‚ โ”‚
76
- โ”‚ โ”‚ ๐Ÿ“Š UI Blocks โ€” ECharts, Mermaid, Summaries โ”‚ โ”‚
77
- โ”‚ โ”‚ ๐Ÿ”— Action Hints โ€” "โ†’ billing.pay" โ”‚ โ”‚
78
- โ”‚ โ”‚ โš ๏ธ Guardrails โ€” "50 shown, 250 hidden." โ”‚ โ”‚
79
- โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
80
- โ”‚ โ–ฒ Structured Perception Package โ”‚
81
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
82
- ```
83
-
84
- <div align="center">
85
-
86
- > **Every response is a structured perception package โ€” not raw JSON.**<br/>
87
- > The AI doesn't guess. It *knows*.
88
-
89
- ๐Ÿ“– **[Read the full MVA Pattern Guide โ†’](https://vinkius-labs.github.io/mcp-fusion/mva-pattern)**
90
-
91
- </div>
92
-
93
- ### Without MVA vs With MVA
94
-
95
- | | Without MVA | With MVA (mcp-fusion) |
96
- |---|---|---|
97
- | **Tool count** | 50 registered tools. LLM sees ALL. Token explosion. | **Action consolidation** โ€” 5,000+ ops in ONE tool via `module.action` discriminator. 10x fewer tokens. |
98
- | **Response** | `JSON.stringify(data)` โ€” the AI guesses | **Structured perception package** โ€” data + rules + UI + affordances |
99
- | **Domain context** | None. `45000` โ€” dollars? cents? yen? | **System rules**: *"amount_cents is in CENTS. Divide by 100."* |
100
- | **Next actions** | AI hallucinates tool names | **Agentic HATEOAS** โ€” `.suggestActions()` with explicit hints |
101
- | **Large datasets** | 10,000 rows dump into context | **Cognitive guardrails** โ€” `.agentLimit(50)` + filter guidance |
102
- | **Security** | Internal fields leak to LLM | **Schema as boundary** โ€” Zod `.strict()` rejects undeclared fields with actionable errors |
103
- | **Charts** | Not possible | **UI Blocks** โ€” `.uiBlocks()` โ€” ECharts, Mermaid, summaries |
104
- | **Routing** | `switch/case` ร— 50 branches | **Hierarchical groups** โ€” `platform.users.list` โ€” infinite nesting |
105
- | **Error recovery** | `throw Error` โ€” AI gives up | **Self-healing** โ€” `toolError()` + **Agentic Error Presenter** โ€” auto-formatted validation/routing errors with coaching prompts |
106
- | **Token cost** | Full JSON payloads every time | **TOON encoding** โ€” ~40% fewer tokens |
107
- | **Type safety** | Manual casting, no client types | **tRPC-style client** โ€” `createFusionClient()` with full inference |
108
- | **Reusability** | Same entity rendered differently everywhere | **Presenter** โ€” define once, reuse across all tools |
109
-
110
- ๐Ÿ“– **[See the full side-by-side comparison with code examples โ†’](https://vinkius-labs.github.io/mcp-fusion/comparison)**
111
-
112
- ---
113
-
114
- ## What It Looks Like in Code
115
-
116
- ```typescript
117
- // โœ… The mcp-fusion way โ€” your handler returns raw data. That's it.
118
- const billing = defineTool<AppContext>('billing', {
119
- actions: {
120
- get_invoice: {
121
- returns: InvoicePresenter, // โ† The AI will UNDERSTAND this data
122
- params: { id: 'string' },
123
- handler: async (ctx, args) => {
124
- return await ctx.db.invoices.findUnique({ where: { id: args.id } });
125
- // Raw data โ†’ Presenter validates, renders, guides โ€” automatically
126
- },
127
- },
128
- },
129
- });
27
+ Model (Zod Schema) โ†’ View (Presenter) โ†’ Agent (LLM)
28
+ validates perceives acts
130
29
  ```
131
30
 
132
- The **Presenter** automatically:
133
- - โœ… **Validates** data through Zod (rejects unknown fields with actionable errors, validates shapes)
134
- - โœ… **Injects domain rules** โ€” "amount_cents is in CENTS. Divide by 100."
135
- - โœ… **Renders charts** โ€” Server-side ECharts, Mermaid diagrams
136
- - โœ… **Suggests next actions** โ€” "โ†’ billing.pay: Process payment"
137
- - โœ… **Truncates intelligently** โ€” "50 shown, 250 hidden. Use filters."
138
-
139
- No switch/case. No manual JSON.stringify. No praying.
140
-
141
- ```bash
142
- npm install @vinkius-core/mcp-fusion zod
143
- ```
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.
144
32
 
145
33
  ---
146
34
 
147
- ## The Presenter: Your Agent's Perception Layer
35
+ ## Presenter
148
36
 
149
- The Presenter is domain-level, not tool-level. Define `InvoicePresenter` once โ€” every tool that returns invoices uses it. Consistent perception. Zero hallucination.
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.
150
38
 
151
39
  ```typescript
152
- import { createPresenter, ui, defineTool } from '@vinkius-core/mcp-fusion';
40
+ import { createPresenter, ui } from '@vinkius-core/mcp-fusion';
153
41
  import { z } from 'zod';
154
42
 
155
- // โ”€โ”€ Define the Presenter (MVA View Layer) โ”€โ”€
156
43
  export const InvoicePresenter = createPresenter('Invoice')
157
44
  .schema(z.object({
158
45
  id: z.string(),
@@ -162,7 +49,7 @@ export const InvoicePresenter = createPresenter('Invoice')
162
49
  .systemRules((invoice, ctx) => [
163
50
  'CRITICAL: amount_cents is in CENTS. Divide by 100 before display.',
164
51
  ctx?.user?.role !== 'admin'
165
- ? 'RESTRICTED: Mask totals for non-admin users.'
52
+ ? 'RESTRICTED: Do not reveal exact totals to non-admin users.'
166
53
  : null,
167
54
  ])
168
55
  .uiBlocks((invoice) => [
@@ -171,7 +58,7 @@ export const InvoicePresenter = createPresenter('Invoice')
171
58
  }),
172
59
  ])
173
60
  .agentLimit(50, (omitted) =>
174
- ui.summary(`โš ๏ธ 50 shown, ${omitted} hidden. Use filters.`)
61
+ ui.summary(`โš ๏ธ 50 shown, ${omitted} hidden. Use status or date_range filters.`)
175
62
  )
176
63
  .suggestActions((invoice) =>
177
64
  invoice.status === 'pending'
@@ -180,110 +67,104 @@ export const InvoicePresenter = createPresenter('Invoice')
180
67
  );
181
68
  ```
182
69
 
183
- The agent receives a complete perception package:
70
+ The agent receives:
184
71
 
185
72
  ```text
186
- ๐Ÿ“„ DATA โ†’ Validated, sensitive fields stripped
73
+ ๐Ÿ“„ DATA โ†’ Validated through Zod .strict() โ€” undeclared fields rejected
187
74
  ๐Ÿ“‹ RULES โ†’ "amount_cents is in CENTS. Divide by 100."
188
75
  ๐Ÿ“Š UI BLOCKS โ†’ ECharts gauge rendered server-side
189
76
  โš ๏ธ GUARDRAIL โ†’ "50 shown, 250 hidden. Use filters."
190
- ๐Ÿ”— HINTS โ†’ "โ†’ billing.pay: Process payment"
77
+ ๐Ÿ”— AFFORDANCE โ†’ "โ†’ billing.pay: Process payment"
191
78
  ```
192
79
 
193
- ### Pipeline Integration โ€” Zero Boilerplate
194
-
195
- Attach the Presenter to any action. The handler returns raw data. The framework handles everything.
80
+ Presenters compose via `.embed()` โ€” child Presenter rules, UI blocks, and suggestions merge automatically:
196
81
 
197
82
  ```typescript
198
- const billing = defineTool<AppContext>('billing', {
199
- actions: {
200
- get_invoice: {
201
- returns: InvoicePresenter, // โ† MVA View Layer
202
- params: { id: 'string' },
203
- handler: async (ctx, args) => {
204
- return await ctx.db.invoices.findUnique({
205
- where: { id: args.id },
206
- include: { client: true },
207
- });
208
- // Raw data โ†’ Presenter validates, renders, suggests โ€” automatically
209
- },
210
- },
211
- },
212
- });
213
- ```
214
-
215
- ### Presenter Composition
216
-
217
- Real data has relationships. `.embed()` composes child Presenters for nested data โ€” rules and UI blocks merge automatically.
218
-
219
- ```typescript
220
- const ClientPresenter = createPresenter('Client')
221
- .schema(clientSchema)
222
- .systemRules(['Display company name prominently.']);
223
-
224
83
  const InvoicePresenter = createPresenter('Invoice')
225
84
  .schema(invoiceSchema)
226
- .embed('client', ClientPresenter); // โ† nested composition
85
+ .embed('client', ClientPresenter)
86
+ .embed('payment_method', PaymentMethodPresenter);
227
87
  ```
228
88
 
229
89
  ---
230
90
 
231
- ## Action Consolidation: One Tool, Not Fifty
91
+ ## Tool Definition
92
+
93
+ Two APIs, identical output. `defineTool()` uses JSON shorthand (no Zod imports). `createTool()` uses full Zod schemas.
232
94
 
233
- Standard MCP servers expose individual tools per operation. 50 tools = 50 schemas burning tokens. mcp-fusion consolidates related operations behind a discriminator field.
95
+ ### `defineTool()` โ€” JSON-First
234
96
 
235
97
  ```typescript
236
- const projects = defineTool<AppContext>('projects', {
237
- description: 'Manage workspace projects',
98
+ import { defineTool } from '@vinkius-core/mcp-fusion';
99
+
100
+ const billing = defineTool<AppContext>('billing', {
101
+ description: 'Billing operations',
238
102
  shared: { workspace_id: 'string' },
239
103
  actions: {
240
- list: {
104
+ get_invoice: {
241
105
  readOnly: true,
242
- returns: ProjectPresenter,
243
- handler: async (ctx, args) => await ctx.db.projects.findMany(),
106
+ returns: InvoicePresenter,
107
+ params: { id: 'string' },
108
+ handler: async (ctx, args) =>
109
+ await ctx.db.invoices.findUnique({ where: { id: args.id } }),
244
110
  },
245
- create: {
246
- params: { name: { type: 'string', min: 1 } },
247
- handler: async (ctx, args) => await ctx.db.projects.create(args),
111
+ create_invoice: {
112
+ params: {
113
+ client_id: 'string',
114
+ amount: { type: 'number', min: 0 },
115
+ currency: { enum: ['USD', 'EUR', 'BRL'] as const },
116
+ },
117
+ handler: async (ctx, args) =>
118
+ await ctx.db.invoices.create({ data: args }),
248
119
  },
249
- delete: {
120
+ void_invoice: {
250
121
  destructive: true,
251
- params: { project_id: 'string' },
122
+ params: { id: 'string', reason: { type: 'string', optional: true } },
252
123
  handler: async (ctx, args) => {
253
- await ctx.db.projects.delete(args.project_id);
254
- return 'Deleted';
124
+ await ctx.db.invoices.void(args.id);
125
+ return 'Invoice voided';
255
126
  },
256
127
  },
257
128
  },
258
129
  });
259
130
  ```
260
131
 
261
- The LLM sees one perfectly structured tool:
262
- ```text
263
- Action: list | create | delete
264
- - 'list': Requires: workspace_id. For: list
265
- - 'create': Requires: workspace_id, name. For: create
266
- - 'delete': Requires: workspace_id, project_id โš ๏ธ DESTRUCTIVE
132
+ ### `createTool()` โ€” Full Zod
133
+
134
+ ```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
+ });
267
148
  ```
268
149
 
269
- ### Two APIs โ€” One Framework
150
+ ### Action Consolidation
270
151
 
271
- | Feature | `defineTool()` | `createTool()` |
272
- |---|---|---|
273
- | **Syntax** | Declarative config object | Fluent builder chain |
274
- | **Zod needed?** | No (auto-converts) | Yes |
275
- | **Best for** | Rapid prototyping | Complex validation |
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:
276
153
 
277
- Both produce identical MCP tools. Mix and match freely.
154
+ ```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
160
+ ```
278
161
 
279
- ---
162
+ ### Hierarchical Groups
280
163
 
281
- ## Enterprise Engineering Core
164
+ For large APIs (5,000+ operations), nest actions into groups:
282
165
 
283
- ### Hierarchical Groups โ€” 5,000+ Actions
284
166
  ```typescript
285
- new GroupedToolBuilder<AppContext>('platform')
286
- .tags('core')
167
+ createTool<AppContext>('platform')
287
168
  .group('users', 'User management', g => {
288
169
  g.use(requireAdmin)
289
170
  .action({ name: 'list', readOnly: true, handler: listUsers })
@@ -292,134 +173,229 @@ new GroupedToolBuilder<AppContext>('platform')
292
173
  .group('billing', 'Billing operations', g => {
293
174
  g.action({ name: 'refund', destructive: true, schema: refundSchema, handler: issueRefund });
294
175
  });
295
- // Discriminator: users.list | users.ban | billing.refund
176
+ // Discriminator values: users.list | users.ban | billing.refund
296
177
  ```
297
178
 
298
- ### Context Derivation โ€” `defineMiddleware()`
299
- tRPC-style middleware that derives typed data into context:
179
+ ---
180
+
181
+ ## Prompt Engine
182
+
183
+ Full MCP `prompts/list` + `prompts/get` implementation. Prompt arguments are **flat primitives only** (string, number, boolean, enum) โ€” MCP clients render them as forms.
184
+
185
+ ```typescript
186
+ import { definePrompt, PromptMessage } from '@vinkius-core/mcp-fusion';
187
+
188
+ 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,
195
+ middleware: [requireAuth, requireRole('auditor')],
196
+ handler: async (ctx, { invoiceId, depth }) => {
197
+ const invoice = await ctx.db.invoices.get(invoiceId);
198
+
199
+ return {
200
+ messages: [
201
+ PromptMessage.system('You are a Senior Financial Auditor.'),
202
+ ...PromptMessage.fromView(InvoicePresenter.make(invoice, ctx)),
203
+ PromptMessage.user(`Perform a ${depth} audit on this invoice.`),
204
+ ],
205
+ };
206
+ },
207
+ });
208
+ ```
209
+
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
+ ---
224
+
225
+ ## Middleware
226
+
227
+ tRPC-style context derivation with pre-compiled chains:
228
+
300
229
  ```typescript
301
230
  import { defineMiddleware } from '@vinkius-core/mcp-fusion';
302
231
 
303
232
  const requireAuth = defineMiddleware(async (ctx: { token: string }) => {
304
233
  const user = await db.getUser(ctx.token);
305
234
  if (!user) throw new Error('Unauthorized');
306
- return { user }; // โ† TS infers: { user: User }
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: { ... },
307
242
  });
308
243
  ```
309
244
 
310
- ### Self-Healing Errors โ€” `toolError()`
311
- Structured recovery for autonomous agents:
245
+ ---
246
+
247
+ ## Error Handling
248
+
249
+ Structured errors with recovery instructions. The agent receives the error code, a suggestion, and a list of valid actions to try:
250
+
312
251
  ```typescript
252
+ import { toolError } from '@vinkius-core/mcp-fusion';
253
+
313
254
  return toolError('ProjectNotFound', {
314
255
  message: `Project '${id}' does not exist.`,
315
256
  suggestion: 'Call projects.list first to get valid IDs.',
316
257
  availableActions: ['projects.list'],
317
258
  });
318
- // Output: [ProjectNotFound] Project 'xyz' does not exist.
319
- // ๐Ÿ’ก Suggestion: Call projects.list first.
320
- // ๐Ÿ“‹ Try: projects.list
321
259
  ```
322
260
 
323
- ### Streaming Progress โ€” `progress()`
324
- ```typescript
325
- handler: async function* (ctx, args) {
326
- yield progress(10, 'Cloning repository...');
327
- yield progress(50, 'Building AST...');
328
- yield progress(90, 'Almost done...');
329
- return success('Deployed successfully');
330
- }
261
+ ```text
262
+ [ProjectNotFound] Project 'xyz' does not exist.
263
+ ๐Ÿ’ก Suggestion: Call projects.list first to get valid IDs.
264
+ ๐Ÿ“‹ Try: projects.list
331
265
  ```
332
266
 
333
- ### Type-Safe Client โ€” `createFusionClient()`
334
- End-to-end type safety from server to client:
267
+ ---
268
+
269
+ ## Type-Safe Client
270
+
271
+ End-to-end type inference from server to client โ€” autocomplete for action names and typed arguments:
272
+
335
273
  ```typescript
336
274
  import { createFusionClient } from '@vinkius-core/mcp-fusion/client';
337
- import type { AppRouter } from './mcp-server';
275
+ import type { AppRouter } from './server';
338
276
 
339
277
  const client = createFusionClient<AppRouter>(transport);
340
- const result = await client.execute('projects.create', { name: 'Vinkius V2' });
341
- // ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
342
- // autocomplete! typed args!
278
+ const result = await client.execute('billing.get_invoice', { workspace_id: 'ws_1', id: 'inv_42' });
279
+ // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
280
+ // autocomplete typed args
343
281
  ```
344
282
 
345
- ### State Sync โ€” Temporal Awareness
346
- RFC 7234-inspired cache-control signals prevent agents from using stale data:
283
+ ---
284
+
285
+ ## Registry & Server Integration
286
+
347
287
  ```typescript
348
- registry.attachToServer(server, {
349
- stateSync: {
288
+ import { ToolRegistry, PromptRegistry } from '@vinkius-core/mcp-fusion';
289
+
290
+ const tools = new ToolRegistry<AppContext>();
291
+ tools.register(billing);
292
+ tools.register(projects);
293
+
294
+ const prompts = new PromptRegistry<AppContext>();
295
+ prompts.register(AuditPrompt);
296
+ prompts.register(SummarizePrompt);
297
+
298
+ // Attach to MCP server (works with Server and McpServer โ€” duck-typed)
299
+ tools.attachToServer(server, {
300
+ contextFactory: (extra) => createAppContext(extra),
301
+ filter: { tags: ['public'] }, // Tag-based context gating
302
+ toolExposition: 'flat', // 'flat' or 'grouped' wire format
303
+ stateSync: { // RFC 7234-inspired cache signals
350
304
  defaults: { cacheControl: 'no-store' },
351
305
  policies: [
352
306
  { match: 'sprints.update', invalidates: ['sprints.*'] },
353
- { match: 'tasks.update', invalidates: ['tasks.*', 'sprints.*'] },
354
307
  { match: 'countries.*', cacheControl: 'immutable' },
355
308
  ],
356
309
  },
357
310
  });
311
+
312
+ prompts.attachToServer(server, {
313
+ contextFactory: (extra) => createAppContext(extra),
314
+ });
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Streaming Progress
320
+
321
+ Generator handlers yield progress events โ€” automatically forwarded as MCP `notifications/progress` when the client provides a `progressToken`:
322
+
323
+ ```typescript
324
+ handler: async function* (ctx, args) {
325
+ yield progress(10, 'Cloning repository...');
326
+ yield progress(50, 'Building AST...');
327
+ yield progress(90, 'Running analysis...');
328
+ return success(analysisResult);
329
+ }
358
330
  ```
359
331
 
360
- ### Zod Parameter Validation (.strict())
361
- When the LLM sends arguments, Fusion merges schemas using `.merge().strict()`, then `safeParse()`. Unknown fields trigger an **actionable validation error** naming each unrecognized field. **The LLM learns which fields are valid and self-corrects on retry.**
332
+ ---
333
+
334
+ ## Observability
335
+
336
+ Zero-overhead typed event system. Debug observers attach per-tool or globally:
362
337
 
363
- ### Tag-Based Context Gating
364
- Control exactly what the LLM sees per session:
365
338
  ```typescript
366
- registry.attachToServer(server, { filter: { tags: ['core'] } }); // Only core tools
367
- registry.attachToServer(server, { filter: { exclude: ['internal'] } }); // No internal tools
339
+ import { createDebugObserver } from '@vinkius-core/mcp-fusion';
340
+
341
+ // Per-tool
342
+ billing.debug(createDebugObserver());
343
+
344
+ // Global โ€” propagates to all registered tools
345
+ tools.enableDebug(createDebugObserver((event) => {
346
+ opentelemetry.addEvent(event.type, event);
347
+ }));
368
348
  ```
369
349
 
370
- ### Freeze-After-Build Immutability
371
- After `buildToolDefinition()`, the builder is permanently frozen. `Object.freeze()` prevents mutation. Mutation methods throw. This eliminates accidental post-registration bugs.
350
+ OpenTelemetry-compatible tracing with structural subtyping (no `@opentelemetry/api` dependency required):
351
+
352
+ ```typescript
353
+ tools.enableTracing(tracer);
354
+ // Spans: mcp.tool, mcp.action, mcp.durationMs, mcp.isError, mcp.tags
355
+ ```
372
356
 
373
357
  ---
374
358
 
375
- ## Complete Capability Matrix
359
+ ## Capability Matrix
376
360
 
377
- | Capability | What It Solves |
361
+ | Capability | Mechanism |
378
362
  |---|---|
379
- | **MVA Presenter** | Domain rules, UI blocks, affordances โ€” consistent agent perception |
380
- | **Presenter Composition** | `.embed()` nests child Presenters for relational data |
381
- | **Cognitive Guardrails** | `.agentLimit()` prevents context DDoS from large datasets |
382
- | **Agentic Affordances** | `.suggestActions()` HATEOAS-style next-action hints |
383
- | **Context-Aware Rules** | RBAC/DLP through dynamic `systemRules()` with `ctx` |
384
- | **Action Consolidation** | Grouped tools with discriminator enum reduce token burn |
385
- | **Hierarchical Groups** | Namespace 5,000+ actions with `module.action` keys |
386
- | **4-Tier Field Annotations** | LLM knows exactly which fields to send per action |
387
- | **Zod `.merge().strict()`** | Security boundary โ€” unknown fields rejected with actionable errors |
388
- | **Two APIs** | `defineTool()` (zero Zod) and `createTool()` (full Zod) |
389
- | **Context Derivation** | tRPC-style `defineMiddleware()` with type inference |
390
- | **Self-Healing Errors** | `toolError()` + Agentic Error Presenter โ€” auto-formatted validation/routing errors |
391
- | **Streaming Progress** | Generator handlers yield `progress()` events |
392
- | **Type-Safe Client** | `createFusionClient()` with autocomplete and typed args |
393
- | **State Sync** | RFC 7234 cache-control prevents temporal blindness |
394
- | **Prompt Engine** | `definePrompt()` โ€” server-side hydrated templates with flat schema constraint |
395
- | **TOON Encoding** | Token-optimized descriptions and responses |
396
- | **Tag Filtering** | Context gating โ€” control what the LLM sees per session |
397
- | **Observability** | Debug observers with zero-overhead typed event system |
398
- | **Introspection API** | Runtime metadata for compliance audits |
399
- | **Tool Exposition** | `'flat'` or `'grouped'` โ€” decouple authoring topology from wire format |
400
- | **Freeze-After-Build** | `Object.freeze()` โ€” immutability after registration |
401
- | **Duck-Typed Server** | Works with `Server` and `McpServer` โ€” zero coupling |
363
+ | **Presenter** | Domain-level View layer โ€” `.schema()`, `.systemRules()`, `.uiBlocks()`, `.suggestActions()`, `.embed()` |
364
+ | **Cognitive Guardrails** | `.agentLimit(max, onTruncate)` โ€” truncates arrays, injects filter guidance |
365
+ | **Action Consolidation** | Multiple actions โ†’ single MCP tool with discriminator enum |
366
+ | **Hierarchical Groups** | `.group()` โ€” namespace 5,000+ actions as `module.action` |
367
+ | **Prompt Engine** | `definePrompt()` with flat schema constraint, middleware, lifecycle sync |
368
+ | **MVA-Driven Prompts** | `PromptMessage.fromView()` โ€” Presenter โ†’ XML-tagged prompt messages |
369
+ | **Context Derivation** | `defineMiddleware()` โ€” tRPC-style typed context merging |
370
+ | **Self-Healing Errors** | `toolError()` โ€” structured recovery with action suggestions |
371
+ | **Type-Safe Client** | `createFusionClient<T>()` โ€” full inference from server to client |
372
+ | **Streaming Progress** | `yield progress()` โ†’ MCP `notifications/progress` |
373
+ | **State Sync** | RFC 7234 cache-control signals โ€” `invalidates`, `no-store`, `immutable` |
374
+ | **Tool Exposition** | `'flat'` or `'grouped'` wire format โ€” same handlers, different topology |
375
+ | **Tag Filtering** | RBAC context gating โ€” `{ tags: ['core'] }` / `{ exclude: ['internal'] }` |
376
+ | **Observability** | Zero-overhead debug observers + OpenTelemetry-compatible tracing |
377
+ | **TOON Encoding** | Token-Optimized Object Notation โ€” ~40% fewer tokens |
378
+ | **Validation** | Zod `.merge().strict()` โ€” unknown fields rejected with actionable errors |
379
+ | **Introspection** | Runtime metadata via `fusion://manifest.json` MCP resource |
380
+ | **Immutability** | `Object.freeze()` after `buildToolDefinition()` โ€” no post-registration mutation |
402
381
 
403
382
  ---
404
383
 
405
- ## Learn by Doing
384
+ ## Documentation
406
385
 
407
- | Guide | Description |
386
+ | Guide | |
408
387
  |---|---|
409
- | ๐Ÿง  **[The MVA Manifesto](docs/mva-pattern.md)** | Why every MCP server today is built wrong โ€” and how MVA fixes it |
410
- | ๐Ÿ’ฐ **[Cost & Hallucination](docs/cost-and-hallucination.md)** | Fewer tokens + fewer requests = less hallucination + less cost |
411
- | ๐Ÿ **[5-Minute Quickstart](docs/quickstart.md)** | Build your first Fusion server from zero |
412
- | ๐Ÿณ **[Cookbook & Examples](docs/examples.md)** | 14 copy-pasteable real-world patterns for every feature |
413
- | ๐ŸŽฏ **[Presenter Deep Dive](docs/presenter.md)** | The agent-centric View layer โ€” schema, rules, UI, suggestions |
414
- | ๐Ÿ“– **[Introduction](docs/introduction.md)** | Core concepts and philosophy |
415
- | ๐Ÿ—๏ธ **[Architecture](docs/architecture.md)** | Domain model, strategy engine, execution pipeline |
416
- | ๐Ÿ›ก๏ธ **[Middleware](docs/middleware.md)** | Context derivation, authentication, pre-compiled chains |
417
- | ๐Ÿ“ˆ **[Scaling](docs/scaling.md)** | Tag filtering, TOON, hierarchical groups at scale |
418
- | ๐Ÿง  **[State Sync](docs/state-sync.md)** | Prevent temporal blindness with cache signals |
419
- | ๐Ÿ’ฌ **[Prompt Engine](docs/prompts.md)** | Server-side hydrated prompts with coercion and lifecycle sync |
420
- | ๐Ÿ”ญ **[Observability](docs/observability.md)** | Zero-overhead debug observers with typed event system |
421
- | ๐Ÿ”€ **[Tool Exposition](docs/tool-exposition.md)** | Flat vs grouped wire strategies โ€” per-action isolation |
422
- | ๐Ÿ“– **[API Reference](docs/api-reference.md)** | Complete typings and method reference |
388
+ | **[MVA Architecture](https://vinkius-labs.github.io/mcp-fusion/mva-pattern)** | The MVA pattern โ€” why and how |
389
+ | **[Quickstart](https://vinkius-labs.github.io/mcp-fusion/quickstart)** | Build a Fusion server from zero |
390
+ | **[Presenter](https://vinkius-labs.github.io/mcp-fusion/presenter)** | Schema, rules, UI blocks, affordances, composition |
391
+ | **[Prompt Engine](https://vinkius-labs.github.io/mcp-fusion/prompts)** | `definePrompt()`, `PromptMessage.fromView()`, registry |
392
+ | **[Middleware](https://vinkius-labs.github.io/mcp-fusion/middleware)** | Context derivation, authentication, chains |
393
+ | **[State Sync](https://vinkius-labs.github.io/mcp-fusion/state-sync)** | Cache-control signals, causal invalidation |
394
+ | **[Observability](https://vinkius-labs.github.io/mcp-fusion/observability)** | Debug observers, tracing |
395
+ | **[Tool Exposition](https://vinkius-labs.github.io/mcp-fusion/tool-exposition)** | Flat vs grouped wire strategies |
396
+ | **[Cookbook](https://vinkius-labs.github.io/mcp-fusion/examples)** | Real-world patterns |
397
+ | **[API Reference](https://vinkius-labs.github.io/mcp-fusion/api-reference)** | Complete typings |
398
+ | **[Cost & Hallucination](https://vinkius-labs.github.io/mcp-fusion/cost-and-hallucination)** | Token reduction analysis |
423
399
 
424
400
  ---
425
401
 
@@ -429,4 +405,3 @@ After `buildToolDefinition()`, the builder is permanently frozen. `Object.freeze
429
405
  - TypeScript 5.7+
430
406
  - `@modelcontextprotocol/sdk ^1.12.1` (peer dependency)
431
407
  - `zod ^3.25.1 || ^4.0.0` (peer dependency)
432
- - `@toon-format/toon` (for TOON features)
@@ -172,6 +172,42 @@ export declare class ResponseBuilder {
172
172
  * @internal
173
173
  */
174
174
  rawBlock(text: string): this;
175
+ /**
176
+ * Get the serialized data payload.
177
+ *
178
+ * Returns the JSON-stringified (or raw string) data
179
+ * that was passed to the constructor.
180
+ *
181
+ * @returns The data string
182
+ *
183
+ * @remarks Used by {@link PromptMessage.fromView} to decompose
184
+ * a Presenter view into prompt messages without calling `.build()`.
185
+ */
186
+ getData(): string;
187
+ /**
188
+ * Get the accumulated domain rules.
189
+ *
190
+ * @returns Read-only array of rule strings
191
+ */
192
+ getRules(): readonly string[];
193
+ /**
194
+ * Get the accumulated UI blocks.
195
+ *
196
+ * @returns Read-only array of UI blocks
197
+ */
198
+ getUiBlocks(): readonly UiBlock[];
199
+ /**
200
+ * Get the accumulated LLM hints.
201
+ *
202
+ * @returns Read-only array of hint strings
203
+ */
204
+ getHints(): readonly string[];
205
+ /**
206
+ * Get the accumulated action suggestions.
207
+ *
208
+ * @returns Read-only array of action suggestions
209
+ */
210
+ getSuggestions(): readonly ActionSuggestion[];
175
211
  /**
176
212
  * Compile all layers into a multi-block MCP `ToolResponse`.
177
213
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBuilder.d.ts","sourceRoot":"","sources":["../../../src/framework/presenter/ResponseBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAO1E;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IACxB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,0BAA0B;IAE1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAE3C,qDAAqD;gBACzC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAU5C;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;IAK1C;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAK3C;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI;IAK1D;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK5B;;;;;;;;;;;OAWG;IACH,KAAK,IAAI,YAAY;CA2CxB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,CAE/D;yBAFe,QAAQ;mBAmBQ,MAAM,GAAG,MAAM,KAAG,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;0BAsB5E,MAAM,GAAG,MAAM,SACd,SAAS,MAAM,EAAE,KACzB,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"ResponseBuilder.d.ts","sourceRoot":"","sources":["../../../src/framework/presenter/ResponseBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAO1E;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IACxB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,0BAA0B;IAE1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAE3C,qDAAqD;gBACzC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAU5C;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;IAK1C;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK3B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAK3C;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI;IAK1D;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO5B;;;;;;;;;;OAUG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,QAAQ,IAAI,SAAS,MAAM,EAAE;IAI7B;;;;OAIG;IACH,WAAW,IAAI,SAAS,OAAO,EAAE;IAIjC;;;;OAIG;IACH,QAAQ,IAAI,SAAS,MAAM,EAAE;IAI7B;;;;OAIG;IACH,cAAc,IAAI,SAAS,gBAAgB,EAAE;IAM7C;;;;;;;;;;;OAWG;IACH,KAAK,IAAI,YAAY;CA2CxB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,CAE/D;yBAFe,QAAQ;mBAmBQ,MAAM,GAAG,MAAM,KAAG,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;0BAsB5E,MAAM,GAAG,MAAM,SACd,SAAS,MAAM,EAAE,KACzB,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC"}
@@ -181,6 +181,54 @@ export class ResponseBuilder {
181
181
  this._rawBlocks.push(text);
182
182
  return this;
183
183
  }
184
+ // โ”€โ”€ Introspection (for cross-module composition) โ”€โ”€โ”€โ”€โ”€
185
+ /**
186
+ * Get the serialized data payload.
187
+ *
188
+ * Returns the JSON-stringified (or raw string) data
189
+ * that was passed to the constructor.
190
+ *
191
+ * @returns The data string
192
+ *
193
+ * @remarks Used by {@link PromptMessage.fromView} to decompose
194
+ * a Presenter view into prompt messages without calling `.build()`.
195
+ */
196
+ getData() {
197
+ return this._data;
198
+ }
199
+ /**
200
+ * Get the accumulated domain rules.
201
+ *
202
+ * @returns Read-only array of rule strings
203
+ */
204
+ getRules() {
205
+ return this._rules;
206
+ }
207
+ /**
208
+ * Get the accumulated UI blocks.
209
+ *
210
+ * @returns Read-only array of UI blocks
211
+ */
212
+ getUiBlocks() {
213
+ return this._uiBlocks;
214
+ }
215
+ /**
216
+ * Get the accumulated LLM hints.
217
+ *
218
+ * @returns Read-only array of hint strings
219
+ */
220
+ getHints() {
221
+ return this._hints;
222
+ }
223
+ /**
224
+ * Get the accumulated action suggestions.
225
+ *
226
+ * @returns Read-only array of action suggestions
227
+ */
228
+ getSuggestions() {
229
+ return this._suggestions;
230
+ }
231
+ // โ”€โ”€ Compilation โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
184
232
  /**
185
233
  * Compile all layers into a multi-block MCP `ToolResponse`.
186
234
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ResponseBuilder.js","sourceRoot":"","sources":["../../../src/framework/presenter/ResponseBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResponseBuilder.js","sourceRoot":"","sources":["../../../src/framework/presenter/ResponseBuilder.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@
24
24
  * @module
25
25
  */
26
26
  import { type PromptMessagePayload } from './PromptTypes.js';
27
+ import { type ResponseBuilder } from '../presenter/ResponseBuilder.js';
27
28
  /**
28
29
  * Factory for creating MCP prompt messages.
29
30
  *
@@ -86,5 +87,47 @@ export declare const PromptMessage: {
86
87
  text?: string;
87
88
  blob?: string;
88
89
  }) => PromptMessagePayload;
90
+ /**
91
+ * Decompose a Presenter view into prompt messages.
92
+ *
93
+ * MVA-Driven Prompts โ€” the bridge between the Presenter layer
94
+ * (MVA View for Tools) and the Prompt Engine. Extracts system rules,
95
+ * data, UI blocks, and action suggestions from a `ResponseBuilder`
96
+ * into composable `PromptMessagePayload[]` messages.
97
+ *
98
+ * Uses XML-tagged semantic blocks (`<domain_rules>`, `<dataset>`,
99
+ * `<visual_context>`, `<system_guidance>`) optimized for frontier
100
+ * LLM context handling โ€” prevents context leakage between layers.
101
+ *
102
+ * **Single Source of Truth**: If a Presenter's `systemRules()` change,
103
+ * both Tools and Prompts update automatically โ€” zero duplication.
104
+ *
105
+ * @param builder - A `ResponseBuilder` from `Presenter.make()` or `response()`
106
+ * @returns Array of prompt messages, ready to spread into `messages: [...]`
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import { definePrompt, PromptMessage } from '@vinkius-core/mcp-fusion';
111
+ * import { InvoicePresenter } from './presenters';
112
+ *
113
+ * const AuditPrompt = definePrompt<AppContext>('audit', {
114
+ * args: { invoiceId: 'string' } as const,
115
+ * handler: async (ctx, { invoiceId }) => {
116
+ * const invoice = await ctx.db.getInvoice(invoiceId);
117
+ * return {
118
+ * messages: [
119
+ * PromptMessage.system('You are a Senior Financial Auditor.'),
120
+ * ...PromptMessage.fromView(InvoicePresenter.make(invoice, ctx)),
121
+ * PromptMessage.user('Begin the audit for this invoice.'),
122
+ * ],
123
+ * };
124
+ * },
125
+ * });
126
+ * ```
127
+ *
128
+ * @see {@link Presenter} for the MVA View layer
129
+ * @see {@link ResponseBuilder} for the data source
130
+ */
131
+ readonly fromView: (builder: ResponseBuilder) => PromptMessagePayload[];
89
132
  };
90
133
  //# sourceMappingURL=PromptMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PromptMessage.d.ts","sourceRoot":"","sources":["../../../src/framework/prompt/PromptMessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;IACtB;;;;;;;;OAQG;4BACU,MAAM,KAAG,oBAAoB;IAI1C;;;;OAIG;0BACQ,MAAM,KAAG,oBAAoB;IAIxC;;;;;;;OAOG;+BACa,MAAM,KAAG,oBAAoB;IAI7C;;;;;;OAMG;2BACS,MAAM,GAAG,WAAW,QAAQ,MAAM,YAAY,MAAM,KAAG,oBAAoB;IAIvF;;;;;;OAMG;2BACS,MAAM,GAAG,WAAW,QAAQ,MAAM,YAAY,MAAM,KAAG,oBAAoB;IAIvF;;;;;;OAMG;8BAEO,MAAM,GAAG,WAAW,OACrB,MAAM,YACD;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAC9D,oBAAoB;CASjB,CAAC"}
1
+ {"version":3,"file":"PromptMessage.d.ts","sourceRoot":"","sources":["../../../src/framework/prompt/PromptMessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;IACtB;;;;;;;;OAQG;4BACU,MAAM,KAAG,oBAAoB;IAI1C;;;;OAIG;0BACQ,MAAM,KAAG,oBAAoB;IAIxC;;;;;;;OAOG;+BACa,MAAM,KAAG,oBAAoB;IAI7C;;;;;;OAMG;2BACS,MAAM,GAAG,WAAW,QAAQ,MAAM,YAAY,MAAM,KAAG,oBAAoB;IAIvF;;;;;;OAMG;2BACS,MAAM,GAAG,WAAW,QAAQ,MAAM,YAAY,MAAM,KAAG,oBAAoB;IAIvF;;;;;;OAMG;8BAEO,MAAM,GAAG,WAAW,OACrB,MAAM,YACD;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAC9D,oBAAoB;IAUvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;iCACe,eAAe,KAAG,oBAAoB,EAAE;CA4CpD,CAAC"}
@@ -24,6 +24,7 @@
24
24
  * @module
25
25
  */
26
26
  import {} from './PromptTypes.js';
27
+ import {} from '../presenter/ResponseBuilder.js';
27
28
  /**
28
29
  * Factory for creating MCP prompt messages.
29
30
  *
@@ -100,5 +101,82 @@ export const PromptMessage = {
100
101
  },
101
102
  };
102
103
  },
104
+ /**
105
+ * Decompose a Presenter view into prompt messages.
106
+ *
107
+ * MVA-Driven Prompts โ€” the bridge between the Presenter layer
108
+ * (MVA View for Tools) and the Prompt Engine. Extracts system rules,
109
+ * data, UI blocks, and action suggestions from a `ResponseBuilder`
110
+ * into composable `PromptMessagePayload[]` messages.
111
+ *
112
+ * Uses XML-tagged semantic blocks (`<domain_rules>`, `<dataset>`,
113
+ * `<visual_context>`, `<system_guidance>`) optimized for frontier
114
+ * LLM context handling โ€” prevents context leakage between layers.
115
+ *
116
+ * **Single Source of Truth**: If a Presenter's `systemRules()` change,
117
+ * both Tools and Prompts update automatically โ€” zero duplication.
118
+ *
119
+ * @param builder - A `ResponseBuilder` from `Presenter.make()` or `response()`
120
+ * @returns Array of prompt messages, ready to spread into `messages: [...]`
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * import { definePrompt, PromptMessage } from '@vinkius-core/mcp-fusion';
125
+ * import { InvoicePresenter } from './presenters';
126
+ *
127
+ * const AuditPrompt = definePrompt<AppContext>('audit', {
128
+ * args: { invoiceId: 'string' } as const,
129
+ * handler: async (ctx, { invoiceId }) => {
130
+ * const invoice = await ctx.db.getInvoice(invoiceId);
131
+ * return {
132
+ * messages: [
133
+ * PromptMessage.system('You are a Senior Financial Auditor.'),
134
+ * ...PromptMessage.fromView(InvoicePresenter.make(invoice, ctx)),
135
+ * PromptMessage.user('Begin the audit for this invoice.'),
136
+ * ],
137
+ * };
138
+ * },
139
+ * });
140
+ * ```
141
+ *
142
+ * @see {@link Presenter} for the MVA View layer
143
+ * @see {@link ResponseBuilder} for the data source
144
+ */
145
+ fromView(builder) {
146
+ const messages = [];
147
+ // 1. RULES โ†’ SYSTEM ROLE (domain directives travel with the data)
148
+ const rules = builder.getRules();
149
+ if (rules.length > 0) {
150
+ messages.push(PromptMessage.system(`<domain_rules>\n${rules.map(r => `- ${r}`).join('\n')}\n</domain_rules>`));
151
+ }
152
+ // 2. DATA & UI BLOCKS โ†’ USER ROLE (context for the LLM)
153
+ const data = builder.getData();
154
+ const uiBlocks = builder.getUiBlocks();
155
+ let userContent = '';
156
+ if (data) {
157
+ userContent += `<dataset>\n\`\`\`json\n${data}\n\`\`\`\n</dataset>\n\n`;
158
+ }
159
+ if (uiBlocks.length > 0) {
160
+ userContent += `<visual_context>\n${uiBlocks.map(b => b.content).join('\n\n')}\n</visual_context>\n\n`;
161
+ }
162
+ if (userContent.trim()) {
163
+ messages.push(PromptMessage.user(userContent.trim()));
164
+ }
165
+ // 3. AFFORDANCES โ†’ SYSTEM ROLE (hints + HATEOAS suggestions)
166
+ const hints = builder.getHints();
167
+ const suggestions = builder.getSuggestions();
168
+ if (hints.length > 0 || suggestions.length > 0) {
169
+ let guidance = '<system_guidance>\n';
170
+ if (hints.length > 0) {
171
+ guidance += hints.map(h => `Hint: ${h}`).join('\n') + '\n';
172
+ }
173
+ if (suggestions.length > 0) {
174
+ guidance += `Suggested Next Actions: ${suggestions.map(s => `${s.tool} (${s.reason})`).join(', ')}\n`;
175
+ }
176
+ guidance += '</system_guidance>';
177
+ messages.push(PromptMessage.system(guidance));
178
+ }
179
+ return messages;
180
+ },
103
181
  };
104
182
  //# sourceMappingURL=PromptMessage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PromptMessage.js","sourceRoot":"","sources":["../../../src/framework/prompt/PromptMessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAA6B,MAAM,kBAAkB,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB;;;;;;;;OAQG;IACH,MAAM,CAAC,IAAY;QACf,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,IAAY;QACb,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;IAC7D,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,IAAY;QAClB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;IAClE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAA0B,EAAE,IAAY,EAAE,QAAgB;QAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IAChE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAA0B,EAAE,IAAY,EAAE,QAAgB;QAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;IAChE,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CACJ,IAA0B,EAC1B,GAAW,EACX,OAA6D;QAE7D,OAAO;YACH,IAAI;YACJ,OAAO,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE;aAChC;SACJ,CAAC;IACN,CAAC;CACK,CAAC"}
1
+ {"version":3,"file":"PromptMessage.js","sourceRoot":"","sources":["../../../src/framework/prompt/PromptMessage.ts"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -339,6 +339,52 @@ handler: async function* (ctx, args) {
339
339
  // Wire format: { method: 'notifications/progress', params: { progressToken, progress: 25, total: 100, message: 'Loading data...' } }
340
340
  ```
341
341
 
342
+ ## Prompt Engine
343
+
344
+ Server-side hydrated prompt templates with schema-informed coercion and lifecycle sync. The `definePrompt()` factory enforces a **flat schema constraint** โ€” prompt arguments must be primitives (string, number, boolean, enum) because MCP clients render them as forms.
345
+
346
+ ```typescript
347
+ import { definePrompt, PromptMessage } from '@vinkius-core/mcp-fusion';
348
+
349
+ const SummarizePrompt = definePrompt<AppContext>('summarize', {
350
+ title: 'Summarize Document',
351
+ description: 'Generate a summary of a document.',
352
+ args: {
353
+ docId: 'string',
354
+ length: { enum: ['short', 'medium', 'long'] as const },
355
+ } as const,
356
+ handler: async (ctx, { docId, length }) => {
357
+ const doc = await ctx.db.documents.get(docId);
358
+ return {
359
+ messages: [
360
+ PromptMessage.system('You are a Senior Technical Writer.'),
361
+ PromptMessage.user(`Summarize this document (${length}):\n\n${doc.content}`),
362
+ ],
363
+ };
364
+ },
365
+ });
366
+ ```
367
+
368
+ ## MVA-Driven Prompts โ€” fromView()
369
+
370
+ Bridge your Presenter layer into Prompts with zero duplication. `PromptMessage.fromView()` decomposes a `ResponseBuilder` into XML-tagged prompt messages (`<domain_rules>`, `<dataset>`, `<visual_context>`, `<system_guidance>`) optimized for frontier LLMs. Domain rules, UI blocks, and action suggestions from the Presenter are automatically extracted โ€” single source of truth.
371
+
372
+ ```typescript
373
+ const AuditPrompt = definePrompt<AppContext>('audit', {
374
+ args: { invoiceId: 'string' } as const,
375
+ handler: async (ctx, { invoiceId }) => {
376
+ const invoice = await ctx.db.getInvoice(invoiceId);
377
+ return {
378
+ messages: [
379
+ PromptMessage.system('You are a Senior Financial Auditor.'),
380
+ ...PromptMessage.fromView(InvoicePresenter.make(invoice, ctx)),
381
+ PromptMessage.user('Begin the audit.'),
382
+ ],
383
+ };
384
+ },
385
+ });
386
+ ```
387
+
342
388
  ## Important Rules
343
389
 
344
390
  1. `.action()` and `.group()` are MUTUALLY EXCLUSIVE on the same builder
@@ -401,6 +447,17 @@ handler: async function* (ctx, args) {
401
447
  - `isProgressEvent(value)` โ†’ type guard
402
448
  - `ProgressSink` โ€” callback type `(event: ProgressEvent) => void` โ€” auto-wired by `attachToServer()`, or pass manually to `execute()` / `routeCall()` for testing
403
449
 
450
+ ### Prompt Engine
451
+ - `definePrompt<TContext>(name, config)` โ†’ PromptBuilder โ€” JSON-first or Zod schema for args, flat primitives only
452
+ - `PromptMessage.system(text)` โ†’ PromptMessagePayload (system instruction as MCP user role)
453
+ - `PromptMessage.user(text)` โ†’ PromptMessagePayload
454
+ - `PromptMessage.assistant(text)` โ†’ PromptMessagePayload (multi-turn seeding)
455
+ - `PromptMessage.image(role, data, mimeType)` โ†’ PromptMessagePayload
456
+ - `PromptMessage.audio(role, data, mimeType)` โ†’ PromptMessagePayload
457
+ - `PromptMessage.resource(role, uri, options?)` โ†’ PromptMessagePayload
458
+ - `PromptMessage.fromView(builder)` โ†’ PromptMessagePayload[] โ€” decomposes ResponseBuilder into XML-tagged messages (<domain_rules>, <dataset>, <visual_context>, <system_guidance>)
459
+ - `PromptRegistry<TContext>` โ€” .register(), .registerAll(), .getAllPrompts(), .getPrompts(filter), .routeGet(), .notifyChanged(), .has(), .clear(), .size
460
+
404
461
  ### Result Monad
405
462
  - `succeed<T>(value)` โ†’ Success<T>
406
463
  - `fail(response)` โ†’ Failure
@@ -440,6 +497,11 @@ handler: async function* (ctx, args) {
440
497
  - `ManifestTool` โ€” { description, tags, actions, input_schema }
441
498
  - `ManifestAction` โ€” { description, destructive, idempotent, readOnly, required_fields, returns_presenter }
442
499
  - `ManifestPresenter` โ€” { schema_keys, ui_blocks_supported, has_contextual_rules }
500
+ - `PromptResult` โ€” { description?: string, messages: PromptMessagePayload[] }
501
+ - `PromptMessagePayload` โ€” { role: 'user' | 'assistant', content: PromptContentBlock }
502
+ - `PromptContentBlock` โ€” PromptTextContent | PromptImageContent | PromptAudioContent | PromptResourceContent
503
+ - `PromptBuilder<TContext>` โ€” DIP interface: .name, .getDefinition(), .handleGet(), .tags
504
+ - `PromptConfig<TContext>` โ€” { title?, description?, args?, tags?, middleware?, handler }
443
505
 
444
506
  ### Domain Models
445
507
  - `BaseModel` โ€” abstract base (name, title, description, meta, icons)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinkius-core/mcp-fusion",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "MVA (Model-View-Agent) framework for the Model Context Protocol. Structured perception packages with Presenters, cognitive guardrails, self-healing errors, action consolidation, and tRPC-style type safety โ€” so AI agents perceive and act on your data deterministically.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",