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 Failed to start MATLAB engine

Solutions:

  1. Verify MATLAB Engine API is installed:

    python -c "import matlab.engine; print('OK')"
  2. Install the Engine API:

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

  4. Check PATH and MATLAB root:

    • MATLAB must be on your system PATH, or
    • Set matlab_root explicitly in config:
    pool:
      matlab_root: "/Applications/MATLAB_R2024a.app"  # macOS
      # matlab_root: "C:\\Program Files\\MATLAB\\R2024a"  # Windows
  5. Increase engine startup timeout: If MATLAB is slow to start:

    pool:
      engine_start_timeout: 300  # 5 minutes
  6. Check system resources: Verify you have sufficient RAM and disk space. MATLAB engines consume significant memory (~500MB–2GB each).

  7. Verify no MATLAB sessions are locked: Kill any existing MATLAB processes and try again:

    # macOS/Linux
    pkill -f matlab
    
    # Windows
    taskkill /IM MATLAB.exe /F

Pool Startup Problems

Symptom: Failed to initialize engine pool or engines repeatedly crash during startup

Solutions:

  1. Check minimum engines configuration:

    pool:
      min_engines: 2     # Start with fewer engines
      max_engines: 4     # Constrain maximum

    If pool initialization fails, reduce min_engines to 1 to identify which engine is failing.

  2. Enable debug logging (see below) to see detailed startup sequence:

    server:
      log_level: "debug"
  3. Check for licensing issues: MATLAB concurrent license server may be unavailable:

    # Test MATLAB directly
    matlab -r "quit"

    If this hangs or fails, contact your MATLAB license administrator.

  4. Platform-specific limits:

    • macOS: Hard limit of 4 concurrent engines. Set:
      pool:
        max_engines: 4
    • Windows/Linux: No hard limit, but available RAM constrains pool size.
  5. Clean up stale processes:

    # List MATLAB processes
    ps aux | grep matlab  # macOS/Linux
    tasklist | findstr matlab  # Windows
    
    # Kill all MATLAB processes
    pkill -9 -f matlab

Timeout Tuning

Symptom: Jobs time out unexpectedly, or fast code is promoted to async too early

Sync vs. Async Timeout

The server runs code synchronously for fast operations. If code exceeds sync_timeout, it's automatically promoted to an async job:

execution:
  sync_timeout: 30  # seconds — increase for slower operations

Solutions:

  1. For operations taking 30–120 seconds:

    execution:
      sync_timeout: 120  # 2 minutes
  2. For long-running jobs (hours): Use async explicitly. The job will run with a hard time limit:

    execution:
      max_execution_time: 86400  # 24 hours
  3. Per-job timeout considerations:

    • Sync operations: Limited by sync_timeout
    • Async operations: Limited by max_execution_time
    • Large file I/O: May need extended sync_timeout
  4. Monitor actual job duration: Use get_job_status to track progress. Jobs in running state will report estimated time remaining.

Logging Configuration

Enable Debug Logging

Via config file:

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

Via environment variable:

export MATLAB_MCP_SERVER_LOG_LEVEL=debug
matlab-mcp

View logs:

tail -f ./logs/server.log

Log Levels

  • debug — Detailed information on pool operations, engine lifecycle, job scheduling
  • info — Standard operational messages (default)
  • warning — Non-critical issues (e.g., slow jobs)
  • error — Failures that impact functionality

What to Look For in Debug Logs

  1. Engine startup:

    [DEBUG] Engine 1: Starting matlab.engine.start_matlab()
    [DEBUG] Engine 1: Connected in 3.2s
    
  2. Job execution:

    [DEBUG] Job abc123: Assigned to Engine 2
    [DEBUG] Job abc123: Sync execution, timeout in 30s
    [DEBUG] Job abc123: Completed in 2.1s
    
  3. Pool scaling:

    [DEBUG] Pool: Utilization 95%, warmup triggered
    [DEBUG] Engine 3: Starting proactive warmup
    
  4. Errors:

    [ERROR] Engine 2: Connection lost
    [DEBUG] Engine 2: Attempting reconnect...
    

Docker Networking

Symptom: Connection refused when accessing SSE endpoint from host or other containers

Solutions:

  1. Check Docker port mapping:

    docker run -p 8765:8765 -p 8766:8766 matlab-mcp
    • 8765 — MCP SSE transport
    • 8766 — Dashboard (monitoring)
  2. Access from host:

    # Inside container, server listens on 0.0.0.0:8765
    # From host, connect to localhost:8765
    curl http://localhost:8765/sse
  3. Access from another container:

    # Use docker-compose networking
    docker-compose up
    
    # Other containers can reach: http://matlab-mcp:8765
  4. Fix binding to 0.0.0.0: Ensure config has:

    server:
      transport: "sse"
      host: "0.0.0.0"      # Listen on all interfaces
      port: 8765
  5. MATLAB path in Docker: Mount your MATLAB installation and set matlab_root:

    docker run -v /opt/matlab:/opt/matlab:ro \
      -e MATLAB_MCP_POOL_MATLAB_ROOT=/opt/matlab \
      -p 8765:8765 matlab-mcp
  6. Check network connectivity:

    # Inside container
    docker exec <container_id> bash
    apt-get update && apt-get install -y curl
    curl http://localhost:8765/sse
  7. View container logs:

    docker logs -f <container_id>

Enable Debug Logging

Quick Start

Single command:

export MATLAB_MCP_SERVER_LOG_LEVEL=debug
matlab-mcp

Or in config.yaml:

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

Interpreted Output

  1. Check for engine failures:

    grep -i "error\|failed\|exception" ./logs/server.log
  2. Trace a specific job:

    grep "job_abc123" ./logs/server.log
  3. Monitor pool health:

    grep "Pool\|Engine" ./logs/server.log | head -50
  4. Find timeout issues:

    grep "timeout\|exceeded" ./logs/server.log

Blocked Function Error

Symptom: BlockedFunctionError: Function 'system' is blocked

Explanation: The security validator blocks dangerous functions by default to prevent shell injection and unauthorized access.

Solutions:

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

    • Shell commands → system() blocked
    • File operations: Use dir, mkdir, copyfile, movefile, delete
    • Environment variables: Use getenv instead of shell access
    • OS operations: Use MATLAB toolbox functions
  2. Disable the blocklist (not recommended for shared servers):

    security:
      blocked_functions_enabled: false
  3. Remove specific functions from blocklist:

    security:
      blocked_functions:
        - "unix"
        - "dos"
        - "!"
        - "eval"
        # "system" removed — now allowed

"Max Engines Exceeded" on macOS

Symptom: Warning about max engines on macOS, or insufficient engines available

Explanation: MATLAB on macOS has a system limit of approximately 4 concurrent engine instances. The server warns but respects your configured max_engines.

Solution: Set max_engines: 4 on macOS:

pool:
  max_engines: 4

Jobs exceeding capacity will queue with a status of pending until an engine becomes available.

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 output:

    MCP Server (SSE) listening on http://0.0.0.0:8765
    
  2. Check port and host:

    • Default is 8765 on all interfaces (0.0.0.0)
    • For remote access, ensure firewall allows port 8765
    • For local-only access, change to 127.0.0.1:
    server:
      host: "127.0.0.1"  # local only
  3. Verify no port conflict:

    # macOS/Linux
    lsof -i :8765
    
    # Windows
    netstat -ano | findstr :8765
  4. Firewall and network:

    • Ensure port 8765 is open in your firewall
    • If behind a proxy, configure the client for proxy authentication:
    security:
      require_proxy_auth: true
  5. Test with curl:

    curl -i http://localhost:8765/sse
    # Should respond with 200 and keep-alive headers

Job Stuck in "Running" State

Symptom: Job never completes, progress stops updating, or MATLAB appears hung

Solutions:

  1. Check job status and progress:

    get_job_status(job_id)  % shows running/pending/completed, + progress %
  2. Cancel the job:

    cancel_job(job_id)  % sends cancel signal to MATLAB
  3. Check max execution time: If a job exceeds this, it's forcefully terminated:

    execution:
      max_execution_time: 86400  # 24 hours
  4. Debug MATLAB code:

    • Is there an infinite loop?
    • Is the code waiting for user input?
    • Add progress reporting to debug:
    for i = 1:n
        % do work
        if mod(i, 100) == 0
            mcp_progress(__mcp_job_id__, i/n*100, sprintf('Iteration %d/%d', i, n));
        end
    end
  5. Check engine health:

    # View pool status
    get_pool_status()

    If an engine is stuck, it will be marked unhealthy and a new one will start.

  6. Increase sync timeout if promoting too early:

    execution:
      sync_timeout: 60  # give longer for sync operations

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 plot types:

    • line, scatter, bar, area
    • histogram, surface, image
    • subplot and tiledlayout layouts
    • Multiple axes with shared/independent scales
  2. Simplify the plot:

    • Complex multi-axis or custom graphics may not convert fully
    • Remove custom renderers or uipanel elements
    • Use standard MATLAB plot functions
  3. Static fallback:

    • A PNG image is always generated even if Plotly conversion fails
    • A thumbnail (400px width) is also created
    • Check list_files for _plot.png and _thumb.png
  4. Disable Plotly conversion: Fall back to static images only:

    output:
      plotly_conversion: false
  5. Adjust static image quality:

    output:
      static_image_format: "png"  # png | jpg | svg
      static_image_dpi: 150       # increase for higher quality
      thumbnail_enabled: true
      thumbnail_max_width: 400

Large Result Truncated

Symptom: Output is cut off or saved to file instead of returned inline

Explanation: Results exceeding max_inline_text_length (50,000 chars) or large_result_threshold (10,000 elements) are automatically saved to file instead of returned inline.

Solutions:

  1. Increase limits:

    output:
      max_inline_text_length: 100000   # chars
      large_result_threshold: 50000    # matrix/table elements
  2. Use file-based retrieval:

    list_files()  % find output files
    read_data("result.csv", "raw")  % read full data
  3. Reduce result size:

    • Summarize large matrices: disp(summary(data))
    • Save only needed columns: disp(data(:, [1 2 5]))
    • Downsample large datasets before display

Server Health and Monitoring

Symptom: Need to check overall server health or debug performance issues

Solutions:

  1. Check server health:

    get_server_health()  % returns: healthy | degraded | unhealthy
  2. View server metrics:

    get_server_metrics()  % pool utilization, jobs, sessions, system load
  3. View recent errors:

    get_error_log(limit=20)  % last 20 errors/events
  4. Check pool status:

    get_pool_status()  % available/busy/max engines
  5. Dashboard (SSE transport only): Open http://localhost:8766 to view real-time metrics and health status.

Clone this wiki locally