-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Symptom: pip install matlab-mcp fails with permission or dependency errors
Likely Cause: Virtual environment not activated, or missing Python development headers
Solution:
-
Verify Python 3.10+ is installed:
python --version
-
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # macOS/Linux # or venv\Scripts\activate # Windows
-
Upgrade pip:
pip install --upgrade pip
-
Install the package:
pip install matlab-mcp
Symptom: ModuleNotFoundError: No module named 'matlab' after installation
Likely Cause: MATLAB Engine API for Python not installed, or MATLAB path not configured
Solution:
-
Locate your MATLAB installation:
-
Windows:
C:\Program Files\MATLAB\R2024a(or your version) -
macOS:
/Applications/MATLAB_R2024a.app(or your version) -
Linux:
/usr/local/MATLAB/R2024a(or your version)
-
Windows:
-
Install Engine API from MATLAB directory:
cd "C:\Program Files\MATLAB\R2024a\extern\engines\python" # Windows pip install . # or macOS/Linux: cd /Applications/MATLAB_R2024a.app/extern/engines/python pip install .
-
Verify installation:
python -c "import matlab.engine; print('Engine API OK')" -
If still failing, set MATLAB root in config:
# config.yaml pool: matlab_root: "C:\\Program Files\\MATLAB\\R2024a" # Windows # or /Applications/MATLAB_R2024a.app # macOS
Symptom: matlab-mcp command fails to start, or exits immediately
Likely Cause: MATLAB engine pool initialization timeout, invalid config, or missing dependencies
Solution:
flowchart TD
A["Server won't start"] --> B{Check error message}
B -->|Engine timeout| C["Increase engine_start_timeout<br/>in config.yaml"]
B -->|Config error| D["Validate config.yaml syntax<br/>with YAML linter"]
B -->|Module not found| E["Reinstall package:<br/>pip install matlab-mcp"]
B -->|Port in use| F["Change port in config<br/>or kill existing process"]
C --> G["Retry server start"]
D --> G
E --> G
F --> G
Debug Steps:
-
Check for immediate errors:
matlab-mcp --help
Should show usage without errors.
-
Enable debug logging:
export MATLAB_MCP_SERVER_LOG_LEVEL=debug # macOS/Linux # or setenv MATLAB_MCP_SERVER_LOG_LEVEL debug # Windows PowerShell matlab-mcp --config config.yaml
-
Check config syntax:
python -c "from matlab_mcp.config import AppConfig; AppConfig.from_yaml('config.yaml')"If successful, prints config; otherwise shows YAML/validation errors.
-
Test MATLAB engine independently:
python -c "import matlab.engine; eng = matlab.engine.start_matlab(); print('Engine OK'); eng.quit()" -
Increase engine startup timeout:
pool: engine_start_timeout: 60 # 60 seconds (default 30) min_engines: 1 # Start with only 1 engine to debug
Symptom: Engine 1 start timeout after 30s in logs
Likely Cause: MATLAB is slow to start on this system, or licensing issue
Solution:
-
Increase timeout:
pool: engine_start_timeout: 120 # 2 minutes
-
Test MATLAB directly:
matlab -nosplash -nodesktop -r "disp('MATLAB OK'); exit"
-
Check MATLAB license:
matlab >> license
-
Reduce initial pool size:
pool: min_engines: 0 # Start with no engines, scale on demand max_engines: 2 # Limit total engines
Symptom: Agent (Claude Code, Codex CLI, Cursor) reports connection refused or timeout
Likely Cause: Server not running on expected address/port, firewall blocking, or wrong transport
Solution:
flowchart TD
A["Agent can't connect"] --> B{Check server status}
B -->|Server not running| C["Start server:<br/>matlab-mcp"]
B -->|Server running| D{Check transport}
D -->|Using stdio| E["Agent must connect<br/>via same process<br/>check MCP config"]
D -->|Using SSE/HTTP| F{Verify address}
F -->|Wrong address| G["Update agent config<br/>to 127.0.0.1:8765"]
F -->|Firewall blocks| H["Allow port 8765<br/>in firewall settings"]
F -->|No token| I["Set MATLAB_MCP_AUTH_TOKEN<br/>for HTTP transports"]
C --> J["Retry agent connection"]
E --> J
G --> J
H --> J
I --> J
Debug Steps:
-
Verify server is running:
ps aux | grep matlab-mcp # or Windows: tasklist | findstr matlab-mcp
-
Check port is listening:
netstat -an | grep 8765 # macOS/Linux # or Windows: netstat -ano | findstr 8765
-
Test with curl (for HTTP/SSE transports):
curl http://127.0.0.1:8765/health # Should return {"status": "healthy", ...} -
Verify agent configuration:
- For Claude Code/Claude Desktop: Check config at
~/.config/claude/config.json(Linux/macOS) or%APPDATA%\Claude\config.json(Windows) - Ensure
"transport"is correct:"stdio"for local,"sse"or"http"for remote - For HTTP: ensure bearer token matches
MATLAB_MCP_AUTH_TOKENenv var
- For Claude Code/Claude Desktop: Check config at
-
Set auth token for HTTP transports:
export MATLAB_MCP_AUTH_TOKEN="your-token-here" # macOS/Linux # or Windows PowerShell: $env:MATLAB_MCP_AUTH_TOKEN="your-token-here" matlab-mcp --transport streamablehttp
-
Check firewall (Windows):
# Allow port 8765 in Windows Firewall New-NetFirewallRule -DisplayName "MATLAB MCP" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8765
Symptom: Code execution fails with blocked function error
Likely Cause: Security validator blocks dangerous MATLAB functions by default
Solution:
flowchart TD
A["Blocked function error"] --> B{What function is blocked?}
B -->|system/unix/dos| C["Use MATLAB native alternatives:<br/>dir, mkdir, copyfile, movefile"]
B -->|eval/evalc| D["Use feval with named function<br/>or avoid dynamic code"]
B -->|eval/fevalc| E["Rewrite without eval"]
B -->|Other| F{Can disable blocking?}
F -->|Not shared server| G["Disable in config:<br/>security.blocked_functions_enabled: false"]
F -->|Shared server| H["Contact admin<br/>to whitelist function"]
C --> I["Retry execution"]
D --> I
E --> I
G --> I
H --> I
Blocked Functions (Default):
- Shell execution:
system,unix,dos,!(shell escape) - Dynamic code:
eval,evalc,feval(with string function name) - File I/O:
fopen,fread,fwrite(use MATLAB-nativereadtable,writematrix)
Safe Alternatives:
| Blocked | Use Instead |
|---|---|
system('ls') |
dir |
system('mkdir x') |
mkdir('x') |
system('cp a b') |
copyfile('a', 'b') |
system('mv a b') |
movefile('a', 'b') |
eval('x=5') |
x=5 (inline) |
feval('func', args) |
func(args) |
getenv('VAR') |
✓ Safe (whitelisted) |
cd /path |
✓ Safe |
pwd, ls, dir
|
✓ Safe |
To disable blocking (not recommended):
security:
blocked_functions_enabled: falseSymptom: Job never completes, remains in "running" state, or hits timeout
Likely Cause: Long-running code, infinite loop, or MATLAB hang
Solution:
-
Cancel the job: Ask your agent to call
cancel_job:Agent: "Cancel job <job-id>" -
Check execution timeout:
execution: sync_timeout: 30 # Inline execution timeout max_execution_time: 86400 # Max total time (24h)
-
Increase timeout if code is legitimately slow:
execution: sync_timeout: 300 # 5 minutes max_execution_time: 3600 # 1 hour max
-
Enable progress reporting for long-running code:
% In your MATLAB code: for i = 1:1000 % Do work mcp_progress(__mcp_job_id__, i/1000*100, sprintf('Iteration %d', i)); end
-
Check for infinite loops:
while true % Missing break condition? end
Symptom: Code executes but returns wrong values, missing variables, or truncated output
Likely Cause: Large results truncated, workspace not cleared between jobs, or format issue
Solution:
-
Check for truncation:
Output size: 125,000 chars (truncated, saved to file)Increase limits if needed:
output: max_inline_text_length: 100000 # Default 50k chars large_result_threshold: 50000 # Default 10k elements
-
Verify workspace isolation: Each job should start with a fresh workspace. If seeing leftover variables, the session may not be isolated. Check:
whos % See what variables are defined
-
Check result format: Results are automatically converted:
- Tables → JSON
- Figures → Plotly JSON + PNG
- Matrices → arrays
- Text → string (truncated if >50k chars)
Symptom: Code produces plot but no interactive Plotly visualization, only static PNG
Likely Cause: Plot type not supported by converter, or mcp_extract_props.m failed
Solution:
flowchart TD
A["Plotly conversion failed"] --> B{Check plot type}
B -->|Simple line/scatter| C["Update plotly_style_mapper.py<br/>or file bug report"]
B -->|Custom/complex plot| D["Supported: line, scatter, bar,<br/>histogram, surface, heatmap<br/>Simplify plot or use static PNG"]
B -->|Multiple subplots| E["Check domain calculation<br/>for subplot layout"]
D --> F["Use static PNG fallback"]
C --> G["Test with simple plot"]
E --> G
Supported Plot Types:
- ✓ Line plots (
plot) - ✓ Scatter plots (
scatter) - ✓ Bar charts (
bar) - ✓ Histograms (
histogram) - ✓ Surface plots (
surf) - ✓ Heatmaps (
imagesc,heatmap) ⚠️ Custom graphics objects (may not convert)
Solutions:
-
Fallback to static PNG:
output: plotly_conversion: false # Use PNG only
-
Simplify the plot:
% Instead of complex customizations: plot(x, y); title('My Plot'); xlabel('X'); ylabel('Y'); % Rather than: ax = gca; ax.XColor = [0.5 0.5 0.5]; % ... many other properties
-
Check supported subplots:
% Good — standard subplot grid subplot(2, 2, 1); plot(x, y); subplot(2, 2, 2); plot(x, y); % Also supported — tiled layout tiledlayout(2, 2); nexttile; plot(x, y); nexttile; plot(x, y);
-
Enable debug logging:
server: log_level: debug
Check logs for
Plotly conversionerrors.
Symptom: Can't read/upload image files, or file operations fail
Likely Cause: File path traversal protection, or size limits
Solution:
-
Check file size limit:
security: max_upload_size_mb: 100
-
Verify file is in temp directory: Files are restricted to the session's temp directory:
/tmp/<session-id>/ (macOS/Linux) C:\Users\<user>\AppData\Local\Temp\matlab-mcp\<session-id>\ (Windows) -
Test upload:
Agent: "Upload file data.txt with content 'hello'"File is saved to temp directory and can be accessed.
Symptom: Environment variable doesn't override config.yaml setting
Likely Cause: Wrong env var name or format
Solution:
Environment variables use MATLAB_MCP_* prefix with path notation:
# Set specific fields:
export MATLAB_MCP_SERVER_HOST=0.0.0.0
export MATLAB_MCP_SERVER_PORT=9000
export MATLAB_MCP_POOL_MIN_ENGINES=2
export MATLAB_MCP_EXECUTION_SYNC_TIMEOUT=60
export MATLAB_MCP_SECURITY_BLOCKED_FUNCTIONS_ENABLED=false
export MATLAB_MCP_MONITORING_ENABLED=true
# Start server — these override config.yaml
matlab-mcp --config config.yamlEnv Var Naming Pattern:
-
MATLAB_MCP_prefix - Nested keys with underscores:
SERVER_HOST,POOL_MIN_ENGINES - Values coerced to config types (bool, int, float, string)
Symptom: Error: config.yaml not found
Solution:
-
Create a default config:
# Server creates a default config at startup matlab-mcp --config config.yaml --generate-defaults # or manually: cp examples/config_minimal.yaml config.yaml
-
Use absolute path:
matlab-mcp --config /full/path/to/config.yaml
-
Check working directory:
pwd # Prints current directory ls -la config.yaml # File exists here?
Symptom: Agent receives HTTP 401 error when connecting
Likely Cause: Bearer token missing or incorrect, auth not configured
Solution:
flowchart TD
A["HTTP 401 Unauthorized"] --> B{Is auth enabled?}
B -->|Stdio transport| C["Auth bypassed for stdio<br/>no token needed"]
B -->|HTTP/SSE transport| D["Generate and set token"]
C --> E["Check transport:<br/>--transport stdio"]
D --> F["Generate token:<br/>matlab-mcp --generate-token"]
F --> G["Set env var:<br/>export MATLAB_MCP_AUTH_TOKEN=..."]
G --> H["Agent uses Authorization header:<br/>Authorization: Bearer <token>"]
E --> I["Retry agent connection"]
H --> I
Steps:
-
Generate a token:
matlab-mcp --generate-token
Output:
Generated bearer token (64 hex chars): a1b2c3d4e5f6... Environment variable to set: export MATLAB_MCP_AUTH_TOKEN="a1b2c3d4e5f6..." -
Set environment variable:
# macOS/Linux: export MATLAB_MCP_AUTH_TOKEN="a1b2c3d4e5f6..." # Windows PowerShell: $env:MATLAB_MCP_AUTH_TOKEN="a1b2c3d4e5f6..."
-
Start server:
matlab-mcp --transport streamablehttp
-
Configure agent to use bearer token:
{ "mcpServers": { "matlab": { "command": "python", "args": ["-m", "matlab_mcp"], "env": { "MATLAB_MCP_AUTH_TOKEN": "a1b2c3d4e5f6..." } } } }Or for HTTP transports:
{ "mcpServers": { "matlab": { "type": "sse", "url": "http://127.0.0.1:8765", "headers": { "Authorization": "Bearer a1b2c3d4e5f6..." } } } }
Symptom: --generate-token fails with permission denied
Solution:
-
Run with explicit permissions:
python -m matlab_mcp --generate-token
-
Use Python directly:
import secrets token = secrets.token_hex(32) print(f"MATLAB_MCP_AUTH_TOKEN={token}")
-
Check file permissions: If config.yaml or log files have restrictive permissions, update:
chmod 644 config.yaml chmod 755 logs/
Symptom: OSError: [Errno 24] Too many open files
Likely Cause: System file descriptor limit exceeded (MATLAB engines open many files)
Solution:
-
Increase file descriptor limit:
# Temporary (current session): ulimit -n 4096 # Permanent (add to ~/.zshrc or ~/.bash_profile): ulimit -n 4096
-
Verify limit:
ulimit -n # Shows current limit
-
Reduce engine pool:
pool: max_engines: 2 # Fewer engines = fewer files
Symptom: Server fails to start, or firewall/admin dialog appears
Likely Cause: Non-admin user trying to bind to privileged port or access restricted directory
Solution:
-
Use loopback address (no admin needed):
server: host: "127.0.0.1" # Default — requires no admin # Not 0.0.0.0 — that requires admin on Windows without exception
-
Use non-privileged port:
server: port: 8765 # >1024 — no admin needed # Not 80, 443, 8080, etc.
-
Run installer as admin (one-time):
# Use the install.bat provided, or: python -m pip install --user matlab-mcp
-
Check temp directory: Server creates session directories in:
C:\Users\<user>\AppData\Local\Temp\matlab-mcp\Ensure directory exists and is writable:
New-Item -Path "$env:APPDATA\..\Local\Temp\matlab-mcp" -ItemType Directory -Force
Symptom: Plotting fails with matplotlib import error
Likely Cause: Plotting library not installed, or wrong Python environment
Solution:
-
Install visualization dependencies:
pip install matlab-mcp[monitoring] # Includes plotting libs -
Or install separately:
pip install matplotlib plotly pillow
-
Verify environment:
python -c "import matplotlib; print(matplotlib.__version__)"
If issues persist, collect this information for support:
# System info
python --version
matlab -version
uname -a # macOS/Linux
wmic os get version # Windows
# Package versions
pip show matlab-mcp
pip list | grep -E "matlab|fastmcp|pydantic|plotly"
# Config validation
python -c "from matlab_mcp.config import AppConfig; AppConfig.from_yaml('config.yaml')" 2>&1
# MATLAB engine test
python -c "import matlab.engine; eng = matlab.engine.start_matlab(); print(eng.version()); eng.quit()" 2>&1
# Server logs (enable debug)
export MATLAB_MCP_SERVER_LOG_LEVEL=debug
matlab-mcp --config config.yaml 2>&1 | head -100
# Network (if connection issues)
netstat -an | grep 8765
curl -v http://127.0.0.1:8765/health 2>&1Save all output to a file and share with the project.
- GitHub Issues: matlab-mcp-server-python/issues
- Documentation: Check Configuration, Architecture, Security
-
Examples: See
examples/directory for working code samples
# config.yaml
server:
log_level: "debug"
log_file: "./logs/server.debug.log"
monitoring:
enabled: true # Collect detailed metricsThen check logs/server.debug.log for detailed error context:
tail -f logs/server.debug.log
# or search for errors:
grep -i "error\|exception" logs/server.debug.logRun server without MATLAB, perfect for testing transport/auth:
matlab-mcp --inspect --transport streamablehttpThis starts the server with:
- No MATLAB engine pool (instant startup)
- All tools return mock responses
- Auth/transport fully functional
- Useful for agent configuration testing
# Terminal 1: Start server
matlab-mcp
# Terminal 2: Test with curl (stdio transport)
echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}' | python -m matlab_mcp
# Or for HTTP:
curl -H "Authorization: Bearer $MATLAB_MCP_AUTH_TOKEN" \
http://127.0.0.1:8765/healthIf the server is slow:
pool:
min_engines: 0 # Don't start engines until needed
max_engines: 4 # Limit total engines
health_check_interval: 60 # Check less frequently
execution:
sync_timeout: 10 # Promote to async sooner
monitoring:
enabled: false # Disable metrics if not needed
output:
plotly_conversion: false # Skip Plotly, use PNG only