Skip to content

Troubleshooting

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

Troubleshooting

MATLAB Engine Won't Start

Symptom: Engine start timeout or matlab.engine not found

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"

    Or via environment variable:

    export MATLAB_MCP_POOL_MATLAB_ROOT="/Applications/MATLAB_R2024a.app"
  5. Increase timeout: If MATLAB is slow to start:

    pool:
      engine_start_timeout: 300  # 5 minutes

    Or:

    export MATLAB_MCP_POOL_ENGINE_START_TIMEOUT=300
  6. Check engine pool health: Use get_pool_status tool to verify pool is running:

    % In your MCP client
    get_pool_status()

Pool Startup Problems

Symptom: min_engines not reaching desired count, or all engines fail to start

Solutions:

  1. Verify minimum configuration:

    pool:
      min_engines: 2
      max_engines: 10

    The server attempts to warm min_engines on startup. Check logs for failures.

  2. Check logs for startup errors:

    export MATLAB_MCP_SERVER_LOG_LEVEL=debug
    matlab-mcp 2>&1 | tee startup.log

    Look for Engine startup failed messages and the underlying error.

  3. Verify MATLAB installation integrity:

    matlab -r "quit"  # Can MATLAB start at all?
  4. On macOS, verify engine limit: MATLAB on macOS has a hard limit of ~4 concurrent engines. The server caps max_engines at 4 on macOS automatically, but if you override it, engines beyond 4 will fail:

    pool:
      max_engines: 4  # recommended on macOS
  5. Check queue isn't full: If queue_max_size is exceeded, new requests are rejected:

    pool:
      queue_max_size: 50

MATLAB Engine Connection Failures

Symptom: ConnectionError, OSError, or matlab.engine.EngineError during execution

Solutions:

  1. Engine crashed or disconnected: Check server logs for crash indicators:

    tail -f logs/server.log | grep -i "engine\|crash\|error"
  2. Workspace corruption: If engine_affinity is enabled and workspace isolation fails, reset the workspace:

    execution:
      workspace_isolation: true
      engine_affinity: false  # disable affinity if seeing persistent errors
  3. Too many engines for system resources: Reduce max_engines if you see memory/resource exhaustion:

    pool:
      max_engines: 4
  4. Network issue (SSE transport only): Verify host and port are correct and reachable:

    curl http://localhost:8765/health

Timeout Tuning

Symptom: Jobs timeout unexpectedly, or jobs run synchronously when they should be async

Tuning Guide:

  1. Sync vs Async Promotion: By default, fast jobs (<30s) return inline. Slower jobs get a job ID and run async:

    execution:
      sync_timeout: 30  # seconds

    To make promotions more aggressive:

    export MATLAB_MCP_EXECUTION_SYNC_TIMEOUT=10
  2. Hard execution limit per job:

    execution:
      max_execution_time: 86400  # 24h hard limit

    Jobs exceeding this are forcibly cancelled.

  3. Engine startup timeout:

    pool:
      engine_start_timeout: 120  # 2 minutes

    If engines take longer to start, increase this.

  4. Session timeout (inactivity):

    sessions:
      session_timeout: 3600  # 1 hour

    Sessions are cleaned up after this much inactivity.

  5. Scale-down idle timeout:

    pool:
      scale_down_idle_timeout: 900  # 15 minutes

    Idle engines above min_engines are shut down after this duration.

  6. Server shutdown drain timeout:

    server:
      drain_timeout_seconds: 300  # 5 minutes

    Max wait for running jobs to complete during graceful shutdown.

Logging Configuration

Enable Debug Logging:

  1. Via config file:

    server:
      log_level: "debug"
      log_file: "./logs/server.log"
  2. Via environment variable:

    export MATLAB_MCP_SERVER_LOG_LEVEL=debug
    matlab-mcp
  3. View logs in real-time:

    tail -f logs/server.log
  4. Log levels: debug | info | warning | error

    • debug: Detailed execution trace, all API calls, pool state changes
    • info: Server startup, job status, pool scaling events
    • warning: Non-fatal issues, timeouts, recovery attempts
    • error: Failures, exceptions, crash details
  5. Error log tool: Use get_error_log tool to retrieve recent errors programmatically:

    get_error_log(limit=50)  % last 50 errors

Docker Networking

Symptom: Client can't connect to server in Docker, or server can't find MATLAB

Solutions:

  1. Mount MATLAB correctly:

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

    Verify the host path exists and contains MATLAB binaries.

  2. Expose ports: For SSE transport, ensure both ports are exposed:

    -p 8765:8765  # SSE endpoint
    -p 8766:8766  # dashboard/health endpoint
  3. Host binding: By default, the server binds to 0.0.0.0 (all interfaces) inside the container. To restrict:

    server:
      host: "127.0.0.1"  # localhost only
  4. Network mode: For local access to other services, use host network (Linux only):

    docker run --network host \
      -v /path/to/MATLAB:/opt/matlab:ro \
      matlab-mcp --transport sse
  5. Check container logs:

    docker logs <container_id>
  6. Verify MATLAB in container:

    docker exec <container_id> /opt/matlab/bin/matlab -r "quit"
  7. Use docker-compose: Edit docker-compose.yml to set your MATLAB path:

    services:
      matlab-mcp:
        build: .
        ports:
          - "8765:8765"
          - "8766:8766"
        volumes:
          - /path/to/MATLAB:/opt/matlab:ro
        environment:
          MATLAB_MCP_POOL_MATLAB_ROOT: /opt/matlab

"Max engines exceeded" on macOS

Symptom: Warning about max engines on macOS

Explanation: MATLAB on macOS has a hard limit of ~4 concurrent engine instances. The server automatically caps max_engines at 4 on macOS, but warns if you try to override it.

Solution: Accept the macOS limit:

pool:
  max_engines: 4

Or verify your macOS version supports more (newer versions may allow more).

Connection Refused (SSE)

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

Solutions:

  1. Check the server is running:

    matlab-mcp --transport sse
  2. Check port: Default is 8765. Verify in config or change:

    server:
      port: 8765

    Or:

    export MATLAB_MCP_SERVER_PORT=8765
  3. Check host binding:

    server:
      host: "0.0.0.0"  # all interfaces

    Use 127.0.0.1 for local-only access, 0.0.0.0 for remote.

  4. Firewall: Ensure port 8765 (and 8766 for dashboard) is open:

    netstat -an | grep 8765
  5. Verify server is healthy:

    curl http://localhost:8765/health

Blocked Function Error

Symptom: BlockedFunctionError: Function 'system' is blocked

Explanation: The security validator blocks dangerous functions by default to prevent code injection and system compromise.

Solutions:

  1. Use MATLAB-native alternatives instead of system():

    • File operations: dir, mkdir, copyfile, movefile, fileattrib
    • Environment: getenv, setenv
    • Shell commands: use MATLAB equivalents (e.g., pwd, cd)
  2. Disable blocklist (only for trusted/isolated servers):

    security:
      blocked_functions_enabled: false

    Or:

    export MATLAB_MCP_SECURITY_BLOCKED_FUNCTIONS_ENABLED=false
  3. Remove specific functions from blocklist:

    security:
      blocked_functions:
        - "unix"
        - "dos"
        - "!"
        - "eval"
        # "system" removed
  4. Default blocklist includes: system, unix, dos, !, eval, feval, evalc, evalin, assignin, perl, python

Job Stuck in "Running" State

Symptom: Job never completes, progress stops updating

Solutions:

  1. Cancel the job: Use cancel_job tool:

    cancel_job(job_id="abc123")
  2. Check max execution time:

    execution:
      max_execution_time: 86400  # 24h hard limit

    Jobs exceeding this are forcibly cancelled.

  3. Monitor job status:

    get_job_status(job_id="abc123")

    Returns current status and progress percentage.

  4. Check MATLAB code: Is there an infinite loop? Add progress reporting to debug:

    for i = 1:n
        mcp_progress(__mcp_job_id__, i/n*100, sprintf('Iteration %d', i));
        % ... work ...
    end
  5. Check engine health:

    get_pool_status()

    Verify the engine running this job is healthy.

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. Complex, custom, or unsupported plot types may not convert, but a static PNG fallback is always generated.

Solutions:

  1. Check supported types:

    • Line, scatter, bar, histogram, surface, contour, image
    • Multi-axis plots with proper labeling
    • Standard MATLAB plot functions (plot, scatter, bar, surf, etc.)
  2. Simplify the plot: Complex multi-axis layouts, custom graphics objects, or specialized toolbox plots may not convert. Simplify if possible.

  3. Static fallback: A PNG image is always generated even if Plotly conversion fails. Check the result for the static image.

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

    output:
      plotly_conversion: false

    Or:

    export MATLAB_MCP_OUTPUT_PLOTLY_CONVERSION=false
  5. Check image format:

    output:
      static_image_format: "png"  # png | jpg | svg
      static_image_dpi: 150

Large Result Truncated

Symptom: Output is cut off, saved to file, or missing from result

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

Solutions:

  1. Increase limits:

    output:
      max_inline_text_length: 100000
      large_result_threshold: 50000

    Or:

    export MATLAB_MCP_OUTPUT_MAX_INLINE_TEXT_LENGTH=100000
    export MATLAB_MCP_OUTPUT_LARGE_RESULT_THRESHOLD=50000
  2. Use file-based access:

    get_job_result(job_id="abc123")  % retrieves saved file reference
    list_files()                       # see all output files
    read_data(filename="result.mat")   # read file contents
  3. Summarize results before returning: In your MATLAB code, use summary() or height()/size() to get statistics instead of full data.

Workspace Isolation Issues

Symptom: Variables leak between jobs, or workspace not reset

Solutions:

  1. Verify workspace isolation is enabled:

    execution:
      workspace_isolation: true
  2. Disable engine affinity if seeing issues: Engine affinity pins sessions to engines for persistence, but can cause workspace corruption:

    execution:
      engine_affinity: false  # recommended
  3. Check startup commands: These run on every engine start and workspace reset:

    workspace:
      startup_commands:
        - "format long"
        - "addpath('/shared/libs')"
  4. Verify custom paths are added:

    workspace:
      default_paths:
        - "/shared/custom_libs"
        - "/shared/data"

    These are added to MATLAB path on engine start.

Code Quality Checks Disabled

Symptom: check_code tool returns no warnings, or code issues not caught

Solutions:

  1. Verify code checker is enabled:

    code_checker:
      enabled: true
      auto_check_before_execute: false  # manual only by default
  2. Enable auto-check before execution:

    code_checker:
      auto_check_before_execute: true
  3. Configure severity levels:

    code_checker:
      severity_levels: ["error", "warning"]
  4. Manually check code:

    check_code(code="x = 1\ny = x+1")

Monitoring and Health

Symptom: Dashboard not accessible, or health status unclear

Solutions:

  1. Verify monitoring is enabled:

    monitoring:
      enabled: true
      dashboard_enabled: true
      http_port: 8766
  2. Access dashboard:

    • Stdio transport: http://localhost:8766/dashboard
    • SSE transport: http://localhost:8765/dashboard
  3. Check health endpoint:

    curl http://localhost:8766/health  # stdio
    curl http://localhost:8765/health  # sse
  4. Use health tool:

    get_server_health()
    get_server_metrics()
  5. Check retention and database:

    monitoring:
      sample_interval: 10      # seconds
      retention_days: 7        # historical data retention
      db_path: "./monitoring/metrics.db"

Clone this wiki locally