breakpoint-mcp 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/schemas.js +3 -0
- package/dist/tools/tabletop.js +26 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The MCP **host** for [Breakpoint MCP](https://github.com/jlivingston-Cipher/godot-breakpoint-mcp) —
|
|
4
4
|
a [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
|
|
5
5
|
Godot game engine to AI coding assistants across four planes: headless CLI, the live
|
|
6
|
-
editor, Godot's own LSP + DAP, and a runtime bridge inside the running game. **
|
|
6
|
+
editor, Godot's own LSP + DAP, and a runtime bridge inside the running game. **271 tools
|
|
7
7
|
+ 5 MCP resources**, built against the stable `@modelcontextprotocol/sdk` 1.x API.
|
|
8
8
|
Developed and tested with **Claude**; because MCP is an open protocol, other clients can
|
|
9
9
|
connect too (currently untested — reports welcome).
|
package/dist/schemas.js
CHANGED
|
@@ -693,6 +693,7 @@ export const outputSchemas = {
|
|
|
693
693
|
container_path: z.string(),
|
|
694
694
|
mode: z.string(),
|
|
695
695
|
count: z.number(),
|
|
696
|
+
persisted: z.boolean(),
|
|
696
697
|
instances: z.array(z.object({ index: z.number(), instance_path: z.string() })),
|
|
697
698
|
},
|
|
698
699
|
card_deck_from_table: {
|
|
@@ -701,6 +702,7 @@ export const outputSchemas = {
|
|
|
701
702
|
rows_read: z.number(),
|
|
702
703
|
rows_skipped: z.number(),
|
|
703
704
|
unmapped_columns: z.array(z.string()),
|
|
705
|
+
persisted: z.boolean(),
|
|
704
706
|
instances: z.array(z.object({ row_index: z.number(), instance_path: z.string() })),
|
|
705
707
|
},
|
|
706
708
|
card_set_face: {
|
|
@@ -771,6 +773,7 @@ export const outputSchemas = {
|
|
|
771
773
|
unbound: z.array(z.string()),
|
|
772
774
|
placed: z.boolean(),
|
|
773
775
|
cell: z.string().nullable(),
|
|
776
|
+
persisted: z.boolean(),
|
|
774
777
|
},
|
|
775
778
|
piece_move: {
|
|
776
779
|
moved: z.boolean(),
|
package/dist/tools/tabletop.js
CHANGED
|
@@ -505,15 +505,20 @@ export async function emitCardHand(emit, args) {
|
|
|
505
505
|
const container = args.parent === "" ? "." : args.parent;
|
|
506
506
|
const base = sceneRootName(args.template_path);
|
|
507
507
|
const places = computeLayout(args.mode, args.cards.length, args);
|
|
508
|
+
// Finding-A save-persistence (opt-in), threaded per-card through emitOneCard: when
|
|
509
|
+
// set, every card in the hand gets Editable Children so its bound slot data serializes
|
|
510
|
+
// on save instead of reverting on reload. Default off keeps the runtime-bound contract.
|
|
511
|
+
const persisted = args.persist === true;
|
|
508
512
|
const instances = [];
|
|
509
513
|
for (let i = 0; i < args.cards.length; i++) {
|
|
510
514
|
const { instance_path } = await emitOneCard(emit, {
|
|
511
515
|
template_path: args.template_path, parent: container, data: args.cards[i].data,
|
|
512
516
|
name: `${base}_${i}`, face_up: args.cards[i].face_up ?? true, placement: places[i],
|
|
517
|
+
persist: args.persist,
|
|
513
518
|
});
|
|
514
519
|
instances.push({ index: i, instance_path });
|
|
515
520
|
}
|
|
516
|
-
return { container_path: container, mode: args.mode, count: instances.length, instances };
|
|
521
|
+
return { container_path: container, mode: args.mode, count: instances.length, persisted, instances };
|
|
517
522
|
}
|
|
518
523
|
export async function emitDeckFromTable(emit, readFile, args) {
|
|
519
524
|
const container = args.parent === "" ? "." : args.parent;
|
|
@@ -558,13 +563,15 @@ export async function emitDeckFromTable(emit, readFile, args) {
|
|
|
558
563
|
const { instance_path } = await emitOneCard(emit, {
|
|
559
564
|
template_path: args.template_path, parent: container, data, name, face_up,
|
|
560
565
|
placement: args.layout ? places[i] : undefined,
|
|
566
|
+
persist: args.persist,
|
|
561
567
|
});
|
|
562
568
|
instances.push({ row_index: allRows.indexOf(row), instance_path });
|
|
563
569
|
}
|
|
564
570
|
const unmapped_columns = [...header].filter((c) => !referenced.has(c)).sort();
|
|
565
571
|
return {
|
|
566
572
|
deck_container: container, count: instances.length, rows_read,
|
|
567
|
-
rows_skipped: rows_read - instances.length, unmapped_columns,
|
|
573
|
+
rows_skipped: rows_read - instances.length, unmapped_columns,
|
|
574
|
+
persisted: args.persist === true, instances,
|
|
568
575
|
};
|
|
569
576
|
}
|
|
570
577
|
/**
|
|
@@ -1023,13 +1030,25 @@ export async function emitPieceInstance(emit, args) {
|
|
|
1023
1030
|
const res = await emit("node.call_method", { path: instPath, method: "set_data", args: [args.data] });
|
|
1024
1031
|
await emit("node.call_method", { path: instPath, method: "set_face", args: [face_up] });
|
|
1025
1032
|
const { bound, unbound } = splitFromCall(res, args.data);
|
|
1033
|
+
// Finding-A save-persistence (opt-in), mirroring card_instance. set_data mutates the
|
|
1034
|
+
// piece's internal Art/Label nodes, but a sealed sub-scene doesn't serialize those
|
|
1035
|
+
// overrides, so they revert on reload. Enabling "Editable Children" bakes them into the
|
|
1036
|
+
// saved scene. Emitted last, on the piece's final resting path (after any place_on
|
|
1037
|
+
// reparent). Default off preserves the lighter runtime-bound contract.
|
|
1038
|
+
const persisted = args.persist === true;
|
|
1026
1039
|
if (args.place_on) {
|
|
1027
1040
|
const placed = await emitBoardPlace(emit, {
|
|
1028
1041
|
board: args.place_on.board, cell: args.place_on.cell, node: instPath, align: args.place_on.align,
|
|
1029
1042
|
});
|
|
1030
|
-
|
|
1043
|
+
if (persisted) {
|
|
1044
|
+
await emit("node.set_editable_instance", { path: placed.node_path, editable: true });
|
|
1045
|
+
}
|
|
1046
|
+
return { instance_path: placed.node_path, face_up, bound, unbound, placed: true, cell: args.place_on.cell, persisted };
|
|
1047
|
+
}
|
|
1048
|
+
if (persisted) {
|
|
1049
|
+
await emit("node.set_editable_instance", { path: instPath, editable: true });
|
|
1031
1050
|
}
|
|
1032
|
-
return { instance_path: instPath, face_up, bound, unbound, placed: false, cell: null };
|
|
1051
|
+
return { instance_path: instPath, face_up, bound, unbound, placed: false, cell: null, persisted };
|
|
1033
1052
|
}
|
|
1034
1053
|
/**
|
|
1035
1054
|
* Move a piece onto a destination cell (reusing `board_place` for the reparent +
|
|
@@ -1416,6 +1435,7 @@ export function registerTabletopTools(server, bridge, config) {
|
|
|
1416
1435
|
})).min(1).describe("One entry per card to instance"),
|
|
1417
1436
|
mode: z.enum(["row", "fan", "stack", "grid"]).describe("Arrangement mode"),
|
|
1418
1437
|
...layoutKnobs,
|
|
1438
|
+
persist: z.boolean().optional().describe("Bake each card's bound slot data into the saved scene by enabling Editable Children on every instanced card (default false = runtime-bound only, reverts on reload)"),
|
|
1419
1439
|
},
|
|
1420
1440
|
}, async (raw) => {
|
|
1421
1441
|
const a = raw;
|
|
@@ -1452,6 +1472,7 @@ export function registerTabletopTools(server, bridge, config) {
|
|
|
1452
1472
|
align: z.enum(["start", "center", "end"]).optional(),
|
|
1453
1473
|
origin: z.object({ x: z.number(), y: z.number() }).optional(),
|
|
1454
1474
|
}).optional().describe("Optional arrangement (same knobs as card_hand_layout); omitted → stacked at origin"),
|
|
1475
|
+
persist: z.boolean().optional().describe("Bake each stamped card's bound slot data into the saved scene by enabling Editable Children on every card (default false = runtime-bound only, reverts on reload)"),
|
|
1455
1476
|
},
|
|
1456
1477
|
}, async (raw) => {
|
|
1457
1478
|
const a = raw;
|
|
@@ -1677,6 +1698,7 @@ export function registerTabletopTools(server, bridge, config) {
|
|
|
1677
1698
|
cell: z.string().describe("Cell id to place onto (resolves to <board>/cell_<cell>)"),
|
|
1678
1699
|
align: z.object({ x: z.number(), y: z.number() }).optional().describe("Offset from the cell origin in px (default centred)"),
|
|
1679
1700
|
}).optional().describe("Optionally place the new piece on a board cell in the same call"),
|
|
1701
|
+
persist: z.boolean().optional().describe("Bake the bound data into the saved scene by enabling Editable Children on the instance (default false = runtime-bound only, reverts on reload)"),
|
|
1680
1702
|
},
|
|
1681
1703
|
}, async (raw) => {
|
|
1682
1704
|
const a = raw;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breakpoint-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "MCP server exposing Godot to AI coding assistants over the Model Context Protocol — developed and tested with Claude — across four planes (CLI, live editor, LSP+DAP, runtime) with elicitation-gated destructive tools, long jobs on the formal MCP task model, captured console output, and MCP resources.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|