AgentStack
MCP unreviewed MIT Self-run

Matlab Mcp Server Python

mcp-hansur94-matlab-mcp-server-python · by HanSur94

MCP server that connects any AI agent to MATLAB — execute code, async jobs, interactive Plotly plots, custom tools, and monitoring dashboard

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add mcp-hansur94-matlab-mcp-server-python

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution Used

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Matlab Mcp Server Python? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

MATLAB MCP Server

Give any AI agent the power of MATLAB — via the Model Context Protocol

Quick Start • Examples • Tools Reference • Configuration • Wiki


A Python MCP server that connects any AI agent (Claude, Cursor, Copilot, custom agents) to a shared MATLAB installation. Execute code, discover toolboxes, check code quality, get interactive Plotly plots, and run long simulations — all through MCP.

Why?

  • Your AI agent can now write and run MATLAB code directly
  • Long-running jobs (hours!) run async — the agent keeps working while MATLAB computes
  • Multiple users share one MATLAB server via an elastic engine pool
  • Interactive plots come back as Plotly JSON — renderable in any web UI
  • Custom MATLAB libraries become first-class AI tools with zero code changes

Features

| Feature | Description | |---------|-------------| | Execute MATLAB code | Sync for fast commands, auto-async for long jobs | | Elastic engine pool | Scales 2-10+ engines based on demand | | Toolbox discovery | Browse installed toolboxes, functions, help text | | Code checker | Run checkcode/mlint before execution | | Interactive plots | Figures auto-converted to Plotly JSON | | Multi-user (SSE) | Session isolation with per-user workspaces | | Custom tools | Expose your .m functions as MCP tools via YAML | | Progress reporting | Long jobs report percentage back to the agent | | Cross-platform | Windows + macOS, MATLAB R2022b+ | | One-click Windows install | Offline install.bat — no admin rights needed |

MATLAB Plot Conversion to Interactive Plotly

Every MATLAB figure is automatically converted into an interactive Plotly chart — no extra code needed. When your MATLAB code creates a plot, the server:

  1. Extracts figure properties via mcp_extract_props.m — axes, line data, labels, colors, markers, legends, subplots
  2. Maps MATLAB styles to Plotly — line styles (--dash), markers (ocircle), legend positions, axis scales, colormaps
  3. Returns interactive JSON — renderable in any web UI with Plotly.newPlot()
  4. Generates a static PNG + thumbnail as fallback for non-interactive clients

Supported plot types: line, scatter, bar, area, subplots (subplot/tiledlayout), multiple axes, log/linear scales

Style fidelity: Line styles, marker shapes, colors (RGB), line widths, font sizes, axis labels, titles, legends, grid lines, axis limits, and background colors are all preserved.

% This MATLAB code...
x = linspace(0, 2*pi, 200);
plot(x, sin(x), 'r-', 'LineWidth', 2); hold on;
plot(x, cos(x), 'b--', 'LineWidth', 2);
plot(x, sin(x) .* cos(x), 'g-.', 'LineWidth', 2);
legend('sin(x)', 'cos(x)', 'sin(x)*cos(x)');
xlabel('x'); ylabel('y');
title('Trigonometric Functions');

...automatically becomes this interactive Plotly chart:

Line styles, colors, markers, legends, and axis labels are all preserved in the conversion.

Quick Start

Prerequisites

# Install MATLAB Engine API (from your MATLAB installation)
cd /Applications/MATLAB_R2024a.app/extern/engines/python  # macOS
# cd "C:\Program Files\MATLAB\R2024a\extern\engines\python"  # Windows
pip install .

Install the server

Windows (one-click, no admin needed):

git clone https://github.com/HanSur94/matlab-mcp-server-python.git
cd matlab-mcp-server-python
install.bat

The installer auto-detects MATLAB, creates a virtual environment, and installs everything from bundled wheels — fully offline, no internet required. Works on Windows 10/11 with Python 3.10, 3.11, or 3.12.

macOS / Linux:

# Option 1: Install from PyPI
pip install matlab-mcp-python

# Option 2: Install from source
git clone https://github.com/HanSur94/matlab-mcp-server-python.git
cd matlab-mcp-server-python
pip install -e ".[dev]"

Run it

# Single user (stdio) — simplest setup
matlab-mcp

# Multi-user (SSE) — shared server
matlab-mcp --transport sse

Connect to Claude Desktop

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "matlab": {
      "command": "matlab-mcp"
    }
  }
}

Connect to Claude Code

claude mcp add matlab -- matlab-mcp

Connect to Cursor

Add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "matlab": {
      "command": "matlab-mcp"
    }
  }
}

Run with Docker

# Build the image
docker build -t matlab-mcp .

# Run with your MATLAB mounted
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

# Or use docker-compose (edit docker-compose.yml to set your MATLAB path)
docker compose up

> Note: The Docker image does not include MATLAB. You must mount your own MATLAB installation.

> Upgrading? If you previously installed as matlab-mcp-server, uninstall first: pip uninstall matlab-mcp-server && pip install matlab-mcp-python

Examples

Basic: Run MATLAB Code

Ask your AI agent:

> "Calculate the eigenvalues of a 3x3 magic square in MATLAB"

The agent calls execute_code:

A = magic(3);
eigenvalues = eig(A);
disp(eigenvalues)

Result returned inline:

15.0000
 4.8990
-4.8990

Signal Processing

> "Generate a 1kHz sine wave, add noise, then filter it with a low-pass Butterworth filter and plot both"

fs = 8000;
t = 0:1/fs:0.1;
clean = sin(2*pi*1000*t);
noisy = clean + 0.5*randn(size(t));

[b, a] = butter(6, 1500/(fs/2));
filtered = filter(b, a, noisy);

subplot(2,1,1); plot(t, noisy); title('Noisy Signal');
subplot(2,1,2); plot(t, filtered); title('Filtered Signal');

Returns: Interactive Plotly chart + static PNG + thumbnail.

Long-Running Simulation (Async)

> "Run a Monte Carlo simulation with 1 million trials"

n = 1e6;
results = zeros(n, 1);
for i = 1:n
    results(i) = simulate_trial();  % your custom function
    if mod(i, 1e5) == 0
        mcp_progress(__mcp_job_id__, i/n*100, sprintf('Trial %d/%d', i, n));
    end
end
disp(mean(results));

The agent gets a job ID immediately, polls progress ("Trial 500000/1000000 — 50%"), and retrieves results when done.

Custom Tools

Expose your proprietary MATLAB functions as first-class AI tools. Create custom_tools.yaml:

tools:
  - name: analyze_signal
    matlab_function: mylib.analyze_signal
    description: "Analyze a signal and return frequency components, SNR, and peak detection"
    parameters:
      - name: signal_path
        type: string
        required: true
      - name: sample_rate
        type: float
        required: true
      - name: window_size
        type: int
        default: 1024
    returns: "Struct with fields: frequencies, magnitudes, snr, peaks"

  - name: train_model
    matlab_function: ml.train_classifier
    description: "Train a classification model on the given dataset"
    parameters:
      - name: dataset_path
        type: string
        required: true
      - name: model_type
        type: string
        default: "svm"
    returns: "Trained model object saved to workspace"

Now the agent can call analyze_signal or train_model directly — with full parameter validation and help text.

MCP Tools Reference

Code Execution

| Tool | Parameters | Description | |------|-----------|-------------| | execute_code | code: str | Run MATLAB code. Returns inline if fast ( Server — transport, host, port, logging

server:
  name: "matlab-mcp-server"
  transport: "stdio"        # stdio | sse
  host: "0.0.0.0"           # SSE only
  port: 8765                # SSE only
  log_level: "info"         # debug | info | warning | error
  log_file: "./logs/server.log"
  result_dir: "./results"
  drain_timeout_seconds: 300

Pool — engine count, scaling, health checks

pool:
  min_engines: 2            # always warm
  max_engines: 10           # hard ceiling
  scale_down_idle_timeout: 900   # 15 min
  engine_start_timeout: 120
  health_check_interval: 60
  proactive_warmup_threshold: 0.8
  queue_max_size: 50
  matlab_root: null         # auto-detect

Execution — timeouts, workspace isolation

execution:
  sync_timeout: 30          # seconds before async promotion
  max_execution_time: 86400 # 24h hard limit
  workspace_isolation: true
  engine_affinity: false    # pin session to engine
  temp_dir: "./temp"
  temp_cleanup_on_disconnect: true

Security — function blocklist, upload limits

security:
  blocked_functions_enabled: true
  blocked_functions:
    - "system"
    - "unix"
    - "dos"
    - "!"
    - "eval"
    - "feval"
    - "evalc"
    - "evalin"
    - "assignin"
    - "perl"
    - "python"
  max_upload_size_mb: 100
  require_proxy_auth: false

Toolboxes — whitelist/blacklist exposure

toolboxes:
  mode: "whitelist"         # whitelist | blacklist | all
  list:
    - "Signal Processing Toolbox"
    - "Optimization Toolbox"
    - "Statistics and Machine Learning Toolbox"
    - "Image Processing Toolbox"

Output — Plotly, images, thumbnails

output:
  plotly_conversion: true
  static_image_format: "png"
  static_image_dpi: 150
  thumbnail_enabled: true
  thumbnail_max_width: 400
  large_result_threshold: 10000
  max_inline_text_length: 50000

Monitoring

Built-in observability with a web dashboard, JSON health/metrics endpoints, and MCP tools for AI agent self-monitoring.

Dashboard

Access at http://localhost:8766/dashboard (stdio) or http://localhost:8765/dashboard (SSE).

Features:

  • 7 live gauges: pool utilization, engines (busy/total), active jobs, completed jobs, active sessions, avg execution time, errors/min
  • 6 time-series charts (Plotly.js): pool utilization, job throughput, execution time (avg + p95), active sessions, memory usage, error count
  • MATLAB execution log: filterable table showing time, event type, MATLAB code, output, and duration for every job
  • Time range selector: 1h, 6h, 24h, 7d views
  • Auto-refreshes every 10 seconds

Health Endpoint

curl http://localhost:8766/health
{
  "status": "healthy",
  "uptime_seconds": 3600.1,
  "issues": [],
  "engines": {"total": 2, "available": 1, "busy": 1},
  "active_jobs": 1,
  "active_sessions": 3
}

Status codes: 200 for healthy/degraded, 503 for unhealthy.

Health evaluation rules:

| Status | Condition | |--------|-----------| | unhealthy | No engines running (total == 0) | | unhealthy | All engines busy at max capacity (available == 0 && total >= max_engines) | | degraded | Pool utilization > 90% | | degraded | Health check failures detected | | degraded | Error rate > 5/min | | healthy | None of the above |

Metrics Endpoint

curl http://localhost:8766/metrics
{
  "timestamp": "2026-03-12T23:01:56.799Z",
  "pool": {"total": 2, "available": 1, "busy": 1, "max": 10, "utilization_pct": 50.0},
  "jobs": {"active": 1, "completed_total": 47, "failed_total": 2, "cancelled_total": 0, "avg_execution_ms": 28.5},
  "sessions": {"total_created": 5, "active": 3},
  "errors": {"total": 2, "blocked_attempts": 0, "health_check_failures": 0},
  "system": {"uptime_seconds": 3600.1, "memory_mb": 108.8, "cpu_percent": 12.3}
}

Dashboard API

| Endpoint | Parameters | Description | |----------|-----------|-------------| | GET /health | — | Health status + issues | | GET /metrics | — | Live metrics snapshot (no DB hit) | | GET /dashboard | — | Web dashboard HTML | | GET /dashboard/api/current | — | Same as /metrics | | GET /dashboard/api/history | metric, hours | Time-series data from SQLite | | GET /dashboard/api/events | limit, type | Event log with MATLAB output |

Available history metrics: pool.utilization_pct, pool.total_engines, pool.busy_engines, jobs.completed_total, jobs.failed_total, jobs.avg_execution_ms, jobs.p95_execution_ms, sessions.active_count, system.memory_mb, system.cpu_percent, errors.total

Backend Architecture

                    ┌─────────────────────────────────────────────┐
                    │           MetricsCollector                   │
                    │                                             │
                    │  In-memory:                                 │
  record_event() ──│─▶ _counters (7 counters)                    │
  (sync, from any  │   _execution_times (ring buffer, maxlen=100)│
   component)      │                                             │
                    │  Background task (every 10s):               │
                    │   sample_once() ─▶ MetricsStore.insert()   │
                    │                                             │
                    │  Live snapshot (no DB):                     │
                    │   get_current_snapshot() ─▶ /metrics        │
                    └───────────┬─────────────────────────────────┘
                                │
                    ┌───────────▼─────────────────────────────────┐
                    │           MetricsStore (aiosqlite)           │
                    │                                             │
                    │  metrics table:                             │
                    │   id | timestamp | category | metric | value│
                    │   (4 indexes for fast queries)              │
                    │                                             │
                    │  events table:                              │
                    │   id | timestamp | event_type | details     │
                    │   (details = JSON with code, output, etc.)  │
                    │                                             │
                    │  Methods:                                   │
                    │   insert_metrics(), insert_event()          │
                    │   get_latest(), get_history(), get_events() │
                    │   get_aggregates(), prune()                 │
                    │                                             │
                    │  SQLite WAL mode, log-and-swallow errors    │
                    └───────────┬─────────────────────────────────┘
                                │
                    ┌───────────▼─────────────────────────────────┐
                    │     Starlette Dashboard App                  │
                    │                                             │
                    │  /health ─▶ evaluate_health(collector)      │
                    │  /metrics ─▶ collector.get_current_snapshot()│
                    │  /dashboard ─▶ cached index.html            │
                    │  /dashboard/api/* ─▶ store queries          │
                    │  /dashboard/static/* ─▶ JS, CSS, Plotly.js  │
                    └─────────────────────────────────────────────┘

Event Types

Events are recorded synchronously via collector.record_event() from any server component. Each event includes a JSON details field.

| Event Type | Source | Details Fields | |------------|--------|---------------| | job_completed | Executor | job_id, execution_ms, code, output | | job_failed | Executor | job_id, code, error | | session_created | SessionManager | session_id_short | | engine_scale_up | PoolManager | engine_id, total_after | | engine_scale_down | PoolManager | engine_id, total_after | | engine_replaced | PoolManager | old_id, new_id | | health_check_fail | PoolManager | engine_id, error | | blocked_function | SecurityValidator | function, code_snippet |

###

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.