breakpoint-mcp 1.82.0 → 1.82.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/dist/dap.js +7 -1
- package/dist/index.js +9 -1
- package/dist/tools/dap.js +18 -9
- package/package.json +1 -1
package/dist/dap.js
CHANGED
|
@@ -120,9 +120,15 @@ export function unorderedHandshakeWarning(waitedMs) {
|
|
|
120
120
|
export const DAP_RESTART_REMEDY = "Call `dbg_launch` or `dbg_attach` first — a restart reuses the parameters of a launch that already happened, and none has.";
|
|
121
121
|
/**
|
|
122
122
|
* Per-line breakpoint modifier fields, each gated by an adapter capability. Godot
|
|
123
|
-
* advertises
|
|
123
|
+
* advertises none of the three AND ignores them — a "conditional" breakpoint halts
|
|
124
124
|
* unconditionally (measured live on 4.3 and 4.7), so an undropped modifier is not a
|
|
125
125
|
* no-op, it is the opposite of what the caller asked for.
|
|
126
|
+
*
|
|
127
|
+
* 🔴 278 — THE KEYS ARE ABSENT, NOT `false`, AND THIS PARAGRAPH SAID `false` FOR AS LONG
|
|
128
|
+
* AS IT HAS EXISTED. Both read the same way through `!== true`, which is why nothing ever
|
|
129
|
+
* caught it; they are different facts about the adapter, and `docs/dap_capability_ledger.json`
|
|
130
|
+
* is where the difference is now recorded rather than described. The ledger carries the run
|
|
131
|
+
* the reading came from, so the next reader can check it instead of believing this comment.
|
|
126
132
|
*/
|
|
127
133
|
export const BREAKPOINT_MODIFIER_CAPS = {
|
|
128
134
|
condition: "supportsConditionalBreakpoints",
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import { applyWireDefaults } from "./wire-defaults.js";
|
|
|
17
17
|
import { applyOutputSchemas } from "./schemas.js";
|
|
18
18
|
import { applyAnnotations } from "./annotations.js";
|
|
19
19
|
import { applyTimeoutCaveat } from "./timeout-caveat.js";
|
|
20
|
+
import { packageVersion } from "./version.js";
|
|
20
21
|
import { applyCapabilities, applyDroppedToolRefusal, droppedTools, registerCapabilitiesResource, selectPrivilegedGroups, } from "./capabilities.js";
|
|
21
22
|
import { taskStore, TASK_CAPABILITIES } from "./tasks.js";
|
|
22
23
|
import { RESOURCE_CAPABILITIES, registerResourceSubscriptions } from "./subscriptions.js";
|
|
@@ -52,7 +53,14 @@ async function main() {
|
|
|
52
53
|
// so long jobs (export/import/headless script) support poll/await/cancel.
|
|
53
54
|
// D3: also advertise resources.subscribe so clients can subscribe to
|
|
54
55
|
// godot://… resources and receive notifications/resources/updated.
|
|
55
|
-
|
|
56
|
+
// 🔴 READ, NEVER WRITTEN HERE (#248, twenty-eight sessions). This is the version every
|
|
57
|
+
// connected client is told at `initialize`, and it was the ONE place in host/src where
|
|
58
|
+
// a version was a literal — while `--version`, `lsp.ts`'s clientInfo and `cslsp.ts`'s
|
|
59
|
+
// all call `packageVersion()`. `version.ts` says why in its own words: the best
|
|
60
|
+
// outcome is not a gated literal but no literal at all, and the incident it documents
|
|
61
|
+
// is this exact field — twenty-odd releases announcing 0.2.0 to every language server
|
|
62
|
+
// they met, because a literal nobody compares to anything cannot go stale loudly.
|
|
63
|
+
const server = new McpServer({ name: "breakpoint-mcp", version: packageVersion() }, { capabilities: { ...TASK_CAPABILITIES, ...RESOURCE_CAPABILITIES }, taskStore });
|
|
56
64
|
// 208 §7.1 — delete from the wire what the protocol already says: the SDK's
|
|
57
65
|
// draft-07 `$schema` inside every input/output schema (MCP's default dialect is
|
|
58
66
|
// 2020-12, and declaring another is an explicit switch a peer may reject), and
|
package/dist/tools/dap.js
CHANGED
|
@@ -398,17 +398,18 @@ export function registerDapTools(server, dap, cfg) {
|
|
|
398
398
|
"or a path resolving outside the Godot project root — Godot binds breakpoints only to scripts in the project it runs, so " +
|
|
399
399
|
"unlike cs_dbg_set_breakpoints an absolute path outside the root is refused here too. " +
|
|
400
400
|
"Feature-detected: the per-line conditions / hit_conditions / log_messages modifiers are only sent when the connected adapter " +
|
|
401
|
-
"advertises support (supportsConditionalBreakpoints / supportsHitConditionalBreakpoints / supportsLogPoints).
|
|
402
|
-
"
|
|
403
|
-
"
|
|
401
|
+
"advertises support (supportsConditionalBreakpoints / supportsHitConditionalBreakpoints / supportsLogPoints). Measured: no Godot " +
|
|
402
|
+
"build this project tests advertises it — 4.3-stable and 4.7-stable advertise none of the three (the keys are ABSENT rather than " +
|
|
403
|
+
"false) and IGNORE the modifiers, so such a breakpoint would halt unconditionally; see docs/dap_capability_ledger.json. All three " +
|
|
404
|
+
"are therefore dropped on every build measured, and the result includes `unsupported_modifiers` plus a `warning`. Detection happens when the breakpoints are " +
|
|
404
405
|
"applied, so it covers buffered ones too: setting modifiers before a session exists returns `modifier_detection: \"deferred\"` with a " +
|
|
405
406
|
"warning, and dbg_launch then reports the `unsupported_modifiers` actually dropped during the handshake.",
|
|
406
407
|
inputSchema: {
|
|
407
408
|
path: z.string().describe("Script path (res://..., absolute, or project-relative)"),
|
|
408
409
|
lines: z.array(z.number().int().positive()).describe("1-based line numbers"),
|
|
409
|
-
conditions: z.array(z.string().nullable()).optional().describe("Optional per-line condition expressions (aligned to lines, use null to skip a line); break only when the expression is true"),
|
|
410
|
-
hit_conditions: z.array(z.string().nullable()).optional().describe("Optional per-line hit expressions aligned to lines, e.g. '>3' or '%5' — break based on hit count (null to skip)"),
|
|
411
|
-
log_messages: z.array(z.string().nullable()).optional().describe("Optional per-line log messages aligned to lines; a message turns that breakpoint into a LOGPOINT (logs and continues, never halts). {expr} interpolates (null to skip)."),
|
|
410
|
+
conditions: z.array(z.string().nullable()).optional().describe("Optional per-line condition expressions (aligned to lines, use null to skip a line); break only when the expression is true. Gated on supportsConditionalBreakpoints — Measured: no Godot build this project tests advertises it, so this is dropped and reported on every build measured."),
|
|
411
|
+
hit_conditions: z.array(z.string().nullable()).optional().describe("Optional per-line hit expressions aligned to lines, e.g. '>3' or '%5' — break based on hit count (null to skip). Gated on supportsHitConditionalBreakpoints — Measured: no Godot build this project tests advertises it, so this is dropped and reported on every build measured."),
|
|
412
|
+
log_messages: z.array(z.string().nullable()).optional().describe("Optional per-line log messages aligned to lines; a message turns that breakpoint into a LOGPOINT (logs and continues, never halts). {expr} interpolates (null to skip). Gated on supportsLogPoints — Measured: no Godot build this project tests advertises it, so this is dropped and reported on every build measured."),
|
|
412
413
|
},
|
|
413
414
|
}, async ({ path, lines, conditions, hit_conditions, log_messages }) => {
|
|
414
415
|
try {
|
|
@@ -641,8 +642,11 @@ export function registerDapTools(server, dap, cfg) {
|
|
|
641
642
|
"(DAP setExceptionBreakpoints). Pass the filter IDs to enable; call with no filters (or []) to clear them. The result echoes the " +
|
|
642
643
|
"active filters and lists `available_filters` — the exception filters the connected adapter actually advertises. " +
|
|
643
644
|
"Requires a running debug session. Not gated (it only configures the debugger). " +
|
|
644
|
-
"Feature-detected: on an adapter that advertises no exceptionBreakpointFilters (
|
|
645
|
-
"
|
|
645
|
+
"Feature-detected: on an adapter that advertises no exceptionBreakpointFilters (which also does not answer the request — it would " +
|
|
646
|
+
"otherwise time out) it returns a clear \"unsupported\" message WITHOUT sending anything. Measured: no Godot build this project " +
|
|
647
|
+
"tests advertises it — 4.3-stable AND 4.7-stable both advertise no filters, so on a shipped engine it is unsupported surface today " +
|
|
648
|
+
"rather than a feature you can reach; see docs/dap_capability_ledger.json. This sentence used to name 4.3 alone as the example, " +
|
|
649
|
+
"which read as though a newer build had filters. None does.",
|
|
646
650
|
inputSchema: {
|
|
647
651
|
filters: z.array(z.string()).optional().describe("Exception filter IDs to enable (default none = clear). Choose from available_filters in the result."),
|
|
648
652
|
},
|
|
@@ -782,6 +786,9 @@ export function registerDapTools(server, dap, cfg) {
|
|
|
782
786
|
"list the valid goto targets on that line; when the line has exactly one target (or you pass `target_id`) it jumps there. " +
|
|
783
787
|
"DESTRUCTIVE: skips or repeats code by moving execution — confirm with the user and keep this gated. " +
|
|
784
788
|
"Feature-detected: on an adapter that does not advertise `supportsGotoTargetsRequest` it returns a clear \"unsupported\" message WITHOUT prompting. " +
|
|
789
|
+
"Measured: no Godot build this project tests advertises it — 4.3-stable and 4.7-stable both refuse this tool, so on a shipped engine it " +
|
|
790
|
+
"is unsupported surface today rather than a feature you can reach; see docs/dap_capability_ledger.json. It is kept, and kept guarded, " +
|
|
791
|
+
"because a capability is not a boundary and a build can start advertising it. " +
|
|
785
792
|
"Refuses a source that can never carry a target — a missing file, a directory, an empty path (which resolves to the project root), " +
|
|
786
793
|
"or a path resolving outside the Godot project root — the same guard dbg_set_breakpoints applies. " +
|
|
787
794
|
"Only meaningful while stopped at a breakpoint.",
|
|
@@ -854,7 +861,9 @@ export function registerDapTools(server, dap, cfg) {
|
|
|
854
861
|
"resolvable id is armed in one setDataBreakpoints call. Call with no `watch` (or []) to clear all data breakpoints. The result reports the " +
|
|
855
862
|
"armed `breakpoints` (each with its resolved data_id and verified flag) and any `unresolved` variables the adapter cannot watch. " +
|
|
856
863
|
"Requires a running session; NOT gated (it only configures the debugger). Feature-detected: on an adapter that does not advertise " +
|
|
857
|
-
"`supportsDataBreakpoints` it returns a clear \"unsupported\" message without sending any request."
|
|
864
|
+
"`supportsDataBreakpoints` it returns a clear \"unsupported\" message without sending any request. Measured: no Godot build this " +
|
|
865
|
+
"project tests advertises it — 4.3-stable and 4.7-stable both refuse this tool, so on a shipped engine it is unsupported surface " +
|
|
866
|
+
"today rather than a feature you can reach; see docs/dap_capability_ledger.json.",
|
|
858
867
|
inputSchema: {
|
|
859
868
|
watch: z.array(z.object({
|
|
860
869
|
name: z.string().describe("Variable name to watch"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "breakpoint-mcp",
|
|
3
|
-
"version": "1.82.
|
|
3
|
+
"version": "1.82.1",
|
|
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",
|