Skip to main content
Glama

get_variables

Retrieve variable values and details from a specific debugging scope using the variablesReference identifier to inspect program state during debugging sessions.

Instructions

Get variables (scope is variablesReference: number)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sessionIdYes
scopeYesThe variablesReference number from a StackFrame or Variable

Implementation Reference

  • MCP tool handler for 'get_variables': validates input, fetches variables via session manager, logs, and returns JSON response.
    case 'get_variables': {
      if (!args.sessionId || args.scope === undefined) {
        throw new McpError(McpErrorCode.InvalidParams, 'Missing required parameters');
      }
      
      try {
        const variables = await this.getVariables(args.sessionId, args.scope);
        
        // Log variable inspection (truncate large values)
        const truncatedVars = variables.map(v => ({
          name: v.name,
          type: v.type,
          value: v.value.length > 200 ? v.value.substring(0, 200) + '... (truncated)' : v.value
        }));
        
        this.logger.info('debug:variables', {
          sessionId: args.sessionId,
          sessionName: this.getSessionName(args.sessionId),
          variablesReference: args.scope,
          variableCount: variables.length,
          variables: truncatedVars.slice(0, 10), // Log first 10 variables
          timestamp: Date.now()
        });
        
        result = { content: [{ type: 'text', text: JSON.stringify({ success: true, variables, count: variables.length, variablesReference: args.scope }) }] };
      } catch (error) {
        // Handle validation errors specifically
        if (error instanceof SessionTerminatedError ||
            error instanceof SessionNotFoundError ||
            error instanceof ProxyNotRunningError) {
          result = { content: [{ type: 'text', text: JSON.stringify({ success: false, error: error.message }) }] };
        } else {
          // Re-throw unexpected errors
          throw error;
        }
      }
      break;
  • Tool schema definition for 'get_variables' including input schema, description, and parameters (sessionId, scope). Included in list_tools response.
    { name: 'get_variables', description: 'Get variables (scope is variablesReference: number)', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, scope: { type: 'number', description: "The variablesReference number from a StackFrame or Variable" } }, required: ['sessionId', 'scope'] } },
  • src/server.ts:443-486 (registration)
    Registration of all MCP tools including 'get_variables' schema in the ListToolsRequest handler.
        tools: [
          { name: 'create_debug_session', description: 'Create a new debugging session', inputSchema: { type: 'object', properties: { language: { type: 'string', enum: supportedLanguages, description: 'Programming language for debugging' }, name: { type: 'string', description: 'Optional session name' }, executablePath: {type: 'string', description: 'Path to language executable (optional, will auto-detect if not provided)'} }, required: ['language'] } },
          { name: 'list_supported_languages', description: 'List all supported debugging languages with metadata', inputSchema: { type: 'object', properties: {} } },
          { name: 'list_debug_sessions', description: 'List all active debugging sessions', inputSchema: { type: 'object', properties: {} } },
          { name: 'set_breakpoint', description: 'Set a breakpoint. Setting breakpoints on non-executable lines (structural, declarative) may lead to unexpected behavior', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, file: { type: 'string', description: fileDescription }, line: { type: 'number', description: 'Line number where to set breakpoint. Executable statements (assignments, function calls, conditionals, returns) work best. Structural lines (function/class definitions), declarative lines (imports), or non-executable lines (comments, blank lines) may cause unexpected stepping behavior' }, condition: { type: 'string' } }, required: ['sessionId', 'file', 'line'] } },
          { name: 'start_debugging', description: 'Start debugging a script', inputSchema: { 
              type: 'object', 
              properties: { 
                sessionId: { type: 'string' }, 
                scriptPath: { type: 'string', description: scriptPathDescription }, 
                args: { type: 'array', items: { type: 'string' } }, 
                dapLaunchArgs: { 
                  type: 'object', 
                  properties: { 
                    stopOnEntry: { type: 'boolean' },
                    justMyCode: { type: 'boolean' } 
                  },
                  additionalProperties: true
                },
                dryRunSpawn: { type: 'boolean' },
                adapterLaunchConfig: {
                  type: 'object',
                  description: 'Optional adapter-specific launch configuration overrides',
                  additionalProperties: true
                }
              }, 
              required: ['sessionId', 'scriptPath'] 
            } 
          },
          { name: 'close_debug_session', description: 'Close a debugging session', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'step_over', description: 'Step over', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'step_into', description: 'Step into', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'step_out', description: 'Step out', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'continue_execution', description: 'Continue execution', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'pause_execution', description: 'Pause execution (Not Implemented)', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' } }, required: ['sessionId'] } },
          { name: 'get_variables', description: 'Get variables (scope is variablesReference: number)', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, scope: { type: 'number', description: "The variablesReference number from a StackFrame or Variable" } }, required: ['sessionId', 'scope'] } },
          { name: 'get_local_variables', description: 'Get local variables for the current stack frame. This is a convenience tool that returns just the local variables without needing to traverse stack->scopes->variables manually', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, includeSpecial: { type: 'boolean', description: 'Include special/internal variables like this, __proto__, __builtins__, etc. Default: false' } }, required: ['sessionId'] } },
          { name: 'get_stack_trace', description: 'Get stack trace', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, includeInternals: { type: 'boolean', description: 'Include internal/framework frames (e.g., Node.js internals). Default: false for cleaner output.' } }, required: ['sessionId'] } },
          { name: 'get_scopes', description: 'Get scopes for a stack frame', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, frameId: { type: 'number', description: "The ID of the stack frame from a stackTrace response" } }, required: ['sessionId', 'frameId'] } },
          { name: 'evaluate_expression', description: 'Evaluate expression in the current debug context. Expressions can read and modify program state', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, expression: { type: 'string' }, frameId: { type: 'number', description: 'Optional stack frame ID for evaluation context. Must be a frame ID from a get_stack_trace response. If not provided, uses the current (top) frame automatically' } }, required: ['sessionId', 'expression'] } },
          { name: 'get_source_context', description: 'Get source context around a specific line in a file', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, file: { type: 'string', description: fileDescription }, line: { type: 'number', description: 'Line number to get context for' }, linesContext: { type: 'number', description: 'Number of lines before and after to include (default: 5)' } }, required: ['sessionId', 'file', 'line'] } },
        ],
      };
    });
  • Server wrapper method for getVariables that validates session existence before delegating to SessionManager.
    public async getVariables(sessionId: string, variablesReference: number): Promise<Variable[]> {
      this.validateSession(sessionId);
      return this.sessionManager.getVariables(sessionId, variablesReference);
    }
  • Core implementation of getVariables: sends DAP 'variables' request to the debug proxy, parses response, handles errors and empty responses.
    async getVariables(sessionId: string, variablesReference: number): Promise<Variable[]> {
      const session = this._getSessionById(sessionId);
      this.logger.info(`[SM getVariables ${sessionId}] Entered. variablesReference: ${variablesReference}, Current state: ${session.state}`);
      
      if (!session.proxyManager || !session.proxyManager.isRunning()) { 
        this.logger.warn(`[SM getVariables ${sessionId}] No active proxy.`); 
        return []; 
      }
      if (session.state !== SessionState.PAUSED) { 
        this.logger.warn(`[SM getVariables ${sessionId}] Session not paused. State: ${session.state}.`); 
        return []; 
      }
      
      try {
        this.logger.info(`[SM getVariables ${sessionId}] Sending DAP 'variables' for variablesReference ${variablesReference}.`);
        const response = await session.proxyManager.sendDapRequest<DebugProtocol.VariablesResponse>('variables', { variablesReference });
        this.logger.info(`[SM getVariables ${sessionId}] DAP 'variables' response received. Body:`, response?.body);
    
        if (response && response.body && response.body.variables) {
          const vars = response.body.variables.map((v: DebugProtocol.Variable) => ({ 
              name: v.name, value: v.value, type: v.type || "<unknown_type>", 
              variablesReference: v.variablesReference,
              expandable: v.variablesReference > 0 
          }));
          this.logger.info(`[SM getVariables ${sessionId}] Parsed variables:`, vars.map(v => ({name: v.name, value: v.value, type: v.type}))); 
          return vars;
        }
        this.logger.warn(`[SM getVariables ${sessionId}] No variables in response body for reference ${variablesReference}. Response:`, response);
        return [];
      } catch (error) {
        this.logger.error(`[SM getVariables ${sessionId}] Error getting variables:`, error);
        return [];
      }
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/debugmcpdev/mcp-debugger'

If you have feedback or need assistance with the MCP directory API, please join our Discord server