diff --git a/CHANGELOG.md b/CHANGELOG.md
index d824033..e05096d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,11 @@ All notable changes to DebugMCP will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
+## [Unreleased]
+
+### Added
+- **`get_loaded_scripts` tool** — returns all scripts currently loaded in the active debug session via the DAP `loadedSources` request. Works on a running session without requiring execution to be paused. Each entry contains `name`, `path` (null for dynamically generated scripts), and `sourceReference` (non-zero when there is no on-disk path). Gracefully returns an error object if there is no active session or if the debug adapter does not support `loadedSources`.
+
## [1.0.8] - 2025-03-14
### Added
diff --git a/README.md b/README.md
index a16ed39..7ec816c 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,7 @@ DebugMCP is an MCP server that gives AI coding agents full control over the VS C
| **remove_breakpoint** | Remove a breakpoint from a specific line | `fileFullPath` (required)
`line` (required) |
| **clear_all_breakpoints** | Remove all breakpoints at once | None |
| **list_breakpoints** | List all active breakpoints | None |
+| **get_loaded_scripts** | Returns all scripts currently loaded in the active debug session (name, path, sourceReference). Works on a running session without pausing execution. Useful for discovering exact file paths before calling `add_breakpoint`. | None |
| **get_variables_values** | Get variables and their values at current execution point | `scope` (optional: 'local', 'global', 'all') |
| **evaluate_expression** | Evaluate an expression in debug context | `expression` (required) |
diff --git a/src/debugMCPServer.ts b/src/debugMCPServer.ts
index 40e33f8..4ea41d1 100644
--- a/src/debugMCPServer.ts
+++ b/src/debugMCPServer.ts
@@ -183,6 +183,18 @@ export class DebugMCPServer {
return { content: [{ type: 'text' as const, text: result }] };
});
+ // Get loaded scripts tool
+ this.mcpServer!.registerTool('get_loaded_scripts', {
+ description: 'Returns all scripts currently loaded in the active debug session. ' +
+ 'Does not require the session to be paused — it can be called at any point while a debug session is running. ' +
+ 'Each entry includes the script name, its file path on disk (or null for dynamically generated scripts), ' +
+ 'and a sourceReference (non-zero for scripts with no on-disk path). ' +
+ 'Use this to discover exact file paths before calling add_breakpoint, ' +
+ 'which avoids unbound breakpoints caused by guessed or incorrect paths.',
+ }, async () => {
+ const result = await this.debuggingHandler.handleGetLoadedScripts();
+ return { content: [{ type: 'text' as const, text: result }] };
+ });
// Get variables tool
this.mcpServer!.registerTool('get_variables_values', {
description: 'Inspect all variable values at the current execution point. This is your window into program state - see what data looks like at runtime, verify assumptions, identify unexpected values, and understand why code behaves as it does.',
diff --git a/src/debuggingHandler.ts b/src/debuggingHandler.ts
index dd87bde..e0ff2ab 100644
--- a/src/debuggingHandler.ts
+++ b/src/debuggingHandler.ts
@@ -23,6 +23,7 @@ export interface IDebuggingHandler {
handleListBreakpoints(): Promise;
handleGetVariables(args: { scope?: 'local' | 'global' | 'all' }): Promise;
handleEvaluateExpression(args: { expression: string }): Promise;
+ handleGetLoadedScripts(): Promise;
}
/**
@@ -380,6 +381,39 @@ export class DebuggingHandler implements IDebuggingHandler {
}
}
+ /**
+ * Return all scripts currently loaded in the active debug session via the DAP loadedSources request
+ */
+ public async handleGetLoadedScripts(): Promise {
+ try {
+ const session = vscode.debug.activeDebugSession;
+
+ if (!session) {
+ return JSON.stringify({ error: 'No active debug session. Start a debug session first.' });
+ }
+
+ let response: { sources: Array<{ name: string; path?: string; sourceReference?: number }> };
+ try {
+ response = await session.customRequest('loadedSources', {});
+ } catch (err) {
+ return JSON.stringify({
+ error: 'The active debug adapter does not support loadedSources.',
+ hint: 'This capability is supported by Node.js, Electron, and Chrome-based debug adapters.',
+ });
+ }
+
+ const sources = (response.sources ?? []).map(s => ({
+ name: s.name,
+ path: s.path ?? null,
+ sourceReference: s.sourceReference ?? 0,
+ }));
+
+ return JSON.stringify(sources, null, 2);
+ } catch (error) {
+ throw new Error(`Error getting loaded scripts: ${error}`);
+ }
+ }
+
/**
* Evaluate an expression in current debug context
*/