Skip to main content
Glama

generate_config_from_multiple_build_logs

Generate delphi_config.toml files from multiple IDE build logs, producing separate platform-specific configs or a unified config for different configurations and platforms.

Instructions

Generate delphi_config.toml file from multiple IDE build logs for different configurations and platforms. By default, creates separate platform-specific config files (e.g., delphi_config_win32.toml, delphi_config_win64.toml). Use this when you have build logs from multiple configurations (Debug/Release) and/or platforms (Win32/Win64/Linux64/Android/Android64).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
build_log_pathsYesArray of absolute paths to IDE build log files (e.g., Debug-Win32, Release-Win64, Debug-Linux64, Debug-Android64)
output_config_pathNoOutput path for unified config file. Only used when generate_separate_files=False.delphi_config.toml
generate_separate_filesNoGenerate separate platform-specific config files (default). Set to false for a single unified config.
output_dirNoOutput directory for generated platform-specific files. Defaults to current directory..
use_env_varsNoReplace user paths with ${USERNAME} environment variable

Implementation Reference

  • main.py:329-361 (handler)
    The async handler function that executes the generate_config_from_multiple_build_logs tool. It extracts arguments from the tool call, instantiates MultiConfigGenerator, calls generate_from_build_logs(), and returns JSON result.
    async def handle_generate_multi_config(arguments: dict) -> str:
        """Handle generate_config_from_multiple_build_logs tool invocation.
    
        Args:
            arguments: Tool arguments
    
        Returns:
            JSON string with generation result
        """
        import json
    
        # Extract arguments (convert WSL paths when running on Windows)
        build_log_paths = [convert_wsl_to_windows_path(p) for p in arguments["build_log_paths"]]
        output_config_path_str = arguments.get("output_config_path")
        output_config_path = Path(convert_wsl_to_windows_path(output_config_path_str)) if output_config_path_str else None
        generate_separate_files = arguments.get("generate_separate_files", True)
        output_dir_str = arguments.get("output_dir", ".")
        output_dir = Path(convert_wsl_to_windows_path(output_dir_str))
        use_env_vars = arguments.get("use_env_vars", True)
    
        # Initialize generator
        generator = MultiConfigGenerator(use_env_vars=use_env_vars)
    
        # Generate config from multiple logs
        result = generator.generate_from_build_logs(
            build_log_paths=build_log_paths,
            output_path=output_config_path,
            generate_separate_files=generate_separate_files,
            output_dir=output_dir,
        )
    
        # Convert to JSON
        return json.dumps(result.model_dump(), indent=2)
  • main.py:117-157 (registration)
    The Tool definition object registering the tool with the MCP server, including its name, description, and JSON input schema.
    GENERATE_MULTI_CONFIG_TOOL = Tool(
        name="generate_config_from_multiple_build_logs",
        description=(
            "Generate delphi_config.toml file from multiple IDE build logs for different configurations "
            "and platforms. By default, creates separate platform-specific config files "
            "(e.g., delphi_config_win32.toml, delphi_config_win64.toml). "
            "Use this when you have build logs from multiple configurations (Debug/Release) and/or "
            "platforms (Win32/Win64/Linux64/Android/Android64)."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "build_log_paths": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Array of absolute paths to IDE build log files (e.g., Debug-Win32, Release-Win64, Debug-Linux64, Debug-Android64)",
                },
                "output_config_path": {
                    "type": "string",
                    "description": "Output path for unified config file. Only used when generate_separate_files=False.",
                    "default": "delphi_config.toml",
                },
                "generate_separate_files": {
                    "type": "boolean",
                    "description": "Generate separate platform-specific config files (default). Set to false for a single unified config.",
                    "default": True,
                },
                "output_dir": {
                    "type": "string",
                    "description": "Output directory for generated platform-specific files. Defaults to current directory.",
                    "default": ".",
                },
                "use_env_vars": {
                    "type": "boolean",
                    "description": "Replace user paths with ${USERNAME} environment variable",
                    "default": True,
                },
            },
            "required": ["build_log_paths"],
        },
    )
  • main.py:212-214 (registration)
    The call_tool dispatcher that routes the tool name to the handler function.
    elif name == "generate_config_from_multiple_build_logs":
        result = await handle_generate_multi_config(arguments)
        return [TextContent(type="text", text=result)]
  • main.py:195-197 (registration)
    The list_tools function that exposes the tool definition to the MCP client.
    async def list_tools() -> list[Tool]:
        """List available tools."""
        return [COMPILE_TOOL, GENERATE_CONFIG_TOOL, GENERATE_MULTI_CONFIG_TOOL, EXTEND_CONFIG_TOOL]
  • The core logic: MultiConfigGenerator.generate_from_build_logs() method. Parses multiple build logs, then either generates separate platform-specific configs (Windows gets minimal, cross-compile gets full) or a single unified config.
    def generate_from_build_logs(
        self,
        build_log_paths: list[str],
        output_path: Optional[Path] = None,
        generate_separate_files: bool = True,
        output_dir: Optional[Path] = None,
    ) -> MultiConfigGenerationResult:
        """Generate configuration from multiple build log files.
    
        Args:
            build_log_paths: List of paths to IDE build log files
            output_path: Path where to save the generated config. Used when
                generate_separate_files=False.
            generate_separate_files: If True (default), generates separate platform-specific
                config files (e.g., delphi_config_win32.toml, delphi_config_win64.toml).
                Set to False to generate a single unified config.
            output_dir: Directory for output files when generate_separate_files=True.
                Defaults to current directory.
    
        Returns:
            MultiConfigGenerationResult with generation statistics
    
        Raises:
            FileNotFoundError: If any build log doesn't exist
            ValueError: If no build logs can be parsed
        """
        # Parse all build logs
        parsed_logs: dict[tuple[str, str], BuildLogInfo] = {}
        log_entries: list[BuildLogEntry] = []
    
        for log_path_str in build_log_paths:
            log_path = Path(log_path_str)
            if not log_path.exists():
                raise FileNotFoundError(f"Build log not found: {log_path}")
    
            parser = BuildLogParser(log_path)
    
            # Parse the log content
            log_info = parser.parse()
    
            # Get config and platform from parsed log
            config = log_info.build_config
            platform = log_info.platform.value
            auto_detected = True  # Values are detected from compiler command
    
            # Normalize config and platform names
            config = self._normalize_config(config)
            platform = self._normalize_platform(platform)
    
            # Store parsed log info keyed by (config, platform)
            key = (config, platform)
            if key in parsed_logs:
                # If we already have this config/platform, merge paths
                self._merge_log_info(parsed_logs[key], log_info)
            else:
                parsed_logs[key] = log_info
    
            log_entries.append(BuildLogEntry(
                path=str(log_path),
                config=config,
                platform=platform,
                auto_detected=auto_detected,
            ))
    
        if not parsed_logs:
            raise ValueError("No build logs could be parsed successfully")
    
        # Determine output directory
        if output_dir is None:
            output_dir = Path(".")
    
        generated_files: list[str] = []
    
        if generate_separate_files:
            # Generate separate platform-specific config files.
            # All Windows platform logs are grouped into one minimal delphi_config.toml.
            # Cross-compile platforms (Linux64, Android, Android64) each get their own file.
            platforms = set(k[1] for k in parsed_logs.keys())
    
            windows_platforms_found = platforms & WINDOWS_PLATFORMS
            crosscompile_platforms = platforms - WINDOWS_PLATFORMS
    
            if windows_platforms_found:
                # Collect all Windows logs; pick the first one as representative
                windows_logs = {
                    k: v for k, v in parsed_logs.items() if k[1] in WINDOWS_PLATFORMS
                }
                first_windows_log = next(iter(windows_logs.values()))
                # Generate minimal config: only [delphi] section + MSBuild comment
                toml_content = self._generate_windows_minimal_toml(first_windows_log)
                windows_output_path = output_dir / "delphi_config.toml"
                with open(windows_output_path, "w", encoding="utf-8") as f:
                    f.write(toml_content)
                generated_files.append(str(windows_output_path.absolute()))
    
            for platform in sorted(crosscompile_platforms):
                # Get logs for this platform only
                platform_logs = {
                    k: v for k, v in parsed_logs.items() if k[1] == platform
                }
                # Generate TOML content for this platform
                toml_content = self._generate_toml(platform_logs)
                # Write to platform-specific file
                platform_filename = get_platform_config_filename(platform)
                platform_output_path = output_dir / platform_filename
                with open(platform_output_path, "w", encoding="utf-8") as f:
                    f.write(toml_content)
                generated_files.append(str(platform_output_path.absolute()))
    
            # config_file_path will contain comma-separated list of files
            config_file_path = ", ".join(generated_files)
            message = f"Generated {len(generated_files)} platform-specific config file(s) from {len(build_log_paths)} build log(s)"
        else:
            # Generate single unified config
            if output_path is None:
                output_path = output_dir / "delphi_config.toml"
    
            toml_content = self._generate_toml(parsed_logs)
    
            # Write to file
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(toml_content)
    
            config_file_path = str(output_path.absolute())
            generated_files.append(config_file_path)
            message = f"Configuration file generated successfully from {len(build_log_paths)} build log(s)"
    
        # Prepare statistics
        statistics = {
            "build_logs_parsed": len(build_log_paths),
            "configs_found": list(set(e.config for e in log_entries)),
            "platforms_found": list(set(e.platform for e in log_entries)),
            "total_library_paths": self._count_total_paths(parsed_logs),
            "files_generated": generated_files,
        }
    
        return MultiConfigGenerationResult(
            success=True,
            config_file_path=config_file_path,
            build_logs_processed=log_entries,
            statistics=statistics,
            message=message,
        )
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Given no annotations, description carries full burden. It covers default behavior (separate files) and key parameters, but lacks details on file overwriting, error handling, or output structure. Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: first states purpose and default behavior, second gives usage guidance. Front-loaded with key information, no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers main use case and key behaviors adequately given high schema coverage. Lacks output format details and error behavior, but sufficient for most agents.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema descriptions cover all 5 parameters fully (100% coverage). The tool description adds minimal additional context beyond summarizing the schema, so baseline score applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly identifies the action (generate), resource (delphi_config.toml), and context (from multiple IDE build logs). Differentiates from siblings by specifying 'multiple' configurations and platforms, contrasting with the singular version.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: when you have build logs from multiple configurations and/or platforms. Implicitly suggests not using it for single logs (sibling tool). Could be improved by naming alternatives directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Basti-Fantasti/delphi-build-mcp-server'

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