breakpoint-mcp 1.28.0 → 1.29.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/dist/index.js +1 -1
- package/dist/tools/editor/introspection.js +33 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ async function main() {
|
|
|
41
41
|
// so long jobs (export/import/headless script) support poll/await/cancel.
|
|
42
42
|
// D3: also advertise resources.subscribe so clients can subscribe to
|
|
43
43
|
// godot://… resources and receive notifications/resources/updated.
|
|
44
|
-
const server = new McpServer({ name: "breakpoint-mcp", version: "1.
|
|
44
|
+
const server = new McpServer({ name: "breakpoint-mcp", version: "1.29.0" }, { capabilities: { ...TASK_CAPABILITIES, ...RESOURCE_CAPABILITIES }, taskStore });
|
|
45
45
|
// B1: enforce frozen output schemas on every structured tool. Must run before
|
|
46
46
|
// any register*Tools call — it wraps server.registerTool.
|
|
47
47
|
applyOutputSchemas(server);
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { fail } from "./common.js";
|
|
3
|
+
/**
|
|
4
|
+
* Smallest edge, in pixels, a captured editor viewport may have and still be a
|
|
5
|
+
* frame rather than a placeholder.
|
|
6
|
+
*
|
|
7
|
+
* Godot does not tear down the main-screen tab you are not looking at — it
|
|
8
|
+
* collapses that tab's SubViewport to its minimum size and keeps rendering it.
|
|
9
|
+
* `get_texture().get_image()` therefore still succeeds, and the capture returns
|
|
10
|
+
* a real, valid, **2x2** PNG: correct magic bytes, correct mime, an 81-byte
|
|
11
|
+
* payload, and a note reading "Captured 2d viewport (2x2)". Every layer above
|
|
12
|
+
* reports success, and an assistant then *looks at* four pixels and reasons
|
|
13
|
+
* about the scene from them.
|
|
14
|
+
*
|
|
15
|
+
* Measured on Godot 4.7 (session 144), four editor boots, real Metal hardware:
|
|
16
|
+
* with the Script or 3D tab active, `viewport=2d` returned 2x2/81B; with the 2D
|
|
17
|
+
* tab active it returned 1297x492/3.6KB. A fresh editor with no saved layout —
|
|
18
|
+
* the CI condition — boots on the **3D** tab, and opening a `Node2D` scene does
|
|
19
|
+
* not switch it. So the degenerate case is the DEFAULT, not the exception.
|
|
20
|
+
*
|
|
21
|
+
* 8px is deliberately far below any real viewport and far above the collapsed
|
|
22
|
+
* one: it separates the two populations without guessing at a "reasonable" size.
|
|
23
|
+
*/
|
|
24
|
+
const MIN_RENDERED_VIEWPORT_PX = 8;
|
|
3
25
|
/** Editor selection, ClassDB / docs lookups, and viewport screenshot. */
|
|
4
26
|
export function registerIntrospectionTools(server, call, bridge) {
|
|
5
27
|
server.registerTool("selection_get", { title: "Get selection", description: "Return the paths of the nodes currently selected in the editor.", inputSchema: {} }, async () => call("selection.get"));
|
|
@@ -53,11 +75,21 @@ export function registerIntrospectionTools(server, call, bridge) {
|
|
|
53
75
|
server.registerTool("screenshot_editor", {
|
|
54
76
|
title: "Screenshot editor viewport",
|
|
55
77
|
description: "Capture the 2D or 3D editor viewport as a PNG and return it as image content so the assistant can see the scene. " +
|
|
56
|
-
"Requires the matching editor tab (2D/3D) to be active
|
|
78
|
+
"Requires the matching editor tab (2D/3D) to be active: Godot collapses the inactive tab's viewport to a few " +
|
|
79
|
+
"pixels, and this tool returns a viewport_not_rendered error rather than that placeholder frame.",
|
|
57
80
|
inputSchema: { viewport: z.enum(["2d", "3d"]).optional().describe("Which viewport (default 3d)") },
|
|
58
81
|
}, async ({ viewport }) => {
|
|
59
82
|
try {
|
|
60
83
|
const r = (await bridge.request("screenshot.editor_viewport", { viewport: viewport ?? "3d" }));
|
|
84
|
+
if (r.width < MIN_RENDERED_VIEWPORT_PX || r.height < MIN_RENDERED_VIEWPORT_PX) {
|
|
85
|
+
return fail({
|
|
86
|
+
code: "viewport_not_rendered",
|
|
87
|
+
message: `The ${r.viewport} editor viewport measured ${r.width}x${r.height} — a collapsed viewport, not a rendered ` +
|
|
88
|
+
`frame. Godot keeps the inactive main-screen tab's viewport alive at its minimum size, so the capture ` +
|
|
89
|
+
`"succeeds" and returns a placeholder image. Switch the editor to the ${r.viewport.toUpperCase()} tab ` +
|
|
90
|
+
`(opening a scene does NOT switch it), then retry — or capture the viewport whose tab is active.`,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
61
93
|
return {
|
|
62
94
|
content: [
|
|
63
95
|
{ type: "image", data: r.base64, mimeType: r.mime },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breakpoint-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.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",
|