Skip to main content
Glama

list_supported_languages

Discover available programming languages for debugging with metadata to identify compatible options for step-through debugging using the Debug Adapter Protocol.

Instructions

List all supported debugging languages with metadata

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function for the 'list_supported_languages' tool. It queries the adapter registry for installed and available languages, fetches metadata, and returns a comprehensive list including package names, installation status, and display information.
    private async handleListSupportedLanguages(): Promise<ServerResult> {
      try {
        const adapterRegistry = this.getAdapterRegistry();
        // Get installed languages via dynamic registry if available
        const installed = await this.getSupportedLanguagesAsync();
    
        // Also surface known adapters with install status if available from registry
        let available: Array<{ language: string; package: string; installed: boolean; description?: string }> = installed.map(lang => ({
          language: lang,
          package: `@debugmcp/adapter-${lang}`,
          installed: true
        }));
    
        if (adapterRegistry) {
          const dyn = adapterRegistry as unknown as { listAvailableAdapters?: () => Promise<Array<{ name: string; packageName: string; description?: string; installed: boolean }>> };
          if (typeof dyn.listAvailableAdapters === 'function') {
          try {
            const meta = await dyn.listAvailableAdapters!();
            available = meta.map(m => ({
              language: m.name,
              package: m.packageName,
              installed: m.installed,
              description: m.description
            }));
          } catch (e) {
            this.logger.warn('Failed to query detailed adapter metadata; returning installed list only', { error: (e as Error)?.message });
          }
        }
        }
    
        // Also build simple metadata array for backward compatibility with previous payload shape
        const languageMetadata = await this.getLanguageMetadata();
    
        return { content: [{ type: 'text', text: JSON.stringify({
          success: true,
          installed,
          available,
          languages: languageMetadata, // backward-compatible field with display info
          count: installed.length
        }) }] };
      } catch (error) {
        this.logger.error('Failed to list supported languages', { error });
        throw new McpError(McpErrorCode.InternalError, `Failed to list supported languages: ${(error as Error).message}`);
      }
    }
  • The schema definition for the 'list_supported_languages' tool, registered in the list tools response. It takes no input parameters.
    { name: 'list_supported_languages', description: 'List all supported debugging languages with metadata', inputSchema: { type: 'object', properties: {} } },
  • src/server.ts:432-486 (registration)
    Registration of all tools including 'list_supported_languages' in the MCP server's ListToolsRequest handler. Dynamically includes supported languages in the create_debug_session schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      this.logger.debug('Handling ListToolsRequest');
      
      // Get supported languages dynamically - deferred until request time
      const supportedLanguages = await this.getSupportedLanguagesAsync();
      
      // Generate dynamic descriptions for path parameters
      const fileDescription = this.getPathDescription('source file');
      const scriptPathDescription = this.getPathDescription('script');
      
      return {
        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'] } },
        ],
      };
    });
  • Helper method that retrieves the list of supported languages, considering dynamic discovery, disabled languages, and container environment specifics.
    private async getSupportedLanguagesAsync(): Promise<string[]> {
      const disabled = getDisabledLanguages();
      const filter = (langs: readonly string[]) => this.filterDisabledLanguages(langs, disabled);
      const adapterRegistry = this.getAdapterRegistry();
      // Guard against undefined registry in certain test environments
      if (!adapterRegistry) {
        return filter(getDefaultLanguages());
      }
      // Prefer dynamic discovery if available on the concrete registry
      const dynRegistry = adapterRegistry as unknown as { listLanguages?: () => Promise<string[]> };
      const maybeList = dynRegistry.listLanguages;
      if (typeof maybeList === 'function') {
        try {
          const langs = await maybeList.call(adapterRegistry);
          if (Array.isArray(langs) && langs.length > 0) {
            const normalized =
              process.env.MCP_CONTAINER === 'true' ? ensureLanguage(langs, 'python') : langs;
            return filter(normalized);
          }
        } catch (e) {
          this.logger.warn('Dynamic adapter language discovery failed, falling back to registered languages', { error: (e as Error)?.message });
        }
      }
      // Fallback to already-registered factories (may be empty until first use)
      const langs = adapterRegistry.getSupportedLanguages?.() || [];
      if (langs.length > 0) {
        // In container runtime, ensure python is advertised even if not yet registered (preload may be async)
        if (process.env.MCP_CONTAINER === 'true') {
          return filter(ensureLanguage(langs, 'python'));
        }
        return filter(langs);
      }
      // Final fallback to known defaults for UX (ensure python listed in container)
      if (process.env.MCP_CONTAINER === 'true') {
        return filter(ensureLanguage(getDefaultLanguages(), 'python'));
      }
      return filter(getDefaultLanguages());
    }
  • Helper method that generates metadata (display name, version, executable info) for each supported language.
    private async getLanguageMetadata(): Promise<LanguageMetadata[]> {
      const languages = await this.getSupportedLanguagesAsync();
    
      // Map to metadata - in future, this info can come directly from adapter registry
      return languages.map((lang: string) => {
        switch (lang) {
          case 'python':
            return {
              id: 'python',
              displayName: 'Python',
              version: '1.0.0',
              requiresExecutable: true,
              defaultExecutable: 'python'
            };
          case 'mock':
            return {
              id: 'mock',
              displayName: 'Mock',
              version: '1.0.0',
              requiresExecutable: false
            };
          case 'javascript':
            return {
              id: 'javascript',
              displayName: 'JavaScript/TypeScript',
              version: '1.0.0',
              requiresExecutable: true,
              defaultExecutable: 'node'
            };
          default:
            return {
              id: lang,
              displayName: lang.charAt(0).toUpperCase() + lang.slice(1),
              version: '1.0.0',
              requiresExecutable: true
            };
        }
      });
    }

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