@foldkit/devtools-mcp 0.24.1-canary.bfd880b1e6ca → 0.24.1-canary.c55d84c8199b

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/README.md CHANGED
@@ -6,7 +6,7 @@ With it attached, agents can:
6
6
 
7
7
  - Read the current Model, or any historical Model by history index
8
8
  - Narrow reads with dot-string paths and summarized payloads to fit token budgets
9
- - List and inspect the Message history, with Command and Mount lifecycle, diffs, and Block chains
9
+ - List and inspect the Message history, with Command and Mount lifecycle, diffs, and Submodel chains
10
10
  - Query history server-side: filter entries by changed Model paths, count Messages by tag, tail the latest entries, and diff the Models at two indices
11
11
  - Read the recorded init Model, the Commands returned from `init`, and the Mounts that fired during the first render
12
12
  - Inspect Runtime state: current index, retained history bounds, pause status
@@ -36,10 +36,10 @@ pnpm add -D @foldkit/devtools-mcp
36
36
  yarn add -D @foldkit/devtools-mcp
37
37
  ```
38
38
 
39
- Pass your `Message` Schema as `devTools.Message` when calling the Application Composition's owned `assembleApplication` method to let the agent dispatch Messages. The Runtime rejects a payload that does not match the Schema before it reaches update:
39
+ Pass your `Message` Schema to `Runtime.makeApplication` to let the agent dispatch Messages. The Runtime rejects a payload that does not match the Schema before it reaches update:
40
40
 
41
41
  ```typescript
42
- ApplicationComposition.assembleApplication({
42
+ Runtime.makeApplication({
43
43
  devTools: {
44
44
  // Rest of your DevTools config
45
45
  Message,
@@ -70,7 +70,7 @@ Every tool except `foldkit_list_runtimes` accepts an optional `runtime_id`. With
70
70
  | `foldkit_get_model_at` | Snapshots a historical Model after a given history entry. Pass `index: N - 1` to read the Model just before Message `N`. Same `path`/`expand` semantics as `foldkit_get_model`. Indices outside the readable range (older entries are evicted past the rolling buffer) are rejected with the valid bounds. For the initial Model (and the init Commands and Mounts), use `foldkit_get_init`. |
71
71
  | `foldkit_get_init` | Reads the recorded initial Model, the Commands returned from the application's `init` function, and the Mounts that fired during the first render. Each Command and Mount carries its declared args. Equivalent to selecting the synthetic "init" row in the DevTools panel. |
72
72
  | `foldkit_get_runtime_state` | Snapshots the Runtime's DevTools state: history bounds, current paused/live status, and whether init is recorded. Useful for understanding what `foldkit_list_messages` and `foldkit_get_message` will see and detecting whether the Runtime is paused. |
73
- | `foldkit_list_messages` | Lists Message history entries. Each entry carries the Message body, Commands triggered (with args), Mounts that started or ended during the resulting render (with args), timestamp, an `isModelChanged` flag, the diff path lists (`changedPaths` / `affectedPaths`), and any extracted Block chain. Filter server-side with `changed_paths_match`, read the latest entries with `from_end`, and paginate forward with `since_index`. |
73
+ | `foldkit_list_messages` | Lists Message history entries. Each entry carries the Message body, Commands triggered (with args), Mounts that started or ended during the resulting render (with args), timestamp, an `isModelChanged` flag, the diff path lists (`changedPaths` / `affectedPaths`), and any extracted Submodel chain. Filter server-side with `changed_paths_match`, read the latest entries with `from_end`, and paginate forward with `since_index`. |
74
74
  | `foldkit_count_messages_by_tag` | Counts retained history entries by Message tag, without payloads, sorted by count descending. A cheap reconnaissance call before paging through history: it surfaces the high-frequency Messages worth filtering out, and with `changed_paths_match` it answers which Message tags touch a Model subtree. |
75
75
  | `foldkit_diff_models` | Diffs the Models at two history indices server-side, returning path-level changes `{ path, before, after }` with summarized values. Each side is `{ _tag: 'Present', value }`, or `{ _tag: 'Absent' }` when the path does not exist on that side. Pass `changed_paths_match` to narrow the diff to a subtree. |
76
76
  | `foldkit_get_message` | Reads one entry at a given index. The response carries the SerializedEntry only; to inspect the Model around the entry, call `foldkit_get_model_at` with `index - 1` (before) and `index` (after). Use `foldkit_get_init` for the synthetic init entry. |
package/dist/install.js CHANGED
@@ -36,9 +36,9 @@ const printNextSteps = (alreadyRegistered) => {
36
36
  console.log('');
37
37
  console.log('Next steps:');
38
38
  console.log('');
39
- console.log(' 1. Pass the complete Message Codec to ApplicationComposition.assembleApplication (enables dispatch):');
39
+ console.log(' 1. Pass your Message Schema to Runtime.makeApplication (enables dispatch):');
40
40
  console.log('');
41
- console.log(' devTools: { Message: ApplicationComposition.Message }');
41
+ console.log(' devTools: { Message }');
42
42
  console.log('');
43
43
  console.log(' 2. Start your dev server, then restart your AI agent (Claude Code, Cursor, etc.).');
44
44
  console.log('');
package/dist/server.js CHANGED
@@ -42553,9 +42553,9 @@ const printNextSteps = (alreadyRegistered) => {
42553
42553
  console.log("");
42554
42554
  console.log("Next steps:");
42555
42555
  console.log("");
42556
- console.log(" 1. Pass the complete Message Codec to ApplicationComposition.assembleApplication (enables dispatch):");
42556
+ console.log(" 1. Pass your Message Schema to Runtime.makeApplication (enables dispatch):");
42557
42557
  console.log("");
42558
- console.log(" devTools: { Message: ApplicationComposition.Message }");
42558
+ console.log(" devTools: { Message }");
42559
42559
  console.log("");
42560
42560
  console.log(" 2. Start your dev server, then restart your AI agent (Claude Code, Cursor, etc.).");
42561
42561
  console.log("");
@@ -42637,7 +42637,6 @@ const getDirectPropertyNames = (propertySignatures) => {
42637
42637
  }
42638
42638
  return names;
42639
42639
  };
42640
- const callableTaggedStructs = /* @__PURE__ */ new WeakSet();
42641
42640
  const makeCallable = (tag, fields) => {
42642
42641
  const schema = TaggedStruct(tag, fields);
42643
42642
  const propertyNames = Object.hasOwn(fields, "_tag") ? void 0 : getDirectPropertyNames(schema.ast.propertySignatures);
@@ -42657,7 +42656,7 @@ const makeCallable = (tag, fields) => {
42657
42656
  }
42658
42657
  return output;
42659
42658
  } : make;
42660
- const callable = new Proxy(function() {}, {
42659
+ return new Proxy(function() {}, {
42661
42660
  apply(_target, _thisArg, argumentsList) {
42662
42661
  return construct(argumentsList[0]);
42663
42662
  },
@@ -42671,8 +42670,6 @@ const makeCallable = (tag, fields) => {
42671
42670
  return Reflect.getPrototypeOf(schema);
42672
42671
  }
42673
42672
  });
42674
- callableTaggedStructs.add(callable);
42675
- return callable;
42676
42673
  };
42677
42674
  const reservedUnionPropertyNames = /* @__PURE__ */ new Set(["members", "subset"]);
42678
42675
  const taggedUnionTypeOnlyPropertyNames = /* @__PURE__ */ new Set([
@@ -42751,18 +42748,18 @@ function defineTaggedUnion(casesByTag) {
42751
42748
  }
42752
42749
  //#endregion
42753
42750
  //#region ../foldkit/src/devTools/protocol.ts
42754
- /** A serialized Command produced during a Message dispatch (or `init`). `args` is `Some` when the Command declared an args record. `maybeBlockPath` is `None` until the result Message resolves, `Some([])` for a top-level result, and `Some(tags)` for a Block-routed result. */
42751
+ /** A serialized Command produced during a Message dispatch (or `init`). `args` is `Some` when the Command declared an args record. `maybeSubmodelPath` is `None` until the result Message resolves, `Some([])` for a top-level result, and `Some(tags)` for a Submodel-routed result. */
42755
42752
  const SerializedCommand = Struct({
42756
42753
  name: String$2,
42757
42754
  args: OptionFromNullOr(Record(String$2, Unknown)),
42758
- maybeBlockPath: OptionFromNullOr(ArraySchema(String$2))
42755
+ maybeSubmodelPath: OptionFromNullOr(ArraySchema(String$2))
42759
42756
  });
42760
42757
  /** A serialized Mount lifecycle event (start or end). `args` is `Some` when the Mount's definition declared an args record, and carries the runtime values used to construct the MountAction instance. */
42761
42758
  const SerializedMount = Struct({
42762
42759
  name: String$2,
42763
42760
  args: OptionFromNullOr(Record(String$2, Unknown))
42764
42761
  });
42765
- /** A serialized history entry as it appears on the wire. `blockPath` lists `Got<Child>Message` wrapper tags from outer to inner when the entry came up through a Block chain; `maybeLeafTag` is `Some` with the innermost child Message tag when one exists. `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. The Messages dispatched by mount Effects appear as their own entries elsewhere in history. */
42762
+ /** A serialized history entry as it appears on the wire. `submodelPath` lists `Got<Child>Message` wrapper tags from outer to inner when the entry came up through a Submodel chain; `maybeLeafTag` is `Some` with the innermost child Message tag when one exists. `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. The Messages dispatched by mount Effects appear as their own entries elsewhere in history. */
42766
42763
  const SerializedEntry = Struct({
42767
42764
  index: Number$1,
42768
42765
  tag: String$2,
@@ -42774,7 +42771,7 @@ const SerializedEntry = Struct({
42774
42771
  isModelChanged: Boolean$1,
42775
42772
  changedPaths: ArraySchema(String$2),
42776
42773
  affectedPaths: ArraySchema(String$2),
42777
- blockPath: ArraySchema(String$2),
42774
+ submodelPath: ArraySchema(String$2),
42778
42775
  maybeLeafTag: OptionFromNullOr(String$2)
42779
42776
  });
42780
42777
  /** Metadata about a single keyframe. The index identifies the point in history where the runtime can replay back to. */
@@ -47329,7 +47326,7 @@ const DispatchMessagesInput = Struct({
47329
47326
  });
47330
47327
  const GetMessageSchemaInput = Struct({
47331
47328
  runtime_id: RuntimeIdField,
47332
- variant_tag: optional$1(String$2.annotate({ description: "Optional dot-separated path of variant `_tag` values. When omitted, the tool returns a small variant index (tag names plus payload field names plus a tagged-union indicator) so agents can enumerate the top-level union cheaply. When provided, the tool walks the path through each variant's single tagged-union payload field, narrows the schema along the chain, and collapses any union deeper than the path to a `{ \"_summary\": \"union\", \"variants\": [...] }` placeholder. Extend the path to drill further. Examples: `\"ScrolledSidebar\"` (one top-level variant), `\"GotMobileMenuDialogMessage.GotAnimationMessage\"` (two levels of a Block chain)." }))
47329
+ variant_tag: optional$1(String$2.annotate({ description: "Optional dot-separated path of variant `_tag` values. When omitted, the tool returns a small variant index (tag names plus payload field names plus a tagged-union indicator) so agents can enumerate the top-level union cheaply. When provided, the tool walks the path through each variant's single tagged-union payload field, narrows the schema along the chain, and collapses any union deeper than the path to a `{ \"_summary\": \"union\", \"variants\": [...] }` placeholder. Extend the path to drill further. Examples: `\"ScrolledSidebar\"` (one top-level variant), `\"GotMobileMenuDialogMessage.GotAnimationMessage\"` (two levels of a Submodel chain)." }))
47333
47330
  });
47334
47331
  /**
47335
47332
  * Extract the inner JSON Schema from Effect's `JsonSchema.Document` wrapper.
@@ -47438,13 +47435,13 @@ const buildTools = (relayClient) => [
47438
47435
  },
47439
47436
  {
47440
47437
  name: "foldkit_get_message",
47441
- description: "Read a single Message history entry by absolute index. The response carries the SerializedEntry (tag, message body, commands, mountStarts, mountEnds, timestamp, `isModelChanged`, `changedPaths` for leaf-level mutations, `affectedPaths` adding their ancestor paths). Each entry in `commands` carries the Command name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeBlockPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Block Command). `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. Each Mount carries its `name` and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise). For Block-routed entries (tag matches `Got*Message`), the entry also carries `blockPath` listing wrapper tags from outer to inner and `maybeLeafTag` naming the innermost child Message. Model snapshots are not included; call foldkit_get_model_at with `index - 1` (before) and `index` (after) to inspect Model state around the entry.",
47438
+ description: "Read a single Message history entry by absolute index. The response carries the SerializedEntry (tag, message body, commands, mountStarts, mountEnds, timestamp, `isModelChanged`, `changedPaths` for leaf-level mutations, `affectedPaths` adding their ancestor paths). Each entry in `commands` carries the Command name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeSubmodelPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Submodel Command). `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. Each Mount carries its `name` and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise). For Submodel-routed entries (tag matches `Got*Message`), the entry also carries `submodelPath` listing wrapper tags from outer to inner and `maybeLeafTag` naming the innermost child Message. Model snapshots are not included; call foldkit_get_model_at with `index - 1` (before) and `index` (after) to inspect Model state around the entry.",
47442
47439
  inputSchema: toInputSchema(GetMessageInput),
47443
47440
  handle: runRuntimeTool(GetMessageInput, ({ index }) => Request.RequestGetMessage({ index }), relayClient)
47444
47441
  },
47445
47442
  {
47446
47443
  name: "foldkit_get_init",
47447
- description: "Read the runtime's initial Model, the Commands returned from the application's `init` function, and the Mounts that fired during the first render. The init entry is the synthetic row at index -1 in the DevTools panel; this tool exposes the same data without time-travelling the runtime. `maybeModel` is `None` until the runtime has finished its first render and recorded init, then stays `Some` for the rest of the runtime's life. `commands` lists init-time Commands in the order they were produced, each with its name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeBlockPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Block Command); `mountStarts` lists Mounts whose elements appeared in the initial render, each with its name and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise).",
47444
+ description: "Read the runtime's initial Model, the Commands returned from the application's `init` function, and the Mounts that fired during the first render. The init entry is the synthetic row at index -1 in the DevTools panel; this tool exposes the same data without time-travelling the runtime. `maybeModel` is `None` until the runtime has finished its first render and recorded init, then stays `Some` for the rest of the runtime's life. `commands` lists init-time Commands in the order they were produced, each with its name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeSubmodelPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Submodel Command); `mountStarts` lists Mounts whose elements appeared in the initial render, each with its name and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise).",
47448
47445
  inputSchema: toInputSchema(GetInitInput),
47449
47446
  handle: runRuntimeTool(GetInitInput, () => Request.RequestGetInit(), relayClient)
47450
47447
  },
@@ -47474,19 +47471,19 @@ const buildTools = (relayClient) => [
47474
47471
  },
47475
47472
  {
47476
47473
  name: "foldkit_get_message_schema",
47477
- description: "Describe the Message Schema for a Foldkit runtime so agents can construct valid payloads for `foldkit_dispatch_message`. Call with no arguments to receive a small variant index (every top-level variant's `_tag`, its payload field names, and which payload fields are themselves tagged-union shapes). Then call with `variant_tag: \"ChosenVariant\"` to drill in. The argument is a dot-separated path of variant `_tag` values: each segment names a variant, and the walker steps through the variant's single tagged-union payload field to reach the next. So `\"GotMobileMenuDialogMessage\"` narrows one level; `\"GotMobileMenuDialogMessage.GotAnimationMessage\"` narrows two levels of a Block chain. Discriminated unions deeper than the supplied path collapse to `{ \"_summary\": \"union\", \"variants\": [...] }` placeholders so the response stays compact even for deeply-nested apps; extend the path to drill further. `Schema.Option` fields render as `anyOf: [{_tag: \"Some\", value}, {_tag: \"None\"}]`. The full document follows the JSON Schema draft-2020-12 shape from `Schema.toJsonSchemaDocument`: `{ dialect, schema, definitions }`. Returns `maybeResult: None` when the runtime hasn't configured `DevToolsConfig.Message` (dispatch is also unavailable). Fields with no JSON representation, notably `Schema.instanceOf(File)` for user-uploaded files, render as `{type: \"null\"}`; those variants can't be dispatched via MCP because their values live in browser memory.",
47474
+ description: "Describe the Message Schema for a Foldkit runtime so agents can construct valid payloads for `foldkit_dispatch_message`. Call with no arguments to receive a small variant index (every top-level variant's `_tag`, its payload field names, and which payload fields are themselves tagged-union shapes). Then call with `variant_tag: \"ChosenVariant\"` to drill in. The argument is a dot-separated path of variant `_tag` values: each segment names a variant, and the walker steps through the variant's single tagged-union payload field to reach the next. So `\"GotMobileMenuDialogMessage\"` narrows one level; `\"GotMobileMenuDialogMessage.GotAnimationMessage\"` narrows two levels of a Submodel chain. Discriminated unions deeper than the supplied path collapse to `{ \"_summary\": \"union\", \"variants\": [...] }` placeholders so the response stays compact even for deeply-nested apps; extend the path to drill further. `Schema.Option` fields render as `anyOf: [{_tag: \"Some\", value}, {_tag: \"None\"}]`. The full document follows the JSON Schema draft-2020-12 shape from `Schema.toJsonSchemaDocument`: `{ dialect, schema, definitions }`. Returns `maybeResult: None` when the runtime hasn't configured `DevToolsConfig.Message` (dispatch is also unavailable). Fields with no JSON representation, notably `Schema.instanceOf(File)` for user-uploaded files, render as `{type: \"null\"}`; those variants can't be dispatched via MCP because their values live in browser memory.",
47478
47475
  inputSchema: toInputSchema(GetMessageSchemaInput),
47479
47476
  handle: runRuntimeTool(GetMessageSchemaInput, ({ variant_tag }) => Request.RequestGetMessageSchema({ maybeVariantTag: fromNullishOr(variant_tag) }), relayClient)
47480
47477
  },
47481
47478
  {
47482
47479
  name: "foldkit_dispatch_message",
47483
- description: "Dispatch a Message into a Foldkit runtime, as if the application itself produced it. Requires the runtime to have configured DevToolsConfig.Message; without it, dispatch is rejected. Call `foldkit_get_message_schema` with no arguments to enumerate the variants, then with `variant_tag` to learn one variant's exact payload shape, before constructing the Message object. The runtime decodes the payload and returns a clean error if it doesn't match. Messages configured with excludeFromHistory are rejected before execution. A successful response identifies the confirmed recorded history entry. A child Message that becomes stale before queued execution is discarded and returns an error. To dispatch several Messages in order with one call, use foldkit_dispatch_messages.",
47480
+ description: "Dispatch a Message into a Foldkit runtime, as if the application itself produced it. Requires the runtime to have configured DevToolsConfig.Message; without it, dispatch is rejected. Call `foldkit_get_message_schema` with no arguments to enumerate the variants, then with `variant_tag` to learn one variant's exact payload shape, before constructing the Message object. The runtime decodes the payload and returns a clean error if it doesn't match. To dispatch several Messages in order with one call, use foldkit_dispatch_messages.",
47484
47481
  inputSchema: toInputSchema(DispatchMessageInput),
47485
47482
  handle: runRuntimeTool(DispatchMessageInput, ({ message }) => Request.RequestDispatchMessage({ message }), relayClient)
47486
47483
  },
47487
47484
  {
47488
47485
  name: "foldkit_dispatch_messages",
47489
- description: `Dispatch an ordered batch of Messages into a Foldkit runtime in one call, first to last, as if the application produced them in quick succession. Prefer this over repeated foldkit_dispatch_message calls when staging state that takes several Messages: reproducing a bug, filling a form, or building a history fixture. Takes 1 to 100 Messages. Validation is all-or-nothing: the runtime decodes every payload against the Message Schema before dispatching any of them, and one invalid entry rejects the whole batch with an error naming its zero-based position, so there is never a partially applied prefix to clean up. Messages excluded from history are rejected before dispatch. On success, acceptedAtIndices contains the exact recorded history indices in request order. A Message whose captured child occurrence becomes stale before queued execution is omitted, while unrelated Messages recorded between batch entries keep their own indices. Requires DevToolsConfig.Message, like foldkit_dispatch_message.`,
47486
+ description: `Dispatch an ordered batch of Messages into a Foldkit runtime in one call, first to last, as if the application produced them in quick succession. Prefer this over repeated foldkit_dispatch_message calls when staging state that takes several Messages: reproducing a bug, filling a form, or building a history fixture. Takes 1 to 100 Messages. Validation is all-or-nothing: the runtime decodes every payload against the Message Schema before dispatching any of them, and one invalid entry rejects the whole batch with an error naming its zero-based position, so there is never a partially applied prefix to clean up. On success the response carries acceptedAtIndices, the predicted history index for each Message in request order; the runtime may still record its own Messages between entries (for example a Command completing mid-burst), exactly as with rapid user input, and Messages excluded from history via excludeFromHistory are dispatched but never recorded, so entries after one land below their predicted index. Requires DevToolsConfig.Message, like foldkit_dispatch_message.`,
47490
47487
  inputSchema: toInputSchema(DispatchMessagesInput),
47491
47488
  handle: runRuntimeTool(DispatchMessagesInput, ({ messages }) => Request.RequestDispatchMessages({ messages }), relayClient)
47492
47489
  },
package/dist/tools.js CHANGED
@@ -104,7 +104,7 @@ const DispatchMessagesInput = Schema.Struct({
104
104
  }),
105
105
  });
106
106
  const VariantTagField = Schema.optional(Schema.String.annotate({
107
- description: 'Optional dot-separated path of variant `_tag` values. When omitted, the tool returns a small variant index (tag names plus payload field names plus a tagged-union indicator) so agents can enumerate the top-level union cheaply. When provided, the tool walks the path through each variant\'s single tagged-union payload field, narrows the schema along the chain, and collapses any union deeper than the path to a `{ "_summary": "union", "variants": [...] }` placeholder. Extend the path to drill further. Examples: `"ScrolledSidebar"` (one top-level variant), `"GotMobileMenuDialogMessage.GotAnimationMessage"` (two levels of a Block chain).',
107
+ description: 'Optional dot-separated path of variant `_tag` values. When omitted, the tool returns a small variant index (tag names plus payload field names plus a tagged-union indicator) so agents can enumerate the top-level union cheaply. When provided, the tool walks the path through each variant\'s single tagged-union payload field, narrows the schema along the chain, and collapses any union deeper than the path to a `{ "_summary": "union", "variants": [...] }` placeholder. Extend the path to drill further. Examples: `"ScrolledSidebar"` (one top-level variant), `"GotMobileMenuDialogMessage.GotAnimationMessage"` (two levels of a Submodel chain).',
108
108
  }));
109
109
  const GetMessageSchemaInput = Schema.Struct({
110
110
  runtime_id: RuntimeIdField,
@@ -212,13 +212,13 @@ export const buildTools = (relayClient) => [
212
212
  },
213
213
  {
214
214
  name: 'foldkit_get_message',
215
- description: 'Read a single Message history entry by absolute index. The response carries the SerializedEntry (tag, message body, commands, mountStarts, mountEnds, timestamp, `isModelChanged`, `changedPaths` for leaf-level mutations, `affectedPaths` adding their ancestor paths). Each entry in `commands` carries the Command name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeBlockPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Block Command). `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. Each Mount carries its `name` and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise). For Block-routed entries (tag matches `Got*Message`), the entry also carries `blockPath` listing wrapper tags from outer to inner and `maybeLeafTag` naming the innermost child Message. Model snapshots are not included; call foldkit_get_model_at with `index - 1` (before) and `index` (after) to inspect Model state around the entry.',
215
+ description: 'Read a single Message history entry by absolute index. The response carries the SerializedEntry (tag, message body, commands, mountStarts, mountEnds, timestamp, `isModelChanged`, `changedPaths` for leaf-level mutations, `affectedPaths` adding their ancestor paths). Each entry in `commands` carries the Command name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeSubmodelPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Submodel Command). `mountStarts` lists Mounts that fired during the render after this Message; `mountEnds` lists Mounts whose elements were unmounted during that render. Each Mount carries its `name` and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise). For Submodel-routed entries (tag matches `Got*Message`), the entry also carries `submodelPath` listing wrapper tags from outer to inner and `maybeLeafTag` naming the innermost child Message. Model snapshots are not included; call foldkit_get_model_at with `index - 1` (before) and `index` (after) to inspect Model state around the entry.',
216
216
  inputSchema: toInputSchema(GetMessageInput),
217
217
  handle: runRuntimeTool(GetMessageInput, ({ index }) => Request.RequestGetMessage({ index }), relayClient),
218
218
  },
219
219
  {
220
220
  name: 'foldkit_get_init',
221
- description: "Read the runtime's initial Model, the Commands returned from the application's `init` function, and the Mounts that fired during the first render. The init entry is the synthetic row at index -1 in the DevTools panel; this tool exposes the same data without time-travelling the runtime. `maybeModel` is `None` until the runtime has finished its first render and recorded init, then stays `Some` for the rest of the runtime's life. `commands` lists init-time Commands in the order they were produced, each with its name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeBlockPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Block Command); `mountStarts` lists Mounts whose elements appeared in the initial render, each with its name and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise).",
221
+ description: "Read the runtime's initial Model, the Commands returned from the application's `init` function, and the Mounts that fired during the first render. The init entry is the synthetic row at index -1 in the DevTools panel; this tool exposes the same data without time-travelling the runtime. `maybeModel` is `None` until the runtime has finished its first render and recorded init, then stays `Some` for the rest of the runtime's life. `commands` lists init-time Commands in the order they were produced, each with its name, `args` (`Some(record)` when the Command declared an args schema, `None` otherwise), and `maybeSubmodelPath` (`None` before the result resolves, `Some([])` for a resolved top-level Command, or `Some(tags)` for a resolved Submodel Command); `mountStarts` lists Mounts whose elements appeared in the initial render, each with its name and `args` (`Some(record)` when the Mount declared an args schema, `None` otherwise).",
222
222
  inputSchema: toInputSchema(GetInitInput),
223
223
  handle: runRuntimeTool(GetInitInput, () => Request.RequestGetInit(), relayClient),
224
224
  },
@@ -248,7 +248,7 @@ export const buildTools = (relayClient) => [
248
248
  },
249
249
  {
250
250
  name: 'foldkit_get_message_schema',
251
- description: 'Describe the Message Schema for a Foldkit runtime so agents can construct valid payloads for `foldkit_dispatch_message`. Call with no arguments to receive a small variant index (every top-level variant\'s `_tag`, its payload field names, and which payload fields are themselves tagged-union shapes). Then call with `variant_tag: "ChosenVariant"` to drill in. The argument is a dot-separated path of variant `_tag` values: each segment names a variant, and the walker steps through the variant\'s single tagged-union payload field to reach the next. So `"GotMobileMenuDialogMessage"` narrows one level; `"GotMobileMenuDialogMessage.GotAnimationMessage"` narrows two levels of a Block chain. Discriminated unions deeper than the supplied path collapse to `{ "_summary": "union", "variants": [...] }` placeholders so the response stays compact even for deeply-nested apps; extend the path to drill further. `Schema.Option` fields render as `anyOf: [{_tag: "Some", value}, {_tag: "None"}]`. The full document follows the JSON Schema draft-2020-12 shape from `Schema.toJsonSchemaDocument`: `{ dialect, schema, definitions }`. Returns `maybeResult: None` when the runtime hasn\'t configured `DevToolsConfig.Message` (dispatch is also unavailable). Fields with no JSON representation, notably `Schema.instanceOf(File)` for user-uploaded files, render as `{type: "null"}`; those variants can\'t be dispatched via MCP because their values live in browser memory.',
251
+ description: 'Describe the Message Schema for a Foldkit runtime so agents can construct valid payloads for `foldkit_dispatch_message`. Call with no arguments to receive a small variant index (every top-level variant\'s `_tag`, its payload field names, and which payload fields are themselves tagged-union shapes). Then call with `variant_tag: "ChosenVariant"` to drill in. The argument is a dot-separated path of variant `_tag` values: each segment names a variant, and the walker steps through the variant\'s single tagged-union payload field to reach the next. So `"GotMobileMenuDialogMessage"` narrows one level; `"GotMobileMenuDialogMessage.GotAnimationMessage"` narrows two levels of a Submodel chain. Discriminated unions deeper than the supplied path collapse to `{ "_summary": "union", "variants": [...] }` placeholders so the response stays compact even for deeply-nested apps; extend the path to drill further. `Schema.Option` fields render as `anyOf: [{_tag: "Some", value}, {_tag: "None"}]`. The full document follows the JSON Schema draft-2020-12 shape from `Schema.toJsonSchemaDocument`: `{ dialect, schema, definitions }`. Returns `maybeResult: None` when the runtime hasn\'t configured `DevToolsConfig.Message` (dispatch is also unavailable). Fields with no JSON representation, notably `Schema.instanceOf(File)` for user-uploaded files, render as `{type: "null"}`; those variants can\'t be dispatched via MCP because their values live in browser memory.',
252
252
  inputSchema: toInputSchema(GetMessageSchemaInput),
253
253
  handle: runRuntimeTool(GetMessageSchemaInput, ({ variant_tag }) => Request.RequestGetMessageSchema({
254
254
  maybeVariantTag: Option.fromNullishOr(variant_tag),
@@ -256,13 +256,13 @@ export const buildTools = (relayClient) => [
256
256
  },
257
257
  {
258
258
  name: 'foldkit_dispatch_message',
259
- description: "Dispatch a Message into a Foldkit runtime, as if the application itself produced it. Requires the runtime to have configured DevToolsConfig.Message; without it, dispatch is rejected. Call `foldkit_get_message_schema` with no arguments to enumerate the variants, then with `variant_tag` to learn one variant's exact payload shape, before constructing the Message object. The runtime decodes the payload and returns a clean error if it doesn't match. Messages configured with excludeFromHistory are rejected before execution. A successful response identifies the confirmed recorded history entry. A child Message that becomes stale before queued execution is discarded and returns an error. To dispatch several Messages in order with one call, use foldkit_dispatch_messages.",
259
+ description: "Dispatch a Message into a Foldkit runtime, as if the application itself produced it. Requires the runtime to have configured DevToolsConfig.Message; without it, dispatch is rejected. Call `foldkit_get_message_schema` with no arguments to enumerate the variants, then with `variant_tag` to learn one variant's exact payload shape, before constructing the Message object. The runtime decodes the payload and returns a clean error if it doesn't match. To dispatch several Messages in order with one call, use foldkit_dispatch_messages.",
260
260
  inputSchema: toInputSchema(DispatchMessageInput),
261
261
  handle: runRuntimeTool(DispatchMessageInput, ({ message }) => Request.RequestDispatchMessage({ message }), relayClient),
262
262
  },
263
263
  {
264
264
  name: 'foldkit_dispatch_messages',
265
- description: `Dispatch an ordered batch of Messages into a Foldkit runtime in one call, first to last, as if the application produced them in quick succession. Prefer this over repeated foldkit_dispatch_message calls when staging state that takes several Messages: reproducing a bug, filling a form, or building a history fixture. Takes 1 to ${MAX_DISPATCH_BATCH_SIZE} Messages. Validation is all-or-nothing: the runtime decodes every payload against the Message Schema before dispatching any of them, and one invalid entry rejects the whole batch with an error naming its zero-based position, so there is never a partially applied prefix to clean up. Messages excluded from history are rejected before dispatch. On success, acceptedAtIndices contains the exact recorded history indices in request order. A Message whose captured child occurrence becomes stale before queued execution is omitted, while unrelated Messages recorded between batch entries keep their own indices. Requires DevToolsConfig.Message, like foldkit_dispatch_message.`,
265
+ description: `Dispatch an ordered batch of Messages into a Foldkit runtime in one call, first to last, as if the application produced them in quick succession. Prefer this over repeated foldkit_dispatch_message calls when staging state that takes several Messages: reproducing a bug, filling a form, or building a history fixture. Takes 1 to ${MAX_DISPATCH_BATCH_SIZE} Messages. Validation is all-or-nothing: the runtime decodes every payload against the Message Schema before dispatching any of them, and one invalid entry rejects the whole batch with an error naming its zero-based position, so there is never a partially applied prefix to clean up. On success the response carries acceptedAtIndices, the predicted history index for each Message in request order; the runtime may still record its own Messages between entries (for example a Command completing mid-burst), exactly as with rapid user input, and Messages excluded from history via excludeFromHistory are dispatched but never recorded, so entries after one land below their predicted index. Requires DevToolsConfig.Message, like foldkit_dispatch_message.`,
266
266
  inputSchema: toInputSchema(DispatchMessagesInput),
267
267
  handle: runRuntimeTool(DispatchMessagesInput, ({ messages }) => Request.RequestDispatchMessages({ messages }), relayClient),
268
268
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/devtools-mcp",
3
- "version": "0.24.1-canary.bfd880b1e6ca",
3
+ "version": "0.24.1-canary.c55d84c8199b",
4
4
  "description": "MCP server exposing Foldkit DevTools to AI agents (Claude Code, Cursor, etc.)",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "peerDependencies": {
19
19
  "effect": "4.0.0",
20
- "foldkit": "0.168.0-canary.bfd880b1e6ca"
20
+ "foldkit": "0.168.0-canary.c55d84c8199b"
21
21
  },
22
22
  "dependencies": {
23
23
  "@modelcontextprotocol/sdk": "1.29.0",
@@ -25,11 +25,11 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@effect/platform-node": "4.0.0",
28
- "@foldkit/vite-plugin": "0.27.1-canary.bfd880b1e6ca",
28
+ "@foldkit/vite-plugin": "0.27.1-canary.c55d84c8199b",
29
29
  "@types/node": "26.4.0",
30
30
  "@types/ws": "^8.18.1",
31
31
  "effect": "4.0.0",
32
- "foldkit": "0.168.0-canary.bfd880b1e6ca",
32
+ "foldkit": "0.168.0-canary.c55d84c8199b",
33
33
  "rimraf": "^6.1.3",
34
34
  "rolldown": "^1.2.11",
35
35
  "typescript": "^7.0.2",