# Delphi Build MCP Server

A Model Context Protocol (MCP) server that enables AI coding agents like Claude Code to compile Delphi projects programmatically.

## Features

- **IDE-Identical Windows Builds**: Windows targets (Win32/Win64/Win64x) compile via MSBuild, producing byte-identical output to the Delphi IDE — including icons, manifests, and DPI awareness
- **Hybrid Compilation**: MSBuild for Windows targets, direct dcc for cross-compilation (Linux64/Android/Android64)
- **Minimal Configuration**: Windows targets need only the Delphi installation path — MSBuild reads everything else from the .dproj
- **Automatic Configuration**: Generate config from IDE build logs with multi-line parsing
- **Multi-Config Support**: Generate unified config from multiple build logs (Debug/Release × Win32/Win64/Win64x/Linux64)
- **Extend Configuration**: Add new platforms or libraries to existing config without regenerating
- **Smart Compilation**: Reads .dproj files for build settings and compiler flags
- **Package Support**: Compiles both application (.dpr) and package (.dpk) projects with correct output (.exe/.bpl)
- **Filtered Output**: Returns only errors, filters out warnings and hints
- **Multi-Language Support**: Parses both English and German compiler output
- **Response File Support**: Handles command lines >8000 characters automatically
- **Cross-Platform**: Supports Win32, Win64, Win64x (LLVM), Linux64, Android, and Android64
- **Environment Variables**: Auto-expands `${USERNAME}` in paths
- **MCP Compatible**: Works with Claude Code, Cline, and other MCP clients
- **Network Transport**: Streamable HTTP support for remote access (e.g., WSL-Ubuntu to Windows host)
- **WSL Interop**: Use from WSL-Ubuntu via stdio through Windows Python or via Streamable HTTP

## Quick Start

### 1. Install

```bash
# Install UV if you haven't already
# Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh
# Or: pip install uv

cd delphi-build-mcp-server
uv venv
uv pip install -e .
```

### 2. Generate Configuration

In Delphi IDE:
1. Tools > Options > Building > Show compiler progress > "Verbose"
2. Build your project
3. View > Messages > Right-click > Copy All
4. Save to `build.log`

Then generate config:

**Single Build Log (simple projects):**
```bash
# Platform-specific config is generated by default (e.g., delphi_config_win64.toml)
uv run python -m src.config_generator build.log

# Generate generic delphi_config.toml instead
uv run python -m src.config_generator build.log --generic
```

**Multiple Build Logs (multi-platform projects):**

For projects targeting multiple platforms (Win32/Win64/Linux64), create build logs for each configuration:
1. Build in IDE with each Platform/Config combination
2. Save each build log separately (e.g., `build_debug_win32.log`, `build_release_linux64.log`)
3. Generate config from all logs:

```bash
# Separate platform-specific config files (default)
uv run python -m src.multi_config_generator build_win32.log build_win64.log
# Creates: delphi_config_win32.toml, delphi_config_win64.toml

# Custom output directory for platform-specific files
uv run python -m src.multi_config_generator *.log -d ./configs/

# Single unified config instead of separate files
uv run python -m src.multi_config_generator build_win32.log build_win64.log --unified -o my_config.toml

# Disable environment variable substitution
uv run python -m src.multi_config_generator *.log --no-env-vars
```

**Configuration Strategy:**

Windows targets (Win32/Win64/Win64x) use MSBuild, which reads all compiler settings from the .dproj file. Only a minimal `delphi_config.toml` with the Delphi installation path is needed. Cross-compilation targets (Linux64/Android/Android64) still need full platform-specific config files.

| Platform | Config File | Content |
|----------|-------------|---------|
| Win32/Win64/Win64x | `delphi_config.toml` | Minimal (only `[delphi]` section) |
| Linux64 | `delphi_config_linux64.toml` | Full (paths, flags, SDK) |
| Android | `delphi_config_android.toml` | Full (paths, flags, NDK) |
| Android64 | `delphi_config_android64.toml` | Full (paths, flags, NDK) |

**Config search order:**
1. `DELPHI_CONFIG` environment variable (explicit override)
2. `delphi_config_{platform}.toml` (platform-specific)
3. `delphi_config.toml` (generic fallback — Windows targets only)

Or use the Python API:

```python
from src.config_generator import ConfigGenerator
from src.multi_config_generator import MultiConfigGenerator
from pathlib import Path

# Single build log
generator = ConfigGenerator()
result = generator.generate_from_build_log(
    build_log_path=Path("build.log"),
    output_path=Path("delphi_config.toml")
)

# Multiple build logs (recommended for multi-platform)
multi_gen = MultiConfigGenerator()
result = multi_gen.generate_from_build_logs(
    build_log_paths=["build_debug_win32.log", "build_release_win64.log", "build_debug_linux64.log"],
    output_path=Path("delphi_config.toml")
)
print(result.message)
```

### 3. Configure Claude Code

Edit `%APPDATA%\Claude\claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "delphi-build": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "C:\\path\\to\\delphi-build-mcp-server",
        "main.py"
      ],
      "env": {
        "DELPHI_CONFIG": "C:\\path\\to\\delphi-build-mcp-server\\delphi_config.toml"
      }
    }
  }
}
```

### Server Options

The server supports two transport modes:

| Flag | Default | Description |
|------|---------|-------------|
| `--transport` | `stdio` | Transport type: `stdio` or `streamable-http` |
| `--host` | `0.0.0.0` | Bind address (streamable-http only) |
| `--port` | `8080` | Listen port (streamable-http only) |

**Local (stdio, default):**
```bash
uv run main.py
```

**Network (Streamable HTTP):**
```bash
uv run main.py --transport streamable-http
# Server listens on http://0.0.0.0:8080/mcp
```

### Configure Claude Code in WSL-Ubuntu

Two options for using the Delphi MCP server from WSL-Ubuntu:

#### Option 1: stdio via WSL Interop (Simplest)

WSL can execute Windows binaries directly. This uses stdio transport through the Windows Python -- no HTTP server needed, no manual start. Claude Code manages the server lifecycle automatically.

Edit `~/.claude.json` (or project-level `.mcp.json`) in WSL:

```json
{
  "mcpServers": {
    "delphi-build": {
      "command": "/mnt/c/Users/<username>/path/to/delphi-build-mcp-server/.venv/Scripts/python.exe",
      "args": [
        "/mnt/c/Users/<username>/path/to/delphi-build-mcp-server/main.py"
      ],
      "env": {
        "DELPHI_CONFIG": "C:\\Users\\<username>\\path\\to\\delphi_config.toml"
      }
    }
  }
}
```

> **Note:** The `DELPHI_CONFIG` path must use Windows-style paths since the server runs as a Windows process.

#### Option 2: Streamable HTTP (Network Transport)

Run the MCP server as a persistent HTTP service on Windows and connect from WSL over the network.

**1. Start the MCP server on Windows:**

```bash
cd C:\path\to\delphi-build-mcp-server
uv run main.py --transport streamable-http
```

To start the server automatically at logon, place `start_mcp_server.bat` (included in this repository) in your Windows Startup folder (`Win+R` → `shell:startup`).

**2. Find your Windows host IP from WSL:**

```bash
# Method 1: WSL gateway IP
cat /etc/resolv.conf | grep nameserver | awk '{print $2}'

# Method 2: Windows hostname
hostname -I  # run on Windows side
```

**3. Configure Claude Code in WSL:**

Edit `~/.claude.json` (or project-level `.mcp.json`):

```json
{
  "mcpServers": {
    "delphi-build": {
      "url": "http://<windows-host-ip>:8080/mcp"
    }
  }
}
```

> **Note:** If the connection is refused, you may need to allow port 8080 through Windows Firewall:
> ```powershell
> netsh advfirewall firewall add rule name="Delphi MCP Server" dir=in action=allow protocol=TCP localport=8080
> ```

### 4. Use in Claude Code

```
Please compile my Delphi project at X:\MyProject\MyApp.dproj
```

## Tools

### `compile_delphi_project`

Compile a Delphi project and return parsed results.

**Parameters:**
- `project_path` (required): Path to .dpr or .dproj file
- `force_build_all`: Force rebuild all units
- `override_config`: Override build config (Debug/Release)
- `override_platform`: Override platform (Win32/Win64/Win64x/Linux64)
- `additional_search_paths`: Extra search paths
- `additional_flags`: Additional compiler flags

**Returns:**
- `success`: Whether compilation succeeded
- `errors`: List of compilation errors (warnings/hints filtered)
- `compilation_time_seconds`: Time taken
- `output_executable`: Path to compiled EXE
- `statistics`: Compilation statistics

### `generate_config_from_build_log`

Generate `delphi_config.toml` from a single IDE build log.

**Parameters:**
- `build_log_path` (required): Path to build log file
- `output_config_path`: Output file path (overrides default platform-specific naming)
- `use_platform_specific_name`: Generate platform-specific filename (e.g., delphi_config_win64.toml) based on detected platform (default: true)
- `use_env_vars`: Replace paths with ${USERNAME} (default: true)

**Returns:**
- `success`: Whether generation succeeded
- `config_file_path`: Path to generated config
- `statistics`: Paths found and processed
- `detected_info`: Delphi version, platform, build config

### `generate_config_from_multiple_build_logs`

Generate configuration from multiple IDE build logs for different configurations and platforms. By default, creates separate platform-specific files (e.g., delphi_config_win32.toml, delphi_config_win64.toml).

**Parameters:**
- `build_log_paths` (required): Array of paths to IDE build log files (e.g., Debug-Win32, Release-Win64, Debug-Linux64)
- `output_config_path`: Output file path for unified config (only used when generate_separate_files=false)
- `generate_separate_files`: Generate separate platform-specific config files (default: true). Set to false for a single unified config.
- `output_dir`: Output directory for generated files (default: current directory)
- `use_env_vars`: Replace paths with ${USERNAME} (default: true)

**Returns:**
- `success`: Whether generation succeeded
- `config_file_path`: Path to generated config(s)
- `build_logs_processed`: Details of each processed log (path, config, platform, auto_detected)
- `statistics`: Configs found, platforms found, total library paths, files generated

### `extend_config_from_build_log`

Extend an existing `delphi_config.toml` with settings from a new IDE build log. Useful for adding support for new platforms (e.g., Win64x) or libraries without regenerating the entire configuration.

**Parameters:**
- `existing_config_path` (required): Path to existing delphi_config.toml
- `build_log_path` (required): Path to IDE build log file
- `output_config_path`: Output path (default: overwrites existing)
- `use_env_vars`: Replace paths with ${USERNAME} (default: true)

**Returns:**
- `success`: Whether extension succeeded
- `config_file_path`: Path to extended config
- `paths_added`: Number of new paths added
- `paths_skipped`: Number of duplicates skipped
- `platforms_added`: List of new platforms (e.g., ["Win64x"])
- `settings_updated`: Count of settings updated per section

## Documentation

- **[QUICKSTART.md](QUICKSTART.md)** - 5-minute setup guide
- **[DOCUMENTATION.md](DOCUMENTATION.md)** - Complete reference

## Project Structure

```
delphi-build-mcp-server/
|-- main.py                       # MCP server entry point (stdio + streamable-http)
|-- src/
|   |-- models.py                 # Pydantic data models
|   |-- buildlog_parser.py        # Parse IDE build logs
|   |-- dproj_parser.py           # Parse .dproj files
|   |-- config.py                 # Load TOML configuration
|   |-- output_parser.py          # Parse dcc compiler output
|   |-- msbuild_output_parser.py  # Parse MSBuild output (extracts _PasCoreCompile)
|   |-- msbuild_compiler.py       # MSBuild compilation for Windows targets
|   |-- rsvars_parser.py          # Parse rsvars.bat for MSBuild environment
|   |-- config_generator.py       # Generate TOML configs (single log)
|   |-- multi_config_generator.py # Generate TOML configs (multi-log)
|   |-- config_extender.py        # Extend existing TOML configs
|   +-- compiler.py               # Direct dcc compilation for cross-compilation
|-- tests/                        # Unit tests
|-- start_mcp_server.bat          # Auto-start script for Windows (shell:startup)
|-- test_stdio_wsl.sh             # Test stdio transport from WSL
|-- test_http_transport.sh        # Test Streamable HTTP transport (bash)
|-- test_http_transport.bat       # Test Streamable HTTP transport (Windows)
|-- delphi_config.toml.template   # Configuration template
|-- pyproject.toml                # Python project config
|-- QUICKSTART.md                 # Quick start guide
+-- DOCUMENTATION.md              # Complete documentation
```

## Requirements

- Python 3.10+
- Delphi 11, 12, or 13
- MCP-compatible client (Claude Code, Cline, etc.)

## How It Works

**Note:** The server automatically handles response files for projects with 80+ library paths (command lines >8000 chars) and parses both English and German compiler output.

```
1. AI Agent calls compile_delphi_project
   |
   v
2. Parse .dproj file to determine platform
   |
   v
3. Route based on platform:
   |
   +---> Windows (Win32/Win64/Win64x):
   |     - Load minimal config (delphi.root_path only)
   |     - Set up MSBuild environment from rsvars.bat
   |     - Execute msbuild.exe (IDE-identical output)
   |     - Parse _PasCoreCompile section for errors
   |
   +---> Cross-compilation (Linux64/Android/Android64):
         - Load full platform-specific config
         - Build dcc compiler command
         - Execute dcc32/dcc64/dcclinux64/dccaarm64
         - Parse compiler output for errors
   |
   v
4. Return structured result to AI
```

## Example Usage

### Compile a Project

```python
from src.compiler import DelphiCompiler
from pathlib import Path

compiler = DelphiCompiler()
result = compiler.compile_project(
    project_path=Path("X:/MyProject/MyApp.dproj")
)

if result.success:
    print(f"[OK] Compilation successful: {result.output_executable}")
else:
    print(f"[FAIL] Compilation failed with {len(result.errors)} errors:")
    for error in result.errors:
        print(f"  {error.file}({error.line},{error.column}): {error.message}")
```

### Generate Config from Build Log

```python
from src.config_generator import ConfigGenerator
from pathlib import Path

generator = ConfigGenerator(use_env_vars=True)
result = generator.generate_from_build_log(
    build_log_path=Path("build.log"),
    output_path=Path("delphi_config.toml")
)

print(f"[OK] {result.message}")
print(f"  Detected: Delphi {result.detected_info.delphi_version}")
print(f"  Platform: {result.detected_info.platform}")
print(f"  Paths found: {result.statistics['unique_paths']}")
```

### Generate Multi-Platform Config from Multiple Build Logs

```python
from src.multi_config_generator import MultiConfigGenerator
from pathlib import Path

generator = MultiConfigGenerator(use_env_vars=True)
result = generator.generate_from_build_logs(
    build_log_paths=[
        "build_debug_win32.log",
        "build_release_win32.log",
        "build_debug_linux64.log",
        "build_release_linux64.log"
    ],
    output_path=Path("delphi_config.toml")
)

print(f"[OK] {result.message}")
print(f"  Configs: {result.statistics['configs_found']}")
print(f"  Platforms: {result.statistics['platforms_found']}")
print(f"  Total paths: {result.statistics['total_library_paths']}")
```

### Extend Existing Config with New Platform

```python
from src.config_extender import ConfigExtender
from pathlib import Path

# Extend existing config with Win64x platform support
extender = ConfigExtender(use_env_vars=True)
result = extender.extend_from_build_log(
    existing_config_path=Path("delphi_config.toml"),
    build_log_path=Path("build_win64x.log")
)

print(f"[OK] {result.message}")
print(f"  New platforms: {result.platforms_added}")
print(f"  Paths added: {result.paths_added}")
print(f"  Paths skipped (duplicates): {result.paths_skipped}")
```

Or via CLI:

```bash
uv run python -m src.config_extender delphi_config.toml build_win64x.log
uv run python -m src.config_extender delphi_config.toml build_win64x.log -o extended_config.toml
```

## Troubleshooting

### "Configuration file not found"

Generate it from a build log:
```bash
uv run python -m src.config_generator build.log
```

### "Unit not found"

Regenerate config from a fresh IDE build log that includes all dependencies.

### "Compiler not found"

Verify `delphi.root_path` in `delphi_config.toml` points to your Delphi installation.

## Development

### Install Development Dependencies

```bash
uv pip install -e ".[dev]"
```

### Run Tests

```bash
uv run pytest
```

### Test Sample Projects

Two sample projects are included for testing:

```bash
# Test successful compilation
uv run python test_compile_samples.py
```

- **sample/working/Working.dproj** - Compiles successfully
- **sample/broken/Broken.dproj** - Intentionally has errors for testing error parsing

### Code Formatting

```bash
uv run black src/
uv run ruff check src/
```

## Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

## License

MIT License - see LICENSE file for details.

## Support

- **Documentation**: [DOCUMENTATION.md](DOCUMENTATION.md)
- **Quick Start**: [QUICKSTART.md](QUICKSTART.md)
- **Issues**: https://github.com/basti-fantasti/delphi-build-mcp-server/issues

## Acknowledgments

- Built with [Model Context Protocol](https://modelcontextprotocol.io)
- Designed for [Claude Code](https://claude.com/claude-code)
- Supports [Embarcadero Delphi](https://www.embarcadero.com/products/delphi)
