yaml-flow 8.5.0 → 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.
Files changed (44) hide show
  1. package/browser/asset-integrity.json +3 -3
  2. package/browser/board-livecards-client.js +1 -1
  3. package/cli/browser-api/board-live-cards-browser-adapter.d.ts +1 -1
  4. package/cli/bundled/board-live-cards-cli.mjs +13 -13
  5. package/cli/bundled/chat-store-cli.mjs +13 -13
  6. package/cli/{types-D2s3VzyY.d.ts → types-H3EMBPY2.d.ts} +7 -2
  7. package/examples/board/demo-shell-with-server.html +2 -2
  8. package/examples/board/doc.html +2 -2
  9. package/examples/board/server/README-mcp-api.md +680 -0
  10. package/examples/board/test/server-http-mcp-test.js +391 -34
  11. package/examples/board-local/demo-shell-localstorage.html +3 -3
  12. package/lib/artifacts-store-public.d.cts +1 -1
  13. package/lib/artifacts-store-public.d.ts +1 -1
  14. package/lib/board-live-cards-mcp.cjs +1 -1
  15. package/lib/board-live-cards-mcp.d.cts +42 -5
  16. package/lib/board-live-cards-mcp.d.ts +42 -5
  17. package/lib/board-live-cards-mcp.js +1 -1
  18. package/lib/board-live-cards-node.cjs +14 -14
  19. package/lib/board-live-cards-node.d.cts +4 -4
  20. package/lib/board-live-cards-node.d.ts +4 -4
  21. package/lib/board-live-cards-node.js +14 -14
  22. package/lib/{board-live-cards-public-CvkDfZQ7.d.cts → board-live-cards-public-B13InXhC.d.cts} +7 -2
  23. package/lib/{board-live-cards-public-DdVhH4M-.d.ts → board-live-cards-public-BGS22cMb.d.ts} +7 -2
  24. package/lib/board-live-cards-public.cjs +1 -1
  25. package/lib/board-live-cards-public.d.cts +1 -1
  26. package/lib/board-live-cards-public.d.ts +1 -1
  27. package/lib/board-live-cards-public.js +1 -1
  28. package/lib/board-live-cards-server-runtime.cjs +4 -4
  29. package/lib/board-live-cards-server-runtime.d.cts +2 -2
  30. package/lib/board-live-cards-server-runtime.d.ts +2 -2
  31. package/lib/board-live-cards-server-runtime.js +4 -4
  32. package/lib/card-store-public.d.cts +1 -1
  33. package/lib/card-store-public.d.ts +1 -1
  34. package/lib/chat-store-public.cjs +1 -1
  35. package/lib/chat-store-public.d.cts +6 -1
  36. package/lib/chat-store-public.d.ts +6 -1
  37. package/lib/chat-store-public.js +1 -1
  38. package/lib/server-runtime/index.cjs +4 -4
  39. package/lib/server-runtime/index.d.cts +3 -3
  40. package/lib/server-runtime/index.d.ts +3 -3
  41. package/lib/server-runtime/index.js +4 -4
  42. package/lib/{types-QNI__eAf.d.ts → types-30R357js.d.ts} +1 -1
  43. package/lib/{types-NM_d_1oZ.d.cts → types-CIgsh56O.d.cts} +1 -1
  44. package/package.json +1 -1
@@ -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
+