-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
This guide helps you diagnose and fix common problems with the MATLAB MCP Server across installation, runtime, configuration, networking, and code execution scenarios.
graph TD
A[Problem Occurs] --> B{Category?}
B -->|Engine/Pool| C[Installation & Startup]
B -->|Code Won't Run| D[Runtime & Execution]
B -->|Settings Not Working| E[Configuration]
B -->|Can't Connect| F[Networking]
B -->|Other| G[Advanced]
C --> C1["See: MATLAB Engine Issues"]
D --> D1["See: Code Execution Issues"]
E --> E1["See: Configuration Issues"]
F --> F1["See: Networking Issues"]
G --> G1["See: Advanced Issues"]
Symptom:
-
Engine start timeoutin logs -
matlab.engine not foundwhen running server ModuleNotFoundError: No module named 'matlab'
Likely Causes:
- MATLAB Engine API for Python not installed
- MATLAB version too old (< 2020b)
- MATLAB installation not found on PATH
- Engine API installed for different Python version
Solution:
-
Verify MATLAB Engine API is installed:
python -c "import matlab.engine; print('OK')"If this fails, continue to step 2.
-
Install the Engine API for your MATLAB version:
Windows:
cd "C:\Program Files\MATLAB\R2024a\extern\engines\python" pip install .
macOS:
cd /Applications/MATLAB_R2024a.app/extern/engines/python pip install .
Linux:
cd /usr/local/MATLAB/R2024a/extern/engines/python pip install .
-
Check MATLAB version:
matlab -r "version, exit"Must be R2020b or later. If older, upgrade MATLAB.
-
Set
matlab_rootin config if MATLAB is not on PATH:pool: matlab_root: "/Applications/MATLAB_R2024a.app" # macOS # or "C:\\Program Files\\MATLAB\\R2024a" # Windows
-
Increase engine start timeout if MATLAB is slow:
pool: engine_start_timeout: 300 # 5 minutes instead of 120s
-
Verify Python version matches MATLAB compatibility:
python --version # Must match MATLAB's supported versionsConsult your MATLAB release notes for compatible Python versions.
Symptom:
- Engine state shows STOPPED unexpectedly
- Health check failures in logs
- Jobs fail with "engine not alive"
Likely Causes:
- Unrecoverable MATLAB error in previous execution
- Out of memory (MATLAB workspace too large)
- Segmentation fault (rare, usually with specific toolboxes)
- Timeout in long-running operation
Solution:
-
Check engine state via admin tool:
Call get_pool_statusLook for
available<total_engines. -
Enable debug logging to see error details:
server: log_level: "debug"
Then check logs for the exact failure reason.
-
Increase health check frequency:
pool: health_check_interval: 30 # Check every 30s instead of 60s
-
Lower
max_execution_timeto fail fast on hangs:execution: max_execution_time: 3600 # 1 hour instead of 24 hours
-
If on macOS, reduce
max_engines(known stability issue):pool: max_engines: 4 # macOS limit
Symptom:
- Job runs forever and never returns
- Progress updates stop
- Client eventually gets timeout error
Likely Causes:
- Infinite loop or unresponsive blocking operation
- Code waiting for user input
- Code accessing unreachable network resource
- MATLAB engine hung
Solution:
-
Cancel the stuck job immediately: Ask the AI agent to call
cancel_jobwith the job ID. -
Check
sync_timeoutsetting:execution: sync_timeout: 30 # Synchronous timeout before async promotion max_execution_time: 86400 # Hard timeout (24 hours)
If your job should take longer, increase
sync_timeout. -
Add progress reporting to debug long jobs:
mcp_progress(__mcp_job_id__, progress_pct, sprintf('Step %d/%d', i, total));
Check progress via
get_job_statusto verify the job is still making progress. -
Look for blocking operations in your code:
pause()-
keyboard(interactive debugger) -
input()(waiting for console input) - Network calls without timeout
Replace with non-blocking alternatives or add timeouts.
-
Check available memory:
memory % Shows memory usage in MATLAB
If memory is exhausted, your code may hang during allocation. Use
clearvarsto free memory.
Symptom:
BlockedFunctionError: Function 'system' is blockedBlockedFunctionError: Function 'eval' is blocked
Likely Causes:
- Your code uses a dangerous function (intentionally blocked for security)
- You need to perform a task that requires the blocked function
- You're testing code that wasn't written for the sandbox
Solution:
Option 1: Use MATLAB-native alternatives (recommended)
| Blocked Function | MATLAB Alternative |
|---|---|
system('ls') |
dir, cd, ls (filesystem functions) |
unix('ls') |
Same as above |
eval('code') |
feval(func_name, args) or str2func
|
| File operations |
movefile, copyfile, delete, mkdir
|
| Env vars | getenv('VAR_NAME') |
Option 2: Disable blocking for trusted code (team/personal use only)
Remove the specific function from the blocklist:
security:
blocked_functions_enabled: true
blocked_functions: # Remove "system" from this list
- "eval"
- "feval"
- "unix"
# "system" removedOption 3: Disable all blocking (not recommended for production)
security:
blocked_functions_enabled: falseSymptom:
-
execute_codereturns empty output - Variables appear to be unset
- No errors are raised
Likely Causes:
- Code ran but produced no console output (silent execution)
- Semicolon suppressing output
- Variables only exist in a local scope
- Workspace isolation cleared variables between calls
Solution:
-
Add
disp()to see intermediate values:result = expensive_calculation(); disp(['Result: ', num2str(result)]) % Will appear in output
-
Call
get_workspaceafterexecute_codeto see all variables: Ask the agent to callget_workspaceto list all defined variables and their values. -
Check workspace isolation: If enabled (default),
clear allruns between sessions. Variables persist within a session but not across sessions. -
Return values explicitly: MATLAB doesn't auto-print unless you omit the semicolon, but the server captures workspace variables:
x = 42 % No semicolon, but server still captures x
Symptom:
- Plot returns as static image only (no interactive Plotly version)
- No error message (silent failure)
- Some plots convert, others don't
Likely Causes:
- Plot type not supported (custom graphics, app objects)
- Figure properties not fully extracted
- Plotly JSON validation failed
- Too complex/large for Plotly conversion
Supported Types:
- ✅ Line plots
- ✅ Scatter plots
- ✅ Bar charts
- ✅ Histograms
- ✅ 3D surfaces
- ✅ Heatmaps
- ✅ Multi-axis subplots
- ❌ Custom graphics, patch objects, or app components
Solution:
-
Enable debug logging to see conversion errors:
server: log_level: "debug"
Look for
plotlyorextract_propsmessages in the log. -
Use standard plotting functions:
plot(x, y); % ✅ Supported scatter(x, y); % ✅ Supported patch(x, y); % ❌ Not supported
-
Disable Plotly conversion if not needed:
output: plotly_conversion: false # Return static images only
-
Simplify complex layouts: Split multi-panel figures into separate
figure()calls if they use custom layouts:figure('Position', [100 100 800 600]); % ❌ Custom position % Better: use standard tiledlayout tiledlayout(2, 1); nexttile; plot(x, y); nexttile; plot(x, z);
Symptom:
- Output message says "Result saved to file: result_12345.txt"
- Values shown as
<array: 10000x1000>instead of full data - Inline text cut off mid-sentence
Likely Causes:
- Result exceeds
max_inline_text_length(50,000 characters) - Workspace has too many large variables
- Output contains a massive matrix/table
Solution:
-
Access the full result file: Use
read_dataorget_job_resultto fetch the saved file. -
Increase truncation thresholds (if safe for your setup):
output: max_inline_text_length: 100000 # Default: 50,000 large_result_threshold: 50000 # Default: 10,000
-
Reduce output size in code:
% Instead of returning all 1M values: data = randn(1000000, 1); % Return only a summary: summary = [mean(data); std(data); min(data); max(data)]; disp(summary)
-
Clear unused variables:
% Before expensive computation: clearvars
Symptom:
- Configuration changes in
config.yamldon't apply - Server still uses old settings
- Environment variables ignored
Likely Causes:
- Configuration file not found or syntax error
- Server not restarted after config change
- Environment variable not set correctly
- Config file in wrong location
Solution:
-
Verify config file is loaded:
matlab-mcp --config /path/to/config.yaml
Check server startup log for:
Loaded config from: ... -
Validate YAML syntax:
python -m yaml /path/to/config.yaml # Checks for parse errorsYAML is whitespace-sensitive; use spaces not tabs.
-
Check environment variable format: Environment variables override config file with
MATLAB_MCP_prefix and double underscores for nesting:# Set pool min_engines to 4: export MATLAB_MCP_POOL__MIN_ENGINES=4 # Set execution sync_timeout to 60: export MATLAB_MCP_EXECUTION__SYNC_TIMEOUT=60
-
Restart the server after changes:
# Kill current server pkill -f matlab-mcp # Start with config: matlab-mcp --config ./config.yaml
-
Check current effective config via debug logging:
server: log_level: "debug"
Server prints merged config on startup.
Symptom:
-
list_functionsreturns empty list for a toolbox - Function not found even though toolbox is installed
- Toolbox not listed in
list_toolboxes
Likely Causes:
- Toolbox filtered out by
toolboxesconfig - Toolbox not actually installed
- Function name is incorrect
Solution:
-
Check toolbox mode:
toolboxes: mode: "whitelist" # "all", "whitelist", or "blacklist" list: - "Signal Processing" # Must match exact name
-
List available toolboxes: Call
list_toolboxesto see exact names MATLAB reports. -
Use whitelist mode for security:
toolboxes: mode: "whitelist" list: - "Signal Processing Toolbox" - "Statistics and Machine Learning Toolbox"
-
Check function name: Verify function exists in MATLAB:
help signal_name % In MATLAB, not through server
Symptom:
-
ERR_CONNECTION_REFUSEDwhen connecting to SSE endpoint Connection refused: localhost:8765- Agent can't reach the server
Likely Causes:
- Server not running
- Wrong port in config/agent config
- Firewall blocking port
- Server bound to wrong host (localhost vs 0.0.0.0)
Solution:
-
Verify server is running:
ps aux | grep matlab-mcp -
Check configured port:
server: port: 8765 # Default host: "0.0.0.0" # 0.0.0.0 for remote, 127.0.0.1 for local
-
Test local connection:
curl http://localhost:8765/health
Should return JSON health status.
-
Check firewall:
# macOS sudo lsof -i :8765 # Linux sudo netstat -tlnp | grep 8765
-
For remote access, use reverse proxy (nginx, Caddy):
server { location /mcp { proxy_pass http://localhost:8765; } }
Then connect agent to
https://yourdomain.com/mcp. -
Enable SSE explicitly:
server: transport: "sse"
Symptom:
- Requests take 5+ seconds to respond
- Pool appears full (all engines busy)
- Requests queuing up
Likely Causes:
- Engine pool too small for concurrent requests
- Engine startup slow (MATLAB is slow to initialize)
- Code itself is genuinely slow
- Network latency (if using remote server)
Solution:
-
Increase engine pool size:
pool: min_engines: 4 # Start with more engines max_engines: 16 # Allow scaling up
-
Reduce engine start timeout if startup is slow:
pool: engine_start_timeout: 300 # Allow 5 minutes for MATLAB to start
-
Enable proactive warmup to keep engines ready:
pool: proactive_warmup_threshold: 0.8 # Start new engine if 80% busy
-
Check queue length: Call
get_pool_statusto see:- How many engines are busy
- What the queue depth is
- If bottleneck is pool or code
-
For remote deployments, reduce network hops:
- Use CDN or caching proxy
- Reduce result size with
max_inline_text_length - Stream results incrementally
Symptom:
-
get_pool_statusshows all engines busy but no new engines created - Jobs queue indefinitely
- Max engines not reached even under load
Likely Causes:
-
max_enginesset too low -
proactive_warmup_thresholdnot triggered - Engine startup failing silently
Solution:
-
Verify max_engines > min_engines:
pool: min_engines: 2 max_engines: 10 # Must be > min
-
Check engine startup is working: Enable debug logging and look for startup errors:
server: log_level: "debug"
-
Lower proactive warmup threshold:
pool: proactive_warmup_threshold: 0.6 # Start scaling at 60% utilization
-
Manually trigger scaling by checking pool:
Call get_pool_status to see if new engines are created
Symptom:
- Server memory grows over time
- Never releases memory even after jobs complete
- Eventually runs out of memory
Likely Causes:
- Workspace not isolated between jobs
- Large figures not cleared
- Job results not cleaned up
- MATLAB engine memory not freed
Solution:
-
Enable workspace isolation (default):
execution: workspace_isolation: true # Clears workspace between sessions
-
Manually clear large variables:
clear large_matrix clear functions
-
Set shorter job retention:
sessions: job_retention_seconds: 3600 # 1 hour (default: 24 hours)
-
Monitor memory via dashboard: Access
http://localhost:8766/dashboardto see memory usage over time. -
Restart server periodically (if memory leak persists): Add a systemd timer or cron job to restart every 24 hours.
Symptom:
- Custom tools don't appear in MCP tools list
- Tool calls return "tool not found"
- YAML file exists but not loaded
Likely Causes:
-
custom_tools.yamlfile not found - YAML syntax error
- Tool definitions invalid
- Config path is relative (not resolved correctly)
Solution:
-
Check config file path:
custom_tools: config_file: "./custom_tools.yaml" # Relative to working directory
-
Validate YAML syntax:
python -c "import yaml; yaml.safe_load(open('custom_tools.yaml'))" -
Check tool definitions:
tools: - name: "my_function" matlab_function: "my_pkg.my_func" # Must exist in MATLAB description: "Does something useful" parameters: x: type: "number" description: "Input value" returns: type: "object"
-
Test tool in MATLAB directly:
result = my_pkg.my_func(42) % Should not error
-
Enable debug logging:
server: log_level: "debug"
Look for messages about custom tool loading.
Symptom:
- Dashboard loads but shows zeros/empty
- Charts are empty
- Metrics endpoint returns empty objects
Likely Causes:
- Monitoring disabled in config
- Dashboard HTTP port not accessible
- Metrics store empty or not initialized
- JavaScript errors in browser console
Solution:
-
Verify monitoring is enabled:
monitoring: enabled: true dashboard_enabled: true
-
Check dashboard URL:
http://localhost:8766/dashboardPort defaults to 8766; check
monitoring.http_portin config. -
Check metrics are being recorded:
Call get_server_metrics via MCP toolShould return non-empty stats.
-
Open browser console (F12) and look for JavaScript errors:
- Plotly.js not loading
- API endpoint 404
- CORS issues (if remote server)
-
Rebuild metrics database:
rm ./monitoring/metrics.db # Delete stale DB # Restart server—new DB will be created
Set log level to debug to see detailed server activity:
server:
log_level: "debug"
log_file: "./logs/server.log"Or via environment variable:
export MATLAB_MCP_SERVER__LOG_LEVEL=debug
matlab-mcpLog file will show:
- Config loading and merging
- Engine pool operations (creation, scaling, health checks)
- Job execution details (start, finish, errors)
- Security validation decisions
- Monitoring events
For bug reports, gather:
-
Server version:
pip show matlab-mcp
-
Environment info:
python --version matlab -r "version, exit" uname -a # or `systeminfo` on Windows
-
Config file (with sensitive info redacted):
cat config.yaml
-
Last 100 lines of log file:
tail -100 ./logs/server.log > logs_excerpt.txt -
Pool status snapshot: Call
get_pool_statusand save output -
Server health snapshot: Call
get_server_healthand save output -
Minimal reproducible example: Include exact MATLAB code that triggers the issue
| Log Message | Meaning | Action |
|---|---|---|
Loaded config from: ... |
Config successfully parsed | Check if paths are absolute |
Engine pool initialized: min=2 max=10 |
Pool created with correct sizes | Verify settings |
Engine (engine-0) start timeout exceeded |
MATLAB took > 120s to start | Increase engine_start_timeout
|
Health check failed: Engine unavailable |
Engine crashed or became unresponsive | Check MATLAB errors |
BlockedFunctionError: Function 'system' is blocked |
Security validation rejected code | Use alternative or disable |
Job promotion: sync→async timeout exceeded |
Code took > 30s, moved to background | Normal for long-running code |
SQLAlchemy warning: ... |
Database initialization message | Safe to ignore |
- Check the FAQ: FAQ page for common questions
- Review examples: Examples page for working code samples
- Read Configuration guide: Configuration page for all settings
- Check Architecture guide: Architecture page to understand data flow
Visit the issue tracker on GitHub:
- Check if your issue is already reported
- Include diagnostics from section above
- Provide minimal reproducible example
- Specify your platform (Windows/macOS/Linux) and MATLAB version
- GitHub Discussions: Ask questions, share tips
- GitHub Issues: Report bugs
- Pull Requests: Contribute fixes or features
flowchart TD
A["Problem Occurs"] --> B{"Can you<br/>import matlab.engine?"}
B -->|No| C["→ See: MATLAB Engine Won't Start"]
B -->|Yes| D{"Does code<br/>execute at all?"}
D -->|No| E["→ See: Code Execution Issues"]
D -->|Yes| F{"Is output<br/>correct?"}
F -->|No| G{"Is result<br/>truncated?"}
G -->|Yes| H["→ See: Result Truncated"]
G -->|No| I["→ See: Code Produces No Output"]
F -->|Yes| J{"Are settings<br/>being applied?"}
J -->|No| K["→ See: Settings Not Taking Effect"]
J -->|Yes| L{"Can you<br/>connect to<br/>server?"]
L -->|No| M["→ See: SSE Connection Refused"]
L -->|Yes| N["✅ System Working<br/>Enable debug logging<br/>for detailed insights"]