Skip to content
github-actions[bot] edited this page Mar 22, 2026 · 20 revisions

FAQ

General / Overview

What is this project?

The MATLAB MCP Server is a Python-based Model Context Protocol (MCP) server that connects AI agents (Claude, Cursor, Copilot, etc.) to MATLAB installations. It enables agents to execute MATLAB code, discover toolboxes, generate interactive plots, manage async jobs, and expose custom functions—all through the MCP protocol.

What MATLAB versions are supported?

MATLAB 2020b and later. The MATLAB Engine API for Python must be installed separately from your MATLAB installation.

What platforms are supported?

  • macOS: Fully supported (Intel and Apple Silicon with known engine pooling limits)
  • Windows: Fully supported (via Python 3.10-3.12)
  • Linux: Supported but less commonly tested
  • Docker: Supported; MATLAB installation must be mounted as a volume

What AI agents work with this?

Any agent supporting the Model Context Protocol (MCP):

  • Claude Desktop
  • Claude Code
  • Cursor (with MCP support)
  • GitHub Copilot (with MCP support)
  • Custom agents built with MCP SDKs

What is the licence?

See the project repository for licence details.

Can I run it without MATLAB installed?

No. The server requires a local MATLAB installation with the Engine API configured. It connects to real MATLAB engines via the matlab.engine Python module.

Can I use MATLAB Online?

Not currently. The server connects to locally-installed MATLAB only.

Where do I install it from?

PyPI: pip install matlab-mcp-python (or matlab-mcp for older versions). See Installation for details.

Setup

How do I install the MATLAB 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 .

Adjust the path for your MATLAB version. See Installation for platform-specific details.

Should I use stdio or SSE transport?

Feature stdio SSE
Users Single Multiple
Setup Simple More complex
Network Local only Remote (with proxy)
Sessions One (default) Per-user
Best for Local development, testing Shared servers, CI/CD

Default: stdio. Change in config.yaml under server.transport.

See Configuration for full details.

Can I run the server remotely?

Yes, with SSE transport. Start the server on a remote machine (or in Docker) and connect via HTTP. Always put it behind an authenticating reverse proxy for production. Set require_proxy_auth: true in config.

graph LR
    A["Agent 1<br/>(Claude)"]
    B["Agent 2<br/>(Cursor)"]
    P["Reverse Proxy<br/>(nginx + auth)"]
    S["MATLAB MCP<br/>Server<br/>(SSE)"]
    M["MATLAB<br/>Engines"]
    
    A -->|HTTP| P
    B -->|HTTP| P
    P -->|Trusted<br/>localhost| S
    S -->|Engine API| M
Loading

How do I configure the server?

See Configuration. The server reads config.yaml by default. You can also override settings with environment variables prefixed with MATLAB_MCP_, e.g.:

export MATLAB_MCP_POOL_MIN_ENGINES=2
export MATLAB_MCP_POOL_MAX_ENGINES=8
matlab-mcp-server

How do I install it in Docker?

docker-compose up -d

The docker-compose.yml mounts your MATLAB installation. See Installation for volume mounting details.

How do I use it with Claude Desktop?

Create/edit ~/.config/claude.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "matlab": {
      "command": "matlab-mcp-server",
      "args": ["--transport", "stdio"]
    }
  }
}

Restart Claude Desktop. See Installation for other agents.

Performance

How many engines should I run?

Personal use        → 1–2 engines
Small team (2–5)    → 2–4 engines
Larger team         → Scale based on concurrent users
macOS limit         → ~4 engines (platform limitation)

Each engine consumes ~500MB–2GB of memory depending on loaded toolboxes.

How do I tune pool scaling?

Edit config.yaml:

pool:
  min_engines: 1                    # Always keep 1 warm
  max_engines: 8                    # Scale up to 8 under load
  proactive_warmup_threshold: 0.8   # Start new engine at 80% utilization
  scale_down_idle_timeout: 900      # Stop idle engines after 15 min
  health_check_interval: 30         # Check engine health every 30s

See Configuration for all tuning options.

What happens when all engines are busy?

Requests queue (FIFO). If the pool hasn't reached max_engines, a new engine starts automatically. Requests wait in queue with a configurable queue_max_size (default 50).

How do I reduce memory usage?

  • Lower min_engines and max_engines
  • Reduce max_sessions (SSE only)
  • Use workspace_isolation: false to skip full clear all between sessions (less safe)
  • Disable toolboxes you don't need via toolboxes.mode: include + whitelist

How do I improve execution speed?

  • Increase min_engines to avoid startup latency
  • Lower sync_timeout if you're OK with more async jobs
  • Disable code checking: execution.check_code_before_run: false (less safe)
  • Increase startup_commands time allowance if MATLAB takes time to load

Integration

How does async execution work?

Code completing within sync_timeout (default 30s) returns immediately. Longer code is auto-promoted to async:

sequenceDiagram
    Agent->>Server: execute_code("long_task()")
    Server->>MATLAB: eval(background=True)
    par Wait for result
        Server->>Server: Monitor for 30s
    and
        MATLAB->>MATLAB: Run long_task()
    end
    Note over Server: 30s timeout → async
    Server->>Agent: {status: "running", job_id: "abc123"}
    Agent->>Server: get_job_status("abc123")
    Server->>Agent: {status: "running", progress: 45%}
    Agent->>Server: get_job_result("abc123")
    Server->>Agent: {status: "completed", output: "..."}
Loading

See Async Jobs for details on mcp_progress() and job management tools.

How do I report progress from long jobs?

Use the mcp_progress() helper injected into the workspace:

for i = 1:1000000
    do_work(i);
    if mod(i, 100000) == 0
        mcp_progress(__mcp_job_id__, i/1000000 * 100, sprintf('Trial %d/1000000', i));
    end
end

The agent polls get_job_status() to see the progress message and percentage.

Can I use custom MATLAB functions as tools?

Yes. Define them in custom_tools.yaml:

tools:
  - name: analyze_signal
    function: signal.analysis.fft_peaks
    description: Find dominant frequencies in a signal
    parameters:
      signal:
        type: array
        description: Input signal vector
      n_peaks:
        type: int
        default: 5
        description: Number of peaks to return

See Custom Tools for full YAML format and type system.

How do I integrate with CI/CD?

Use the server in SSE mode:

  1. Start the server as a background service
  2. Point your CI/CD pipeline to the HTTP endpoint
  3. Submit jobs and poll for results

Example (pseudo-code):

import requests

response = requests.post(
    "http://localhost:8765/rpc",
    json={"jsonrpc": "2.0", "method": "execute_code", "params": {"code": "test"}}
)
job_id = response.json()["result"]["job_id"]

# Poll until done
while True:
    status = requests.post(
        "http://localhost:8765/rpc",
        json={"jsonrpc": "2.0", "method": "get_job_status", "params": {"job_id": job_id}}
    )
    if status.json()["result"]["status"] == "completed":
        break
    time.sleep(1)

Can I use it with a CI/CD system like GitHub Actions?

Yes. Run the server in a Docker container with MATLAB mounted, then submit jobs via HTTP (SSE) or pipe commands via stdin (stdio). See Installation for Docker setup.

What frameworks are compatible?

The server is framework-agnostic. It works with any tool that can speak MCP:

  • Claude SDK (Python, TypeScript)
  • Cursor (IDE integration)
  • LangChain (with MCP adapter)
  • Custom applications (via MCP client libraries)

How do I handle large data transfers?

  • Upload files: Use upload_data tool (base64-encoded, max size configurable, default 100MB)
  • Download results: Use read_data or read_image tools to retrieve results
  • Avoid inline: Don't try to return multi-GB results inline; save to disk and read back
% Instead of returning huge matrix:
large_result = randn(100000, 100000);
save(fullfile(__mcp_temp_dir__, 'result.mat'), 'large_result');
disp('Saved to result.mat');

% Agent then calls:
% read_data('result.mat', 'raw')

Can I call the server from Python code?

Yes, via the MCP client libraries:

from mcp_client import MCPClient

async with MCPClient("stdio", "matlab-mcp-server") as client:
    result = await client.call_tool("execute_code", code="x = 1:10; plot(x, x.^2)")
    print(result)

Security

Is it safe to expose over the network?

For stdio: Local only, no network risk.

For SSE: Always use an authenticating reverse proxy:

  • Put nginx/Apache in front with basic auth, OAuth, SAML, etc.
  • Set require_proxy_auth: true in config
  • Bind to 127.0.0.1 if the proxy is on the same host
  • Use HTTPS/TLS in production
# Example nginx proxy
location / {
    auth_basic "MATLAB MCP";
    auth_basic_user_file /etc/nginx/htpasswd;
    proxy_pass http://localhost:8765;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Can agents run arbitrary system commands?

No. The default blocklist prevents:

  • system(), unix(), dos()
  • ! shell escape
  • eval(), feval(), evalc(), evalin(), assignin()
  • perl(), python()

You can customize the blocklist in config.yaml:

security:
  blocked_functions_enabled: true
  blocked_functions:
    - system
    - eval
    - my_dangerous_function

See Security for details.

Are user sessions isolated?

Yes. When workspace_isolation: true (default in SSE):

clear all
clear global
clear functions
fclose all
restoredefaultpath

This is run between sessions (but not between jobs in the same session). Each session gets its own temp directory.

How do I limit upload sizes?

security:
  max_upload_size_mb: 100  # Default; set lower if needed

How do I prevent accidental workspace pollution?

Enable workspace_isolation and set an appropriate session_timeout:

sessions:
  session_timeout: 3600  # 1 hour
workspace:
  isolation: true

Each session starts fresh after the timeout.

Troubleshooting

The server won't start

  1. Verify MATLAB Engine API is installed: python -c "import matlab.engine; print('OK')"
  2. Check logs: cat logs/server.log (path from config)
  3. Ensure config.yaml is valid YAML
  4. Check environment variable overrides: echo $MATLAB_MCP_*

MATLAB engines die randomly

  • macOS: You're hitting the ~4-engine limit. Set max_engines: 4
  • Memory: Each engine uses ~500MB–2GB. Check ps aux | grep MATLAB
  • License: Verify you have enough MATLAB licenses for your pool size
  • Health checks failing: Increase health_check_interval (default 30s) to reduce noise

Jobs are getting stuck

  • Increase sync_timeout if jobs are auto-promoting unexpectedly
  • Check get_job_status() for detailed state
  • Use cancel_job() to forcefully stop stuck jobs
  • Review MATLAB output for infinite loops or deadlocks

Plots aren't converting to Plotly

Supported types: line, scatter, bar, histogram, surface, image. Custom graphics may fall back to static PNG. Check config:

output:
  convert_figures_to_plotly: true
  save_plot_png: true

"Blocked function" error when I need to use system()

Temporarily disable blocking (dev/testing only):

security:
  blocked_functions_enabled: false

Or whitelist specific functions by removing them from the blocklist.

Large results are truncated

Adjust output length limits in config.yaml:

output:
  max_text_length: 10000  # Increase from default 1000
  save_truncated_results: true
  result_dir: /path/to/results

SSE connection drops

  • Check reverse proxy logs
  • Verify require_proxy_auth is set if using auth
  • Increase queue_timeout in config if requests take long
  • Use --transport sse --host 0.0.0.0 --port 8765 for explicit binding

Development

How do I run tests?

pip install -e ".[dev]"
pytest tests/ -v

Tests use a mock MATLAB engine—no MATLAB installation needed.

How do I add a new tool?

  1. Implement in src/matlab_mcp/tools/
  2. Register in server.py with @mcp.tool
  3. Add tests in tests/test_tools_*.py

See the existing tools for structure.

How do I contribute?

Open an issue or PR on GitHub. Contributions welcome!

Where's the architecture documented?

See Architecture for system diagrams, component details, and data flow.

Clone this wiki locally