-
Notifications
You must be signed in to change notification settings - Fork 0
Examples
Ready-to-run examples are in the examples/ directory. You don't run these directly — ask your AI agent to execute them!
Ask your agent: "Calculate the eigenvalues of a 3×3 magic square"
A = magic(3);
eigenvalues = eig(A);
disp(eigenvalues)The server executes this synchronously and returns the eigenvalues to the agent within milliseconds.
Ask your agent: "Create two 100×100 random matrices, multiply them, and show the trace"
A = rand(100);
B = rand(100);
C = A * B;
fprintf('Trace: %.4f\n', trace(C));Ask your agent: "Solve the system: 3x + 2y - z = 1, 2x - 2y + 4z = -2, −x + 0.5y − z = 0"
A = [3 2 -1; 2 -2 4; -1 0.5 -1];
b = [1; -2; 0];
x = A \ b;
disp(x)All MATLAB figures are automatically converted to interactive Plotly visualizations with live zoom, pan, and export capabilities. Static PNG thumbnails are also generated.
Ask your agent: "Plot sin(x) from 0 to 2π"
x = linspace(0, 2*pi, 200);
plot(x, sin(x), 'LineWidth', 2, 'Color', [0 0.4470 0.7410]);
xlabel('x');
ylabel('sin(x)');
title('Sine Wave');
grid on;The agent receives both an interactive Plotly JSON and a PNG thumbnail it can display inline.
Ask your agent: "Show me the peaks function as a 3D surface"
[X, Y] = meshgrid(-3:0.1:3);
Z = peaks(X, Y);
surf(X, Y, Z);
colorbar;
shading interp;
title('Peaks Function');The interactive 3D plot rotates and zooms in the agent's UI.
Ask your agent: "Plot 4 sine waves at different frequencies in subplots"
t = linspace(0, 1, 1000);
freqs = [5 10 20 50];
for i = 1:4
subplot(2, 2, i);
plot(t, sin(2*pi*freqs(i)*t), 'LineWidth', 1.5);
title(sprintf('%d Hz', freqs(i)));
ylabel('Amplitude');
end
xlabel('Time (s)');All four plots appear in a 2×2 grid with independent axes.
Ask your agent: "Generate a 440 Hz tone with noise, compute its FFT, and show both time and frequency domains"
fs = 8000; % Sample rate
t = 0:1/fs:0.5; % 0.5 seconds
signal = sin(2*pi*440*t) + 0.3*randn(size(t)); % 440 Hz + noise
% Compute FFT
N = length(signal);
Y = fft(signal);
f = (0:N-1) * (fs / N);
% Plot time domain
subplot(2, 1, 1);
plot(t*1000, signal, 'b-', 'LineWidth', 0.5);
title('Time Domain');
xlabel('Time (ms)');
ylabel('Amplitude');
grid on;
% Plot frequency domain (one-sided)
subplot(2, 1, 2);
plot(f(1:N/2), 2*abs(Y(1:N/2))/N, 'r-', 'LineWidth', 1);
title('Frequency Domain (FFT)');
xlabel('Frequency (Hz)');
ylabel('Magnitude');
xlim([0 2000]);
grid on;Ask your agent: "Apply a low-pass Butterworth filter to a noisy signal"
fs = 1000;
t = 0:1/fs:2;
signal = sin(2*pi*10*t) + 3*sin(2*pi*80*t) + randn(size(t));
% Design 2nd-order low-pass filter (cutoff 30 Hz)
[b, a] = butter(2, 30/(fs/2), 'low');
filtered = filter(b, a, signal);
% Compare
subplot(2, 1, 1);
plot(t, signal, 'b', 'LineWidth', 0.5);
title('Original (10 Hz + 80 Hz + noise)');
subplot(2, 1, 2);
plot(t, filtered, 'r', 'LineWidth', 1);
title('Filtered (low-pass @ 30 Hz)');Jobs exceeding the sync_timeout (default 30 seconds) are automatically promoted to background execution. The agent receives a job ID and can poll progress in real time using the mcp_progress() helper.
Ask your agent: "Run a Monte Carlo simulation with 10 million trials to estimate π"
% This will exceed sync_timeout and run async automatically
n = 1e7;
inside = 0;
for i = 1:n
if rand()^2 + rand()^2 <= 1
inside = inside + 1;
end
% Report progress every 1M trials
if mod(i, 1e6) == 0
mcp_progress(__mcp_job_id__, i/n*100, ...
sprintf('Trial %d/%d (π ≈ %.6f)', i, n, 4*inside/i));
end
end
pi_estimate = 4 * inside / n;
fprintf('\nFinal estimate: π ≈ %.8f\n', pi_estimate);Agent sees in real time:
- Job ID:
job_abc123 - Progress updates: "Trial 1000000/10000000 (π ≈ 3.141592) — 10%"
- Progress updates: "Trial 5000000/10000000 (π ≈ 3.141592) — 50%"
- Job completion with final result
Ask your agent: "Compute the SVD of a large random matrix with progress reporting"
% Large matrix SVD can take several seconds
A = rand(5000, 5000);
mcp_progress(__mcp_job_id__, 0, 'Computing SVD of 5000×5000 matrix...');
tic;
[U, S, V] = svd(A);
elapsed = toc;
mcp_progress(__mcp_job_id__, 100, ...
sprintf('SVD complete in %.2f seconds', elapsed));
fprintf('Singular values: min=%.6e, max=%.6e\n', min(diag(S)), max(diag(S)));Ask your agent: "Solve a large sparse linear system iteratively"
% Set up a sparse system
n = 10000;
A = sprand(n, n, 0.001) + speye(n) * 10; % Sparse + diagonal dominant
b = rand(n, 1);
% Iterative solver with progress callback
mcp_progress(__mcp_job_id__, 0, 'Starting BiCG solver...');
x = zeros(n, 1);
[x, flag, relres, iter] = bicg(A, b, 1e-6, 100);
mcp_progress(__mcp_job_id__, 100, ...
sprintf('Converged in %d iterations (residual: %.2e)', iter, relres));
if flag == 0
fprintf('Solution converged.\n');
else
fprintf('Solver did not converge.\n');
endThe server maintains a per-session temporary directory. Agents can upload data, generate files, and read results back.
Ask your agent: "Show me the MATLAB script you just created"
The agent calls the read_script tool:
read_script(filename="analysis.m")
The server returns the .m file as plain text, which the agent displays inline.
Ask your agent: "What variables are in the results.mat file?"
The agent calls the read_data tool:
read_data(filename="results.mat", format="summary")
The server returns a summary table of variable names, types, and sizes via MATLAB's whos command.
Ask your agent: "Get the actual data from output.csv"
read_data(filename="output.csv", format="raw")
The server returns the file as base64-encoded text that the agent can decode.
Ask your agent: "Show me the plot you just generated"
The agent calls the read_image tool:
read_image(filename="my_plot.png")
The server returns the PNG as a base64 string embedded in the response. The agent's UI renders it inline — visible immediately in Claude Desktop, Cursor, or any MCP-compatible IDE.
Supported formats: .png, .jpg, .jpeg, .gif
Ask your agent: "What toolboxes do I have installed?"
The agent calls the list_toolboxes tool, and the server responds with:
MATLAB (R2024a)
Symbolic Math Toolbox
Signal Processing Toolbox
Statistics and Machine Learning Toolbox
Ask your agent: "Show me what functions are in the Signal Processing Toolbox"
The agent calls the list_functions tool:
list_functions(toolbox="signal")
The server returns a list of available functions like fft, filter, spectrogram, etc.
Ask your agent: "How do I use the fft function?"
The agent calls the get_help tool:
get_help(function="fft")
The server returns MATLAB's built-in help text.
Ask your agent: "Check this code for style issues"
x=1;y=2;z=3;
result=x+y+z;
disp(result)The agent calls the check_code tool, and the server responds with:
{
"issues": [
{
"line": 1,
"column": 1,
"message": "Constant assignment",
"severity": "warning"
},
{
"line": 1,
"column": 8,
"message": "Operator padding",
"severity": "info"
}
],
"error_count": 0,
"warning_count": 1,
"info_count": 1
}graph TD
A["AI Agent"] -->|"stdio or HTTP"| B["MATLAB MCP Server"]
B --> C["Engine Pool"]
C -->|"eval(code)"| D["MATLAB Engine"]
B --> E["Session Manager"]
E --> F["Per-User Temp Dir"]
B --> G["Monitoring"]
G --> H["SQLite Metrics"]
Use case: You, locally, testing MATLAB code via Claude Desktop or Cursor.
Configuration:
server:
transport: "stdio"
log_level: "info"
pool:
min_engines: 1
max_engines: 2
execution:
sync_timeout: 30Start: matlab-mcp
No network, no auth, full MATLAB output in your IDE.
Use case: Shared server for a team of researchers; each user gets workspace isolation; admin wants monitoring.
Configuration:
server:
transport: "streamablehttp"
host: "127.0.0.1"
port: 8765
log_level: "info"
pool:
min_engines: 4
max_engines: 16
health_check_interval: 60
execution:
sync_timeout: 60
async_poll_interval: 2
security:
blocked_functions:
- "system"
- "eval"
- "!"
sessions:
max_sessions: 20
idle_timeout: 3600
monitoring:
enabled: trueStart: matlab-mcp --generate-token to create a token, then set MATLAB_MCP_AUTH_TOKEN=<token> and run the server. Each agent connects with the same token.
Dashboard: Visit http://127.0.0.1:8766/dashboard to monitor pool health, active jobs, and error rates.
Use case: Production deployment with multiple server instances; agents connect via a corporate proxy with TLS.
Configuration:
server:
transport: "streamablehttp"
host: "127.0.0.1" # Listen only on localhost
port: 8765
stateless_http: true # No sticky sessions needed
pool:
min_engines: 8
max_engines: 32
sessions:
max_sessions: 100Proxy setup (Nginx example):
upstream mcp_backend {
server localhost:8765;
server localhost:8765; # Multiple instances
}
server {
listen 443 ssl;
server_name matlab-mcp.example.com;
location / {
proxy_pass http://mcp_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Authorization $http_authorization;
}
}Each agent connects to https://matlab-mcp.example.com/mcp with bearer token auth. Nginx distributes requests round-robin; stateless HTTP mode means any instance can handle any request.
For sensitive operations, require a human to review code before execution.
Ask your agent: "I need to clear all variables and load a large dataset"
The agent submits the code, and the server:
- Detects a "protected" function (
clear all) - Pauses execution
- Sends an approval request to your configured UI/Slack/email
- Waits for human decision
- If approved, executes the code
- If declined, returns an error to the agent
Configuration:
hitl:
enabled: true
approval_required_for:
- "protected_functions" # Requires approval for functions like clear, rmdir, etc.
- "all_execute" # Requires approval for ALL code execution
file_approval_required: true # Requires approval for file upload/deleteSee docs/Security.md for details.
- Configuration Reference — All YAML options
- MCP Tools Reference — Complete tool signatures
- Architecture — How the server is structured
- Async Jobs — Long-running execution patterns