MATLAB MCP Server
Give any AI agent the power of MATLAB — via the Model Context Protocol
Quick Start • Examples • Tools Reference • Configuration • Wiki
______________________________________________________________________
连接的Python MCP服务器 任何AI代理 (Claude、Cursor、Copilot、自定义代理)共享MATLAB安装。执行代码,发现工具箱,检查代码质量,获取交互式Plotly图,并运行长时间模拟——全部完成 主控程序.
为什么?
- 您的AI代理现在可以 编写并运行MATLAB代码 直接
- 长期运行的作业 (小时!)异步运行——代理在MATLAB计算时继续工作
- 多个用户 通过弹性引擎池共享一个MATLAB服务器
- 交互式绘图 以Plotly JSON格式返回——可在任何web UI中渲染
- 自定义MATLAB库 成为一流的人工智能工具,零代码更改
特性
| 特性 | 描述 |
|---|---|
| 执行MATLAB代码 | 同步快速命令,自动异步长任务 |
| 弹性引擎池 | 根据需求扩展2-10+个引擎 |
| 工具箱发现 | 浏览已安装的工具箱、函数、帮助文本 |
| 代码检查器 | 运行 checkcode/mlint 执行前 |
| 交互式绘图 | 图形自动转换为Plotly JSON |
| 多用户(SSE) | 具有每个用户工作区的会话隔离 |
| 自定义工具 | 展示您的 .m 通过YAML充当MCP工具 |
| 进度报告 | 向代理报告长作业百分比 |
| 跨平台 | Windows+macOS,MATLAB R2022b+ |
| 一键Windows安装 | 脱机 install.bat --无需管理员权限 |
MATLAB绘图转换为交互式绘图
每个MATLAB图形都会自动转换为交互式 Plotly 图表——不需要额外的代码。当MATLAB代码创建绘图时,服务器:
- 提取图形属性 通过
mcp_extract_props.m--轴、线数据、标签、颜色、标记、图例、子图 - 将MATLAB样式映射到Plotly --线条样式(
--→dash),标记(o→circle)、图例位置、轴比例、颜色图 - 返回交互式JSON --可在任何web UI中渲染
Plotly.newPlot() - 生成静态PNG+缩略图 作为非交互式客户端的后备方案
支持的绘图类型: 线、散点、条、面积、子图(subplot/tiledlayout),多轴,对数/线性刻度
风格保真度: 线条样式、标记形状、颜色(RGB)、线条宽度、字体大小、轴标签、标题、图例、网格线、轴限制和背景颜色都被保留。
% 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');…自动成为此交互式Plotly图表:
线样式、颜色、标记、图例和轴标签都在转换中保留。
快速开始
先决条件
- Python 3.10+
- MATLAB R2022b+ 随着 用于Python的MATLAB引擎API 安装
# 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 .安装服务器
Windows(一键,无需管理员):
git clone https://github.com/HanSur94/matlab-mcp-server-python.git
cd matlab-mcp-server-python
install.bat安装程序会自动检测MATLAB,创建一个虚拟环境,并从捆绑的轮子安装所有东西——完全离线,不需要互联网。适用于Windows 10/11和Python 3.10、3.11或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]"运行它
# Single user (stdio) — simplest setup
matlab-mcp
# Multi-user (SSE) — shared server
matlab-mcp --transport sse连接到克劳德桌面
添加到您的Claude桌面配置(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):
{
"mcpServers": {
"matlab": {
"command": "matlab-mcp"
}
}
}连接到克劳德代码
claude mcp add matlab -- matlab-mcp连接到光标
添加 .cursor/mcp.json 在您的项目中:
{
"mcpServers": {
"matlab": {
"command": "matlab-mcp"
}
}
}使用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注: Docker镜像不包括MATLAB。您必须安装自己的MATLAB。
升级? 如果您以前安装为matlab-mcp-server,先卸载:pip uninstall matlab-mcp-server && pip install matlab-mcp-python
示例
基础:运行MATLAB代码
问你的AI代理:
“在MATLAB中计算3x3幻方的特征值”
代理人打电话来 execute_code:
A = magic(3);
eigenvalues = eig(A);
disp(eigenvalues)内联返回的结果:
15.0000
4.8990
-4.8990信号处理
“生成1kHz正弦波,添加噪声,然后用低通巴特沃斯滤波器对其进行滤波,并绘制两者”
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');返回:交互式绘图图表+静态PNG+缩略图。
长时间运行模拟(异步)
“用100万次试验运行蒙特卡洛模拟”
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));代理立即获得作业ID,轮询进度(“试用500000/1000000--50%”),并在完成后检索结果。
自定义工具
将您的专有MATLAB函数作为一流的AI工具公开。创建 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"现在代理人可以打电话了 analyze_signal 或 train_model 直接——带有完整的参数验证和帮助文本。
MCP工具参考
代码执行
| 工具 | 参数 | 说明 |
|---|---|---|
execute_code | code: str | 运行MATLAB代码。如果快速(\ |
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: 300Pool — 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-detectExecution — 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: trueSecurity — 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: falseToolboxes — 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监控
内置可观察性,具有web仪表板、JSON健康/指标端点和用于AI代理自我监控的MCP工具。
仪表盘
访问地址: http://localhost:8766/dashboard (stdio)或 http://localhost:8765/dashboard 上海证券交易所
特征:
- 7个带电仪表:池利用率、引擎(忙/总)、活动作业、已完成作业、活动会话、平均执行时间、错误/分钟
- 6个时间序列图 (Plotly.js):池利用率、作业吞吐量、执行时间(avg+p95)、活动会话、内存使用率、错误计数
- MATLAB执行日志:显示每个作业的时间、事件类型、MATLAB代码、输出和持续时间的可过滤表
- 时间范围选择器:1小时、6小时、24小时、7天浏览
- 每10秒自动刷新一次
健康端点
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
}状态码:200表示健康/退化,503表示不健康。
健康评估规则:
| 状态 | 条件 |
|---|---|
unhealthy | 发动机未运行(total == 0) |
unhealthy | 所有发动机均以最大容量运转(available == 0 && total >= max_engines) |
degraded | 池利用率>90% |
degraded | 检测到健康检查失败 |
degraded | 错误率>5/min |
healthy | 以上都没有 |
指标端点
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}
}仪表板API
| 端点 | 参数 | 描述 |
|---|---|---|
GET /health | -- | 健康状况+问题 |
GET /metrics | -- | 实时指标快照(无数据库命中) |
GET /dashboard | -- | Web仪表板HTML |
GET /dashboard/api/current | -- | 与 /metrics |
GET /dashboard/api/history | metric, hours | SQLite的时间序列数据 |
GET /dashboard/api/events | limit, type | 带有MATLAB输出的事件日志 |
可用历史指标: 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
后端架构
┌─────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────┘事件类型
事件通过以下方式同步记录 collector.record_event() 从任何服务器组件。每个事件都包含一个JSON details 现场。
| 事件类型 | 来源 | 详细信息字段 |
|---|---|---|
job_completed | 执行人 | job_id, execution_ms, code, output |
job_failed | 执行人 | job_id, code, error |
session_created | 会话管理器 | session_id_short |
engine_scale_up | 池管理器 | engine_id, total_after |
engine_scale_down | 池管理器 | engine_id, total_after |
engine_replaced | 池管理器 | old_id, new_id |
health_check_fail | 池管理器 | engine_id, error |
blocked_function | 安全验证器 | function, code_snippet |
内存计数器
收集器在每个事件(没有数据库命中)时更新7个计数器:
| 计数器 | 递增 |
|---|---|
completed_total | job_completed |
failed_total | job_failed |
cancelled_total | job_cancelled |
total_created_sessions | session_created |
error_total | 任何错误事件(job_failed, blocked_function, engine_crash, health_check_fail) |
blocked_attempts | blocked_function |
health_check_failures | health_check_fail |
执行时间跟踪
作业执行时间存储在环形缓冲区中(deque(maxlen=100))用于O(1)avg/p95计算,无需DB查询。p95的计算公式为 sorted_times[int((len-1) * 0.95)].
交通一体化
| 传输 | 监控端口 | 方式 |
|---|---|---|
| 上海证券交易所 | 与SSE端口(8765)相同 | 仪表板通过Starlette子应用程序安装 mcp._additional_http_routes |
| 标准 | 独立端口(8766) | Uvicorn作为后台启动 asyncio.Task |
数据保留
清理循环每60秒运行一次并调用 store.prune(retention_days=7) 删除超过配置的保留期的度量和事件。SQLite WAL模式确保在写入过程中不会阻止读取。
配置
monitoring:
enabled: true
sample_interval: 10 # seconds between metric samples
retention_days: 7 # days to keep historical data
db_path: "./monitoring/metrics.db"
dashboard_enabled: true
http_port: 8766 # dashboard/health port (stdio only)环境覆盖: MATLAB_MCP_MONITORING_ENABLED, MATLAB_MCP_MONITORING_SAMPLE_INTERVAL等等。
建筑
AI Agent (Claude, Cursor, etc.)
│
│ MCP Protocol (stdio or SSE)
▼
┌──────────────────────────────────────────────────────────┐
│ MCP Server (FastMCP 2.x) │
│ 20 tools + custom tools │
│ Session manager │ Security validator │ Formatter │
└──────────┬───────────────────────────────┬───────────────┘
│ │
┌──────────▼──────────────────┐ ┌─────────▼──────────────┐
│ Job Executor │ │ MetricsCollector │
│ Sync/async execution │ │ In-memory counters │
│ Timeout auto-promotion │ │ Ring buffer (p95) │
│ stdout/stderr capture │ │ Background sampling │
│ Event recording ──────────────▶ Event recording │
└──────────┬──────────────────┘ └─────────┬──────────────┘
│ │
┌──────────▼──────────────────┐ ┌─────────▼──────────────┐
│ MATLAB Pool Manager │ │ MetricsStore (SQLite) │
│ Elastic engine pool │ │ Time-series metrics │
│ Scale up/down on demand │ │ Event log with output │
│ Health checks & replace │ │ Aggregates & history │
└──────────┬──────────────────┘ └─────────┬──────────────┘
│ │
┌──────────▼──────────────────┐ ┌─────────▼──────────────┐
│ MATLAB Engines (R2022b+) │ │ Dashboard (Starlette) │
│ Engine 1 │ Engine 2 │ ... │ │ /health /metrics │
│ Workspace isolation │ │ /dashboard (Plotly.js) │
└──────────────────────────────┘ └─────────────────────────┘请求流
- AI代理发送
execute_code通过MCP协议 SecurityValidator根据函数块列表检查代码JobExecutor创建作业,从池中获取引擎- 代码在MATLAB中运行,通过以下方式捕获stdout/stderr
StringIO - 如果在内完成
sync_timeout(30s):结果内联返回 - 如果超过超时:升级为异步,代理将获得
job_id投票 MetricsCollector.record_event()日志代码+输出+持续时间- 引擎释放回池,工作区重置
部件接线
所有组件都会收到 collector 施工时参考。启动后,收集器连接到生命周期处理程序中的实时池/跟踪器/会话。这允许同步 record_event() 来自任何组件的调用,没有异步开销。
# Construction (before event loop)
collector = MetricsCollector(config)
pool = EnginePoolManager(config, collector=collector)
executor = JobExecutor(pool, tracker, config, collector=collector)
sessions = SessionManager(config, collector=collector)
security = SecurityValidator(config.security, collector=collector)
# Lifespan (after event loop starts)
collector.pool = pool
collector.tracker = tracker
collector.sessions = sessions
collector.store = MetricsStore(config.monitoring.db_path)发展
# Install dev dependencies
pip install -e ".[dev]"
# Run tests (no MATLAB needed — uses mock engine)
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=matlab_mcp --cov-report=term-missing
# Lint
ruff check src/ tests/项目结构
src/matlab_mcp/
├── server.py # MCP server entry point, tool registration
├── config.py # YAML config, pydantic validation, env overrides
├── pool/
│ ├── engine.py # Single MATLAB engine wrapper
│ └── manager.py # Elastic pool manager
├── jobs/
│ ├── models.py # Job data model, lifecycle
│ ├── tracker.py # Job store, pruning
│ └── executor.py # Sync/async execution, timeout promotion
├── tools/
│ ├── core.py # execute_code, check_code, get_workspace
│ ├── discovery.py # list_toolboxes, list_functions, get_help
│ ├── jobs.py # job status, result, cancel, list
│ ├── files.py # upload, delete, list files
│ ├── admin.py # pool status
│ ├── monitoring.py # get_server_metrics, get_server_health, get_error_log
│ └── custom.py # Custom tool loader from YAML
├── monitoring/
│ ├── collector.py # Background metrics sampling, event recording
│ ├── store.py # Async SQLite storage for time-series data
│ ├── health.py # Health evaluation (healthy/degraded/unhealthy)
│ ├── routes.py # HTTP route handlers (/health, /metrics)
│ ├── dashboard.py # Starlette sub-app with dashboard API
│ └── static/ # Dashboard HTML, CSS, JS (Plotly.js)
├── output/
│ ├── formatter.py # Result formatting
│ ├── plotly_convert.py # Load Plotly JSON from MATLAB extraction
│ ├── plotly_style_mapper.py # MATLAB→Plotly style/property conversion
│ └── thumbnail.py
├── session/
│ └── manager.py # Session lifecycle, temp dirs
├── security/
│ └── validator.py # Function blocklist, filename sanitization
└── matlab_helpers/
├── mcp_extract_props.m
├── mcp_checkcode.m
└── mcp_progress.m安全
| 保护 | 说明 |
|---|---|
| 功能块列表 | 块 system(), unix(), dos(), !, eval(), feval(), evalc(), evalin(), assignin(), perl(), python() 默认情况下 |
| 文件名清理 | 拒绝具有路径遍历或无效字符的文件名 |
| 工作空间隔离 | clear all; clear global; clear functions; fclose all; restoredefaultpath; 休会期间 |
| SSE代理身份验证 | 生产需要具有身份验证的反向代理 |
| 上传大小限制 | 可配置的最大上传大小(默认100MB) |
许可证
贡献
欢迎投稿!请在上打开问题或PR .
