yaml-flow 8.4.25 → 8.5.1
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/browser/asset-integrity.json +3 -3
- package/browser/board-livecards-client.js +1 -1
- package/cli/browser-api/board-live-cards-browser-adapter.d.ts +1 -1
- package/cli/browser-api/board-live-cards-browser-adapter.js +1 -1
- package/cli/bundled/board-live-cards-cli.mjs +14 -14
- package/cli/bundled/chat-store-cli.mjs +13 -13
- package/cli/{types-juH2nFpz.d.ts → types-H3EMBPY2.d.ts} +10 -4
- package/examples/board/demo-shell-with-server.html +2 -2
- package/examples/board/doc.html +2 -2
- package/examples/board/server/README-mcp-api.md +680 -0
- package/examples/board/server/board-server.js +4 -0
- package/examples/board/server/chat-flow/copilot-chat/assistant.js +4 -2
- package/examples/board/server/chat-flow/flow-steps.json +9 -8
- package/examples/board/test/server-http-mcp-test.js +1148 -0
- package/examples/board/test/server-http-test.js +7 -7
- package/examples/board-local/demo-shell-localstorage.html +3 -3
- package/lib/artifacts-store-public.d.cts +1 -1
- package/lib/artifacts-store-public.d.ts +1 -1
- package/lib/board-live-cards-mcp.cjs +2 -0
- package/lib/board-live-cards-mcp.d.cts +296 -0
- package/lib/board-live-cards-mcp.d.ts +296 -0
- package/lib/board-live-cards-mcp.js +2 -0
- package/lib/board-live-cards-node.cjs +14 -14
- package/lib/board-live-cards-node.d.cts +8 -6
- package/lib/board-live-cards-node.d.ts +8 -6
- package/lib/board-live-cards-node.js +14 -14
- package/lib/{board-live-cards-public-B4RcYPC_.d.cts → board-live-cards-public-B13InXhC.d.cts} +8 -3
- package/lib/{board-live-cards-public-ydXuA4zh.d.ts → board-live-cards-public-BGS22cMb.d.ts} +8 -3
- package/lib/board-live-cards-public.cjs +1 -1
- package/lib/board-live-cards-public.d.cts +1 -1
- package/lib/board-live-cards-public.d.ts +1 -1
- package/lib/board-live-cards-public.js +1 -1
- package/lib/board-live-cards-server-runtime.cjs +5 -4
- package/lib/board-live-cards-server-runtime.d.cts +3 -3
- package/lib/board-live-cards-server-runtime.d.ts +3 -3
- package/lib/board-live-cards-server-runtime.js +5 -4
- package/lib/card-store-public.d.cts +1 -1
- package/lib/card-store-public.d.ts +1 -1
- package/lib/{chat-storage-lib-B1wU27y3.d.cts → chat-storage-lib-0imhRX3l.d.cts} +2 -1
- package/lib/{chat-storage-lib-DsF4kPon.d.ts → chat-storage-lib-CJn7a6OH.d.ts} +2 -1
- package/lib/chat-store-public.cjs +1 -1
- package/lib/chat-store-public.d.cts +7 -2
- package/lib/chat-store-public.d.ts +7 -2
- package/lib/chat-store-public.js +1 -1
- package/lib/server-runtime/index.cjs +5 -4
- package/lib/server-runtime/index.d.cts +4 -4
- package/lib/server-runtime/index.d.ts +4 -4
- package/lib/server-runtime/index.js +5 -4
- package/lib/{types-DwPRb-PY.d.ts → types-30R357js.d.ts} +3 -2
- package/lib/{types-BpfMamGs.d.cts → types-CIgsh56O.d.cts} +3 -2
- package/package.json +10 -2
- package/browser/board-livecards-localstorage.js +0 -10
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
# Board Server — MCP API Reference
|
|
2
|
+
|
|
3
|
+
Every board server exposes two MCP endpoints under `/api/boards/:boardId`:
|
|
4
|
+
|
|
5
|
+
| Endpoint | Content-Type | Purpose |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `POST /api/boards/:boardId/mcp` | `application/json` → `application/json` | All tools except file downloads |
|
|
8
|
+
| `POST /api/boards/:boardId/mcp-raw` | `application/json` → `application/octet-stream` | File content download only (`inspect.file-contents`) |
|
|
9
|
+
|
|
10
|
+
## Request / response shape
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
// POST /api/boards/:boardId/mcp
|
|
14
|
+
{
|
|
15
|
+
"tool": "<tool-name>",
|
|
16
|
+
"args": { ... }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Response (200)
|
|
20
|
+
{
|
|
21
|
+
"status": "success",
|
|
22
|
+
"data": { ... }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Error (400 / 500)
|
|
26
|
+
{
|
|
27
|
+
"error": "message"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Tool reference
|
|
34
|
+
|
|
35
|
+
### `discover.source-kinds`
|
|
36
|
+
|
|
37
|
+
Returns the known source-kind registry from the task executor.
|
|
38
|
+
|
|
39
|
+
**Args:** none
|
|
40
|
+
|
|
41
|
+
**Returns:**
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"status": "success",
|
|
45
|
+
"data": {
|
|
46
|
+
"version": "...",
|
|
47
|
+
"commonSourceFields": { ... },
|
|
48
|
+
"sourceKinds": { "<kind>": { ... } }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### `inspect.board-runtime-status`
|
|
56
|
+
|
|
57
|
+
Returns a summary of all registered cards and overall board state.
|
|
58
|
+
|
|
59
|
+
**Args:** none
|
|
60
|
+
|
|
61
|
+
**Returns:**
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"status": "success",
|
|
65
|
+
"data": {
|
|
66
|
+
"meta": { ... },
|
|
67
|
+
"summary": {
|
|
68
|
+
"card_count": 2,
|
|
69
|
+
"completed": 1,
|
|
70
|
+
"eligible": 0,
|
|
71
|
+
"pending": 0,
|
|
72
|
+
"blocked": 0,
|
|
73
|
+
"in_progress": 1,
|
|
74
|
+
"failed": 0,
|
|
75
|
+
"unresolved": 0
|
|
76
|
+
},
|
|
77
|
+
"cards": [
|
|
78
|
+
{
|
|
79
|
+
"card-id": "my-card",
|
|
80
|
+
"status": "completed",
|
|
81
|
+
"error": null,
|
|
82
|
+
"requires": [],
|
|
83
|
+
"requires_satisfied": [],
|
|
84
|
+
"requires_missing": [],
|
|
85
|
+
"provides_declared": ["output-key"],
|
|
86
|
+
"provides_runtime": ["output-key"]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
### `inspect.card-definition-and-runtime`
|
|
96
|
+
|
|
97
|
+
Returns the full card definition, its runtime state, and the current values of all `provides` outputs.
|
|
98
|
+
|
|
99
|
+
**Args:**
|
|
100
|
+
|
|
101
|
+
| Field | Type | Required |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `card_id` | string | yes |
|
|
104
|
+
|
|
105
|
+
**Returns:**
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"status": "success",
|
|
109
|
+
"data": {
|
|
110
|
+
"cardId": "my-card",
|
|
111
|
+
"card_status_in_board": {
|
|
112
|
+
"name": "my-card",
|
|
113
|
+
"status": "completed",
|
|
114
|
+
"error": null,
|
|
115
|
+
"requires": [],
|
|
116
|
+
"requires_satisfied": [],
|
|
117
|
+
"requires_missing": [],
|
|
118
|
+
"provides_declared": ["output-key"],
|
|
119
|
+
"provides_runtime": ["output-key"]
|
|
120
|
+
},
|
|
121
|
+
"card_definition_and_static_data": {
|
|
122
|
+
"id": "my-card",
|
|
123
|
+
"card_data": { ... },
|
|
124
|
+
"source_defs": [ ... ]
|
|
125
|
+
},
|
|
126
|
+
"refs_for_fetched_source_files": {
|
|
127
|
+
"output.json": "sha256:abc123..."
|
|
128
|
+
},
|
|
129
|
+
"runtime_data": {
|
|
130
|
+
"requires": { "upstream-key": { ... } },
|
|
131
|
+
"provides": { "output-key": { ... } },
|
|
132
|
+
"computed_values": { ... },
|
|
133
|
+
"rendered_view": {
|
|
134
|
+
"layout": "...",
|
|
135
|
+
"features": { ... },
|
|
136
|
+
"elements": [ { "id": "el1", "kind": "text", "label": "Output", "visible": true, "resolved": "..." } ]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### `inspect.chat-messages-on-cards`
|
|
146
|
+
|
|
147
|
+
Returns chat records for one or all cards, with flexible filtering.
|
|
148
|
+
|
|
149
|
+
**Args:**
|
|
150
|
+
|
|
151
|
+
| Field | Type | Default | Notes |
|
|
152
|
+
|---|---|---|---|
|
|
153
|
+
| `card_id` | string | — | Target card |
|
|
154
|
+
| `all-turns` | boolean | `false` | Return all turns (ignores `tail-turns`) |
|
|
155
|
+
| `tail-turns` | number | — | Last N user turns only |
|
|
156
|
+
| `tail` | number | — | Last N individual messages |
|
|
157
|
+
| `turn-id` | string | — | Only messages with this turn id |
|
|
158
|
+
| `tail-turns-before-id` | string | — | Requires `tail-turns`; messages before the given turn id |
|
|
159
|
+
|
|
160
|
+
**Returns:**
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"status": "success",
|
|
164
|
+
"data": {
|
|
165
|
+
"cardId": "my-card",
|
|
166
|
+
"messages": [
|
|
167
|
+
{ "role": "user", "text": "hello", "turn": "abc123", "ts": "2026-05-28T10:00:00.000Z" },
|
|
168
|
+
{ "role": "system", "text": "processing...", "turn": "abc123", "ts": "2026-05-28T10:00:00.100Z" },
|
|
169
|
+
{ "role": "assistant","text": "hi there", "turn": "abc123", "ts": "2026-05-28T10:00:01.200Z" }
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
When a system message references a file attachment, a `retrieval_hint` field is added:
|
|
176
|
+
```json
|
|
177
|
+
{ "role": "system", "text": "file uploaded: report.pdf as abc.pdf #0", "turn": "abc123",
|
|
178
|
+
"retrieval_hint": "Retrieve using inspect-file-contents --card-id my-card --file-idx 0" }
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### `inspect.file-contents` _(only on `/mcp-raw`)_
|
|
184
|
+
|
|
185
|
+
Downloads the raw bytes of a file attachment stored on a card.
|
|
186
|
+
|
|
187
|
+
**Endpoint:** `POST /api/boards/:boardId/mcp-raw`
|
|
188
|
+
|
|
189
|
+
**Args:**
|
|
190
|
+
|
|
191
|
+
| Field | Type | Required |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| `card_id` | string | yes |
|
|
194
|
+
| `file_idx` | number | yes |
|
|
195
|
+
|
|
196
|
+
**On `/mcp-raw`:** returns raw bytes (`application/octet-stream`) with headers:
|
|
197
|
+
- `Content-Disposition: attachment; filename="<name>"`
|
|
198
|
+
- `Content-Type: <mime_type>`
|
|
199
|
+
|
|
200
|
+
**On `/mcp`:** this tool is rejected. Use `/mcp-raw`.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### `manage.read-card`
|
|
205
|
+
|
|
206
|
+
Reads the stored document for a single live card.
|
|
207
|
+
|
|
208
|
+
**Args:**
|
|
209
|
+
|
|
210
|
+
| Field | Type | Required |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `card_id` | string | yes |
|
|
213
|
+
|
|
214
|
+
**Returns:** array containing the matching live card document (empty array if not found), wrapped in the MCP success envelope:
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"status": "success",
|
|
218
|
+
"data": [
|
|
219
|
+
{
|
|
220
|
+
"id": "my-card",
|
|
221
|
+
"card_data": {
|
|
222
|
+
"id": "my-card",
|
|
223
|
+
"sources": [ ... ],
|
|
224
|
+
"compute": { ... },
|
|
225
|
+
"files": [ { "name": "report.pdf", "stored_name": "abc.pdf", "mime_type": "application/pdf", "size": 1024 } ]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### `manage.upsert-card`
|
|
235
|
+
|
|
236
|
+
Validates, stores, and registers a card definition. Triggers a board restart for the card.
|
|
237
|
+
|
|
238
|
+
**Args:**
|
|
239
|
+
|
|
240
|
+
| Field | Type | Required |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| `card_id` | string | yes |
|
|
243
|
+
| `candidate_card_content` | object | yes — must include `id` matching `card_id` |
|
|
244
|
+
|
|
245
|
+
**Returns (success):**
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"status": "success",
|
|
249
|
+
"data": {
|
|
250
|
+
"validation": { "status": "success", "data": { "isValid": true } },
|
|
251
|
+
"card_saved": null,
|
|
252
|
+
"board_result": { "status": "success" },
|
|
253
|
+
"refresh_notify": { "status": "success" }
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Returns (validation failure):**
|
|
259
|
+
```json
|
|
260
|
+
{ "error": "Validation failed" }
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### `manage.deprecate`
|
|
266
|
+
|
|
267
|
+
Removes a card from the board.
|
|
268
|
+
|
|
269
|
+
**Args:**
|
|
270
|
+
|
|
271
|
+
| Field | Type | Required |
|
|
272
|
+
|---|---|---|
|
|
273
|
+
| `card_id` | string | yes |
|
|
274
|
+
|
|
275
|
+
**Returns:** the `board.removeCard` result normalized into the MCP success envelope. On success:
|
|
276
|
+
```json
|
|
277
|
+
{ "status": "success", "data": {} }
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### `manage.upload-card-file`
|
|
283
|
+
|
|
284
|
+
Uploads a file to a card's attachment store (outside the chat flow).
|
|
285
|
+
|
|
286
|
+
**Args — provide exactly one of `bytes`, `text`, or `base64`:**
|
|
287
|
+
|
|
288
|
+
| Field | Type | Notes |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| `card_id` | string | required |
|
|
291
|
+
| `file_name` | string | required |
|
|
292
|
+
| `content_type` | string | optional, default `application/octet-stream` |
|
|
293
|
+
| `bytes` | number[] | raw byte array |
|
|
294
|
+
| `text` | string | UTF-8 encoded |
|
|
295
|
+
| `base64` | string | base64 or base64url encoded |
|
|
296
|
+
|
|
297
|
+
**Returns:** the stored file metadata object in the MCP success envelope:
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"status": "success",
|
|
301
|
+
"data": {
|
|
302
|
+
"ok": true,
|
|
303
|
+
"file": {
|
|
304
|
+
"fileIdx": 2,
|
|
305
|
+
"name": "report.pdf",
|
|
306
|
+
"stored_name": "abc123.pdf",
|
|
307
|
+
"mime_type": "application/pdf",
|
|
308
|
+
"size": 204800,
|
|
309
|
+
"uploaded_at": "2026-05-28T10:00:00.000Z"
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
### `stage-ai-response-and-any-attachments`
|
|
318
|
+
|
|
319
|
+
Stages an assistant response (with optional file attachments) directly into a card's chat store. Used by agent pipelines to inject a response without going through the SSE chat flow.
|
|
320
|
+
|
|
321
|
+
**Args:**
|
|
322
|
+
|
|
323
|
+
| Field | Type | Notes |
|
|
324
|
+
|---|---|---|
|
|
325
|
+
| `card_id` | string | required |
|
|
326
|
+
| `text` | string | response text |
|
|
327
|
+
| `turn-id` | string | turn id to associate the message with |
|
|
328
|
+
| `files` | array | optional array of file metadata objects |
|
|
329
|
+
|
|
330
|
+
**Returns:**
|
|
331
|
+
```json
|
|
332
|
+
{
|
|
333
|
+
"status": "success",
|
|
334
|
+
"data": {
|
|
335
|
+
"cardId": "my-card",
|
|
336
|
+
"id": "msg-uuid-...",
|
|
337
|
+
"role": "assistant",
|
|
338
|
+
"turn": "abc123",
|
|
339
|
+
"files": []
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## `preflight.*` tools
|
|
347
|
+
|
|
348
|
+
Preflight tools let you test a **candidate card definition** in-memory without committing it to the board.
|
|
349
|
+
|
|
350
|
+
### Quick Reference
|
|
351
|
+
|
|
352
|
+
All preflight tools are invoked through:
|
|
353
|
+
|
|
354
|
+
```json
|
|
355
|
+
{
|
|
356
|
+
"tool": "preflight.<name>",
|
|
357
|
+
"args": { ... }
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
| Tool | MCP `args` shape | Success `data` shape |
|
|
362
|
+
|---|---|---|
|
|
363
|
+
| `preflight.validate-candidate-card-definition` | `{ "candidate_card_content": <card> }` | `{ "cardId": string, "isValid": boolean, "issues": string[] }` |
|
|
364
|
+
| `preflight.materialize-candidate-card` | `{ "candidate_card_content": <card>, "mock_requires": {}, "mock_fetched_sources": {} }` | `{ "cardId": string, "ok": boolean, "computed_values": object, "errors": Array<{ bindTo, error }>, "provides_outputs": object, "rendered_view": object }` |
|
|
365
|
+
| `preflight.probe-single-source-in-candidate-card` | `{ "candidate_card_content": <card>, "source_idx": number, "mock_projections": {} }` | `{ "bindTo": string, "reachable": boolean, "latencyMs"?: number, "note"?: string }` |
|
|
366
|
+
| `preflight.run-single-source-in-candidate-card` | `{ "candidate_card_content": <card>, "source_idx": number, "mock_projections": {} }` | `{ "bindTo": string, "ok": boolean, "result": unknown, "issues": string[] }` |
|
|
367
|
+
| `preflight.run-single-source-in-live-card` | `{ "card_id": string, "source_idx": number, "mock_requires": {} }` | `{ "bindTo": string, "ok": boolean, "result": unknown, "issues": string[] }` |
|
|
368
|
+
| `preflight.run-one-cycle-with-candidate-card` | `{ "candidate_card_content": <card>, "mock_requires": {} }` | `{ "cardId": string, "ok": boolean, "issues": string[], "provides_outputs": object, "rendered_view": object }` |
|
|
369
|
+
|
|
370
|
+
Unless otherwise noted, successful HTTP responses use the normal MCP envelope:
|
|
371
|
+
|
|
372
|
+
```json
|
|
373
|
+
{
|
|
374
|
+
"status": "success",
|
|
375
|
+
"data": { ... }
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### `preflight.validate-candidate-card-definition`
|
|
380
|
+
|
|
381
|
+
Schema-validates a candidate card.
|
|
382
|
+
|
|
383
|
+
**Args:**
|
|
384
|
+
|
|
385
|
+
| Field | Type | Required |
|
|
386
|
+
|---|---|---|
|
|
387
|
+
| `candidate_card_content` | object | yes |
|
|
388
|
+
|
|
389
|
+
**MCP request body:**
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"tool": "preflight.validate-candidate-card-definition",
|
|
393
|
+
"args": {
|
|
394
|
+
"candidate_card_content": { "id": "my-card", "card_data": {} }
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Returns (valid):**
|
|
400
|
+
```json
|
|
401
|
+
{ "status": "success", "data": { "cardId": "my-card", "isValid": true, "issues": [] } }
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Returns (invalid):** outer `status` is still `"success"` — the validator ran cleanly, it just found problems:
|
|
405
|
+
```json
|
|
406
|
+
{ "status": "success", "data": { "cardId": "my-card", "isValid": false, "issues": [ "view.elements[0].kind is required", "source_defs[0].bindTo is duplicate" ] } }
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### `preflight.materialize-candidate-card`
|
|
412
|
+
|
|
413
|
+
Evaluates the card's `compute[]` steps with the supplied mocks. Does **not** run sources and does **not** produce a rendered view — use `preflight.run-one-cycle-with-candidate-card` for a full pipeline simulation.
|
|
414
|
+
|
|
415
|
+
**Args:**
|
|
416
|
+
|
|
417
|
+
| Field | Type | Notes |
|
|
418
|
+
|---|---|---|
|
|
419
|
+
| `candidate_card_content` | object | required |
|
|
420
|
+
| `mock_requires` | object | required — may be empty, but the key must be present |
|
|
421
|
+
| `mock_fetched_sources` | object | required — may be empty, but the key must be present |
|
|
422
|
+
|
|
423
|
+
**MCP request body:**
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"tool": "preflight.materialize-candidate-card",
|
|
427
|
+
"args": {
|
|
428
|
+
"candidate_card_content": { "id": "my-card", "card_data": {}, "compute": [] },
|
|
429
|
+
"mock_requires": {},
|
|
430
|
+
"mock_fetched_sources": {}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Returns:**
|
|
436
|
+
```json
|
|
437
|
+
{
|
|
438
|
+
"status": "success",
|
|
439
|
+
"data": {
|
|
440
|
+
"cardId": "my-card",
|
|
441
|
+
"ok": true,
|
|
442
|
+
"computed_values": { "title": "My Report", "count": 42 },
|
|
443
|
+
"errors": [],
|
|
444
|
+
"provides_outputs": {
|
|
445
|
+
"output-key": { "title": "My Report", "count": 42 }
|
|
446
|
+
},
|
|
447
|
+
"rendered_view": {
|
|
448
|
+
"layout": "stack",
|
|
449
|
+
"features": {},
|
|
450
|
+
"elements": [
|
|
451
|
+
{ "id": "summary", "kind": "text", "label": "Summary", "visible": true, "resolved": "My Report" }
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
`errors` is an array of `{ "bindTo": string, "error": string }`. On compute failure `ok` is `false` and `errors` lists each broken binding:
|
|
459
|
+
```json
|
|
460
|
+
{ "status": "success", "data": { "cardId": "my-card", "ok": false, "computed_values": {}, "errors": [ { "bindTo": "title", "error": "undefined variable" } ], "provides_outputs": {}, "rendered_view": { "layout": null, "features": null, "elements": [] } } }
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
If `mock_requires` or `mock_fetched_sources` is omitted entirely, the MCP call fails with a 400-style error such as `{ "error": "MCP tool requires mock_requires" }`.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
### `preflight.probe-single-source-in-candidate-card`
|
|
468
|
+
|
|
469
|
+
Calls the registered task executor's `probe-source-preflight` hook for a single source in a candidate card — tests reachability without fetching data. **Requires a task executor to be registered**; returns an error if none is configured.
|
|
470
|
+
|
|
471
|
+
**Args:**
|
|
472
|
+
|
|
473
|
+
| Field | Type | Notes |
|
|
474
|
+
|---|---|---|
|
|
475
|
+
| `candidate_card_content` | object | required |
|
|
476
|
+
| `source_idx` | number | index into the card's `source_defs` array |
|
|
477
|
+
| `mock_projections` | object | optional mock projection data |
|
|
478
|
+
|
|
479
|
+
**MCP request body:**
|
|
480
|
+
```json
|
|
481
|
+
{
|
|
482
|
+
"tool": "preflight.probe-single-source-in-candidate-card",
|
|
483
|
+
"args": {
|
|
484
|
+
"candidate_card_content": { "id": "my-card", "card_data": {}, "source_defs": [ ... ] },
|
|
485
|
+
"source_idx": 0,
|
|
486
|
+
"mock_projections": {}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**Returns:** connectivity / readiness metadata for the source — does **not** return fetched data:
|
|
492
|
+
```json
|
|
493
|
+
{
|
|
494
|
+
"status": "success",
|
|
495
|
+
"data": {
|
|
496
|
+
"bindTo": "my-source",
|
|
497
|
+
"reachable": true,
|
|
498
|
+
"latencyMs": 45,
|
|
499
|
+
"note": "endpoint reachable"
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
> If no task executor is configured the call fails with an HTTP error such as `{ "error": "No task-executor registered for this board" }`.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
### `preflight.run-single-source-in-candidate-card`
|
|
509
|
+
|
|
510
|
+
Executes a single source in a candidate card and returns the real fetched output. This path is live-fetch-only and **requires a configured task executor**.
|
|
511
|
+
|
|
512
|
+
**Args:**
|
|
513
|
+
|
|
514
|
+
| Field | Type | Notes |
|
|
515
|
+
|---|---|---|
|
|
516
|
+
| `candidate_card_content` | object | required |
|
|
517
|
+
| `source_idx` | number | index into the card's `source_defs` array |
|
|
518
|
+
| `mock_projections` | object | optional mock projection data |
|
|
519
|
+
|
|
520
|
+
**MCP request body:**
|
|
521
|
+
```json
|
|
522
|
+
{
|
|
523
|
+
"tool": "preflight.run-single-source-in-candidate-card",
|
|
524
|
+
"args": {
|
|
525
|
+
"candidate_card_content": { "id": "my-card", "card_data": {}, "source_defs": [ ... ] },
|
|
526
|
+
"source_idx": 0,
|
|
527
|
+
"mock_projections": {}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Returns:**
|
|
533
|
+
```json
|
|
534
|
+
{
|
|
535
|
+
"status": "success",
|
|
536
|
+
"data": {
|
|
537
|
+
"bindTo": "my-source",
|
|
538
|
+
"ok": true,
|
|
539
|
+
"result": { "items": [ ... ] },
|
|
540
|
+
"issues": []
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
On live fetch failure the command still returns `status: "success"`, but with `ok: false` and a populated `issues` list:
|
|
546
|
+
|
|
547
|
+
```json
|
|
548
|
+
{
|
|
549
|
+
"status": "success",
|
|
550
|
+
"data": {
|
|
551
|
+
"bindTo": "my-source",
|
|
552
|
+
"ok": false,
|
|
553
|
+
"result": null,
|
|
554
|
+
"issues": ["Probe failed: network timeout"]
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
Field notes:
|
|
560
|
+
|
|
561
|
+
- `result` is parsed JSON when possible; otherwise it is returned as a raw string
|
|
562
|
+
- `issues` is empty on success and contains live-fetch errors when `ok` is `false`
|
|
563
|
+
- If no task executor is configured, the call fails with an HTTP error such as `{ "error": "No task-executor registered for this board" }`
|
|
564
|
+
- Request-shape problems such as an out-of-range `source_idx` also fail with an HTTP error, for example `{ "error": "sourceIdx 4 out of range (card has 1 source(s))" }`
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
### `preflight.run-single-source-in-live-card`
|
|
569
|
+
|
|
570
|
+
Executes a single source using an already-saved live card in card storage. This is useful when you want run-source behavior without supplying `candidate_card_content`.
|
|
571
|
+
|
|
572
|
+
**Args:**
|
|
573
|
+
|
|
574
|
+
| Field | Type | Notes |
|
|
575
|
+
|---|---|---|
|
|
576
|
+
| `card_id` | string | required; id of an existing live card |
|
|
577
|
+
| `source_idx` | number | required; index into the card's `source_defs` array |
|
|
578
|
+
| `mock_requires` | object | required; same contract as `preflight.run-one-cycle-with-candidate-card` |
|
|
579
|
+
|
|
580
|
+
**MCP request body:**
|
|
581
|
+
```json
|
|
582
|
+
{
|
|
583
|
+
"tool": "preflight.run-single-source-in-live-card",
|
|
584
|
+
"args": {
|
|
585
|
+
"card_id": "card-market-prices",
|
|
586
|
+
"source_idx": 0,
|
|
587
|
+
"mock_requires": {}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Returns:** same shape as `preflight.run-single-source-in-candidate-card`:
|
|
593
|
+
```json
|
|
594
|
+
{
|
|
595
|
+
"status": "success",
|
|
596
|
+
"data": {
|
|
597
|
+
"bindTo": "my-source",
|
|
598
|
+
"ok": true,
|
|
599
|
+
"result": { "items": [ ... ] },
|
|
600
|
+
"issues": []
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
On execution failure this still returns `status: "success"` with `ok: false` and `issues` populated.
|
|
606
|
+
|
|
607
|
+
```json
|
|
608
|
+
{
|
|
609
|
+
"status": "success",
|
|
610
|
+
"data": {
|
|
611
|
+
"bindTo": "my-source",
|
|
612
|
+
"ok": false,
|
|
613
|
+
"result": null,
|
|
614
|
+
"issues": ["Probe failed: network timeout"]
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
Request/config errors fail with HTTP error envelopes, for example:
|
|
620
|
+
|
|
621
|
+
- `{ "error": "Card \"missing-card\" not found" }`
|
|
622
|
+
- `{ "error": "sourceIdx 4 out of range (card has 1 source(s))" }`
|
|
623
|
+
- `{ "error": "MCP tool requires mock_requires" }`
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
### `preflight.run-one-cycle-with-candidate-card`
|
|
628
|
+
|
|
629
|
+
Runs a full computation cycle (all sources → compute) against a candidate card in-memory and returns the simplified MCP-facing runtime shape. Nothing is persisted.
|
|
630
|
+
|
|
631
|
+
**Args:**
|
|
632
|
+
|
|
633
|
+
| Field | Type | Notes |
|
|
634
|
+
|---|---|---|
|
|
635
|
+
| `candidate_card_content` | object | required |
|
|
636
|
+
| `mock_requires` | object | optional mock values for `requires` keys |
|
|
637
|
+
|
|
638
|
+
**MCP request body:**
|
|
639
|
+
```json
|
|
640
|
+
{
|
|
641
|
+
"tool": "preflight.run-one-cycle-with-candidate-card",
|
|
642
|
+
"args": {
|
|
643
|
+
"candidate_card_content": { "id": "my-card", "card_data": {}, "provides": [], "view": {} },
|
|
644
|
+
"mock_requires": {}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
**Returns:**
|
|
650
|
+
```json
|
|
651
|
+
{
|
|
652
|
+
"status": "success",
|
|
653
|
+
"data": {
|
|
654
|
+
"cardId": "my-card",
|
|
655
|
+
"ok": true,
|
|
656
|
+
"issues": [],
|
|
657
|
+
"provides_outputs": {
|
|
658
|
+
"output-key": { "title": "My Report", "count": 42 }
|
|
659
|
+
},
|
|
660
|
+
"rendered_view": {
|
|
661
|
+
"layout": "stack",
|
|
662
|
+
"features": {},
|
|
663
|
+
"elements": [
|
|
664
|
+
{ "id": "summary", "kind": "text", "label": "Summary", "visible": true, "resolved": "My Report" }
|
|
665
|
+
]
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
Field notes:
|
|
672
|
+
|
|
673
|
+
- `issues` is a flattened list built from validation issues, source probe errors, projection errors, and compute errors
|
|
674
|
+
- `provides_outputs` is resolved from the card's public `provides[]` bindings; if no `provides[]` is declared, the default binding is `{ "bindTo": cardId, "ref": "card_data" }`
|
|
675
|
+
- `rendered_view` is materialized from the simulated runtime node using the card's `view`
|
|
676
|
+
- The MCP facade intentionally hides low-level `validation`, `source_probes`, `projection_errors`, and `compute_errors` details behind `ok` + `issues`
|
|
677
|
+
|
|
678
|
+
---
|
|
679
|
+
|
|
680
|
+
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
buildLocalBaseSpec,
|
|
18
18
|
createFsBoardPlatformAdapter,
|
|
19
|
+
createFsBoardNonCorePlatformAdapter,
|
|
19
20
|
createFsBoardChatStorage,
|
|
20
21
|
createNodeSpawnInvocationAdapter,
|
|
21
22
|
createArtifactsStore,
|
|
@@ -301,7 +302,9 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
301
302
|
const notifyChannel = `yaml-flow-server-${label}-${boardId}-${process.pid}`;
|
|
302
303
|
const baseRef = parseRef(serializeRef({ kind: 'fs-path', value: boardDir }));
|
|
303
304
|
const boardAdapter = createFsBoardPlatformAdapter(baseRef, { notifyChannel });
|
|
305
|
+
const nonCoreAdapter = createFsBoardNonCorePlatformAdapter(baseRef, { notifyChannel });
|
|
304
306
|
boardAdapter.requestProcessAccumulated = () => {};
|
|
307
|
+
nonCoreAdapter.requestProcessAccumulated = () => {};
|
|
305
308
|
|
|
306
309
|
const artifactsRef = parseRef(serializeRef({ kind: 'fs-path', value: runtimeCardsDir }));
|
|
307
310
|
const artifactsAdapter = createFsBoardPlatformAdapter(artifactsRef, { suppressSpawn: true });
|
|
@@ -313,6 +316,7 @@ function buildBoardContextConfig(label, boardDir, taskExecPath, chatHandlerFlow,
|
|
|
313
316
|
return {
|
|
314
317
|
label,
|
|
315
318
|
boardAdapter,
|
|
319
|
+
nonCoreAdapter,
|
|
316
320
|
artifactsAdapter,
|
|
317
321
|
baseRef,
|
|
318
322
|
cardStoreRef,
|