Skip to content

Troubleshooting

github-actions[bot] edited this page Mar 18, 2026 · 20 revisions

Troubleshooting

MATLAB Engine Connection Failures

Symptom: Engine start timeout, matlab.engine not found, or MATLAB failed to start

Solutions:

  1. Verify MATLAB Engine API is installed:

    python -c "import matlab.engine; print('OK')"

    If this fails, the Engine API is not installed or not on your Python path.

  2. Install the Engine API:

    # macOS
    cd /Applications/MATLAB_R2024a.app/extern/engines/python
    pip install .
    
    # Windows
    cd "C:\Program Files\MATLAB\R2024a\extern\engines\python"
    pip install .
  3. Check MATLAB version: Must be 2020b or later.

  4. Set MATLAB root explicitly: If auto-detection fails, configure the path in config.yaml:

    pool:
      matlab_root: "/Applications/MATLAB_R2024a.app"  # macOS
      # matlab_root: "C:\\Program Files\\MATLAB\\R2024a"  # Windows

    Or via environment variable:

    export MATLAB_MCP_POOL_MATLAB_ROOT=/Applications/MATLAB_R2024a.app
  5. Increase engine start timeout: If MATLAB is slow to start on your system:

    pool:
      engine_start_timeout: 300  # 5 minutes (default: 120)

    Or:

    export MATLAB_MCP_POOL_ENGINE_START_TIMEOUT=300
  6. Check MATLAB license: Ensure your MATLAB license allows headless execution. Run matlab -batch "disp('OK')" to verify.

Engine Pool Startup Problems

Symptom: Pool fails to initialize, or engines die shortly after starting

Solutions:

  1. Check pool configuration:

    pool:
      min_engines: 2         # start with 2 warm engines
      max_engines: 10        # hard ceiling
      health_check_interval: 60  # seconds between pings
  2. Enable debug logging to see engine startup details:

    server:
      log_level: "debug"
      log_file: "./logs/server.log"

    Check the log file for engine startup errors.

  3. Check system resources: Each MATLAB engine uses ~500MB–1GB RAM. Ensure you have enough memory:

    free -h  # Linux/macOS
    wmic OS get TotalVisibleMemorySize,FreePhysicalMemory  # Windows
  4. Increase health check timeout: If engines fail health checks due to system load:

    pool:
      health_check_interval: 120  # 2 minutes instead of 1
  5. macOS-specific: MATLAB has a limit of ~4 concurrent engine instances on macOS. Configure:

    pool:
      max_engines: 4

Timeout Tuning

Symptom: Jobs are timing out, or operations that should be async are promoted too early

Sync vs. Async Promotion

By default, jobs run synchronously (blocking) for up to 30 seconds. If they exceed this time, they are promoted to asynchronous (job ID returned, agent polls for results).

To increase sync timeout (for operations that should complete quickly but need more time):

execution:
  sync_timeout: 60  # 60 seconds instead of 30

Or:

export MATLAB_MCP_EXECUTION_SYNC_TIMEOUT=60

Hard Execution Limit

Symptom: Long-running jobs are killed after 24 hours

The max_execution_time is a hard ceiling. Increase if your jobs legitimately need more time:

execution:
  max_execution_time: 259200  # 72 hours instead of 24

Or:

export MATLAB_MCP_EXECUTION_MAX_EXECUTION_TIME=259200

Workspace Isolation

If you need workspace persistence across calls (to share variables), disable isolation:

execution:
  workspace_isolation: true  # default: sessions get fresh workspaces
  engine_affinity: true      # pin session to same engine

This pins the session to the same engine and skips workspace reset between calls.

Logging Configuration

Enable Debug Logging

server:
  log_level: "debug"
  log_file: "./logs/server.log"

Or via environment variable:

export MATLAB_MCP_SERVER_LOG_LEVEL=debug

Logs are written to ./logs/server.log (relative to working directory) or the path specified in config.

Log Levels

  • debug — Detailed engine lifecycle, code execution, result conversion
  • info — Job status, pool events, health checks (default)
  • warning — Timeouts, blocked functions, conversion failures
  • error — Exceptions, startup failures

What to look for in logs

[DEBUG] Engine 1 started (PID 12345)
[DEBUG] Job job_abc123 executing: execute_code
[DEBUG] Result size: 1.2 MB, saving to file
[ERROR] BlockedFunctionError: Function 'system' is blocked
[WARNING] Plotly conversion failed for figure, falling back to PNG

Docker Networking

Symptom: Cannot connect to server from Docker container, or MATLAB engine fails to start in Docker

Network Configuration

  1. SSE Transport (multi-user):

    docker run -p 8765:8765 -p 8766:8766 \
      -v /path/to/MATLAB:/opt/matlab:ro \
      -e MATLAB_MCP_POOL_MATLAB_ROOT=/opt/matlab \
      -e MATLAB_MCP_SERVER_TRANSPORT=sse \
      -e MATLAB_MCP_SERVER_HOST=0.0.0.0 \
      matlab-mcp

    Connect to http://localhost:8765/sse from the host.

  2. MATLAB Root Path: MATLAB must be mounted into the container and configured:

    docker run \
      -v /usr/local/MATLAB/R2024a:/opt/matlab:ro \
      -e MATLAB_MCP_POOL_MATLAB_ROOT=/opt/matlab \
      matlab-mcp

    Ensure the mount path matches the MATLAB_MCP_POOL_MATLAB_ROOT environment variable.

  3. Docker Compose: Edit docker-compose.yml to mount your MATLAB path:

    services:
      matlab-mcp:
        build: .
        ports:
          - "8765:8765"
          - "8766:8766"
        volumes:
          - /usr/local/MATLAB/R2024a:/opt/matlab:ro
        environment:
          MATLAB_MCP_POOL_MATLAB_ROOT: /opt/matlab
          MATLAB_MCP_SERVER_TRANSPORT: sse

    Then:

    docker compose up
  4. Check MATLAB is accessible:

    docker exec matlab-mcp ls /opt/matlab/bin

    If this fails, the mount path is wrong.

Common Docker Issues

Symptom Cause Solution
matlab.engine not found Engine API not installed in container Install Engine API in Dockerfile before running
MATLAB failed to start MATLAB path not mounted Check -v mount and MATLAB_MCP_POOL_MATLAB_ROOT
Connection refused Server not binding to 0.0.0.0 Set MATLAB_MCP_SERVER_HOST=0.0.0.0
Container exits immediately MATLAB license failure Check license server is accessible, or use license server URL

Enable Debug Logging

Quick Start

Option 1: Via config.yaml

server:
  log_level: "debug"
  log_file: "./logs/server.log"

Option 2: Via environment variable

export MATLAB_MCP_SERVER_LOG_LEVEL=debug
matlab-mcp

Option 3: Both config and environment (environment takes precedence)

export MATLAB_MCP_SERVER_LOG_LEVEL=debug
export MATLAB_MCP_SERVER_LOG_FILE=/var/log/matlab-mcp.log
matlab-mcp

Viewing Logs

# Follow logs in real-time
tail -f ./logs/server.log

# Search for errors
grep ERROR ./logs/server.log

# Last 50 lines
tail -50 ./logs/server.log

Debug Topics

Enable debug logging to troubleshoot:

  • Engine lifecycle: Engine X started, Engine X health check, Engine X shutdown
  • Code execution: Job Y executing: execute_code, Result size, Conversion time
  • Pool management: Queue depth, Scaling decision, Engine allocation
  • Plot conversion: Plotly conversion, Axes found, Line data extracted
  • Security: BlockedFunctionError, Function validation

Blocked Function Error

Symptom: BlockedFunctionError: Function 'system' is blocked

Explanation: The security validator blocks dangerous functions by default to prevent shell injection and file system abuse.

Solutions:

  1. Use MATLAB-native alternatives instead of blocked functions:

    • Instead of system() or unix(): Use dir(), mkdir(), copyfile(), movefile(), delete() for file ops
    • Instead of eval() or feval(): Use named function calls or str2func()
    • Instead of perl() or python(): Use MATLAB native libraries or file I/O
  2. Remove specific functions from blocklist (for trusted environments):

    security:
      blocked_functions:
        - "eval"
        - "feval"
        # Remove 'system' to allow shell commands
  3. Disable blocklist entirely (not recommended for shared servers):

    security:
      blocked_functions_enabled: false

Job Stuck in "Running" State

Symptom: Job never completes, progress stops updating

Solutions:

  1. Check job status: Ask the agent to call get_job_status with the job ID. Look for state: "running" and check the progress percentage.

  2. Cancel the job:

    # Agent calls this:
    cancel_job(job_id="job_abc123")
  3. Check max execution time: If the job has been running longer than max_execution_time, it will be killed:

    execution:
      max_execution_time: 86400  # 24h hard limit
  4. Check MATLAB code: Is there an infinite loop or blocking operation? Add progress reporting to debug:

    for i = 1:n
        % ... computation ...
        mcp_progress(__mcp_job_id__, i/n*100, sprintf('Iteration %d/%d', i, n));
    end
  5. Check pool health: Call get_pool_status to see if engines are stuck or unhealthy. Restart the server if needed.

Plotly Conversion Failed

Symptom: No interactive plot returned, only text output or static PNG

Explanation: The Plotly converter (mcp_extract_props.m) supports common plot types. Some complex or custom plot types may not convert.

Solutions:

  1. Check supported types:

    • ✅ Supported: line, scatter, bar, area, histogram, surface, image, subplots (subplot/tiledlayout)
    • ❌ Limited: custom graphics objects, 3D surface with complex lighting, contour plots with custom rendering
  2. Simplify the plot: Complex multi-axis plots or heavy use of graphics properties may not convert. Try breaking into simpler subplots.

  3. Static fallback: A PNG image is always generated as fallback, even if Plotly conversion fails. The agent will see both.

  4. Disable Plotly conversion: Fall back to static images only:

    output:
      plotly_conversion: false

    Or:

    export MATLAB_MCP_OUTPUT_PLOTLY_CONVERSION=false
  5. Check logs for conversion errors: Enable debug logging to see why conversion failed:

    export MATLAB_MCP_SERVER_LOG_LEVEL=debug
    # Look for: "Plotly conversion failed"

Large Result Truncated

Symptom: Output is cut off, saved to file, or matrix data is not returned inline

Explanation: Results exceeding max_inline_text_length (text) or large_result_threshold (tabular/matrix data) are saved to file instead of returned inline to keep responses manageable.

Solutions:

  1. Increase limits:

    output:
      max_inline_text_length: 100000  # default: 50000
      large_result_threshold: 50000   # default: 10000

    Or:

    export MATLAB_MCP_OUTPUT_MAX_INLINE_TEXT_LENGTH=100000
    export MATLAB_MCP_OUTPUT_LARGE_RESULT_THRESHOLD=50000
  2. Access the full result: If data is saved to file, the agent gets a message like Result saved to file: results/job_abc123_output.csv. Use:

    # Agent calls:
    read_data(filename="results/job_abc123_output.csv", format="raw")
  3. Use list_files + get_job_result:

    # Agent calls:
    list_files()  # see available files
    get_job_result(job_id="job_abc123")  # get full result metadata with file paths

Connection Refused (SSE)

Symptom: Client can't connect to http://localhost:8765/sse

Solutions:

  1. Check the server is running:

    matlab-mcp --transport sse
    # Should print: "Server running on http://0.0.0.0:8765"
  2. Check port binding: Verify port 8765 is open and no other service is using it:

    # macOS/Linux
    lsof -i :8765
    # Windows
    netstat -ano | findstr :8765

    If in use, change the port in config.yaml:

    server:
      port: 8766
  3. Check host binding: For remote access, use 0.0.0.0:

    server:
      host: "0.0.0.0"  # accessible from anywhere

    For local-only access, use 127.0.0.1:

    server:
      host: "127.0.0.1"
  4. Check firewall: Ensure port 8765 (and 8766 for dashboard) is open:

    # macOS
    sudo lsof -i :8765
    
    # Linux (iptables)
    sudo iptables -A INPUT -p tcp --dport 8765 -j ACCEPT
    
    # Windows Firewall
    netsh advfirewall firewall add rule name="MATLAB MCP" dir=in action=allow protocol=tcp localport=8765
  5. Check logs: Enable debug logging to see connection errors:

    export MATLAB_MCP_SERVER_LOG_LEVEL=debug

"Max engines exceeded" on macOS

Symptom: Warning about max engines, or only 4 engines start

Explanation: MATLAB on macOS has a system-level limit of approximately 4 concurrent engine instances. The server respects this limit by default.

Solution: Configure max_engines: 4 on macOS in config.yaml:

pool:
  max_engines: 4

Or:

export MATLAB_MCP_POOL_MAX_ENGINES=4

The server will not attempt to exceed this limit. If you need more concurrent MATLAB sessions on macOS, consider running multiple server instances or using a Linux/Windows machine.

Session and Workspace Issues

Symptom: Variables from previous calls are not available, or workspace is cleared unexpectedly

Explanation: By default, each job gets a fresh workspace for isolation. To persist variables across calls:

Solutions:

  1. Enable workspace persistence:

    execution:
      workspace_isolation: false
      engine_affinity: true  # pin to same engine
  2. Access workspace between calls: Use get_workspace() to see current variables, or have the agent save/load variables:

    % Save to file
    save('my_vars.mat', 'x', 'y', 'z');
    
    % Load in next call
    load('my_vars.mat');
  3. Add startup commands: Commands in workspace.startup_commands run on engine start and after reset:

    workspace:
      startup_commands:
        - "format long"
        - "addpath('/shared/custom_libs')"

Clone this wiki locally