-
Notifications
You must be signed in to change notification settings - Fork 0
Examples
This page demonstrates practical, real-world usage of the MATLAB MCP Server across different languages and complexity levels.
graph LR
A["AI Agent<br/>(Claude, Cursor, Codex)"]
A -->|MCP Protocol| B["MATLAB MCP Server"]
B -->|execute_code| C["Engine Pool<br/>(2-16 engines)"]
C -->|MATLAB API| D["MATLAB Runtime"]
D -->|Results| E["Output Formatting<br/>(text, plots, files)"]
E -->|JSON + Images| A
Before running examples, ensure:
- Python 3.10+ installed
-
MATLAB R2022b+ with Engine API (
pip install matlab.enginefrom MATLAB installation) -
Server running:
matlab-mcp # stdio (single-user) matlab-mcp --transport sse # multi-user
What it demonstrates: Synchronous execution, variable inspection, simple math
Agent request: "Calculate the eigenvalues of this matrix: 4, -2], [1, 1"
A = [4, -2; 1, 1];
eigenvalues = eig(A);
disp(eigenvalues);Expected output:
3.0000
2.0000
Key concepts:
- Fast computation (< sync_timeout) returns inline
- Variables auto-captured via
get_workspacetool - Server uses
whosto inspect workspace
What it demonstrates: Generating synthetic data, statistical analysis
Agent request: "Generate 10,000 samples from a normal distribution and show me the mean, std, and a histogram"
% Generate samples
mu = 100;
sigma = 15;
samples = mu + sigma * randn(10000, 1);
% Compute statistics
fprintf('Mean: %.4f\n', mean(samples));
fprintf('Std Dev: %.4f\n', std(samples));
fprintf('Min: %.4f\n', min(samples));
fprintf('Max: %.4f\n', max(samples));
% Create histogram
histogram(samples, 50);
xlabel('Value');
ylabel('Frequency');
title('Normal Distribution (μ=100, σ=15)');
grid on;Expected output:
Mean: 99.8542
Std Dev: 15.0234
Min: 51.3421
Max: 148.9876
Plus an interactive Plotly histogram.
All plots are automatically converted to interactive Plotly JSON. Agents can click, zoom, and hover over data points.
What it demonstrates: Multi-line plots, legend, axis labels (auto-converted to Plotly)
Agent request: "Plot sin(x), cos(x), and tan(x) from -π to π"
x = linspace(-pi, pi, 200);
figure;
plot(x, sin(x), 'r-', 'LineWidth', 2, 'DisplayName', 'sin(x)');
hold on;
plot(x, cos(x), 'b--', 'LineWidth', 2, 'DisplayName', 'cos(x)');
plot(x, tan(x), 'g-.', 'LineWidth', 2, 'DisplayName', 'tan(x)');
xlabel('x (radians)');
ylabel('y');
title('Trigonometric Functions');
legend('Location', 'northeast');
grid on;
ylim([-5, 5]);Output: Interactive Plotly chart with:
- Red solid line for sin
- Blue dashed line for cos
- Green dash-dot line for tan
- Hoverable legend entries
- Click-to-zoom interactivity
What it demonstrates: 3D visualization, colormap, interactive rendering
Agent request: "Show me a 3D surface plot of z = x²y - xy² from -3 to 3"
[X, Y] = meshgrid(-3:0.2:3, -3:0.2:3);
Z = X.^2 .* Y - X .* Y.^2;
figure;
surf(X, Y, Z, 'EdgeColor', 'none');
colorbar;
shading interp;
xlabel('x');
ylabel('y');
zlabel('z');
title('Saddle Surface: x²y - xy²');Output: Interactive 3D surface (rotatable via mouse drag, zoomable, rotatable)
What it demonstrates: Subplot layout (2×2 grid), mixed plot types (line, scatter, bar, heatmap)
Agent request: "Create a 2×2 subplot showing different data visualization types"
figure('Position', [100, 100, 1000, 800]);
% Subplot 1: Line plot
subplot(2, 2, 1);
x = linspace(0, 10, 100);
plot(x, exp(-x/5) .* sin(x), 'LineWidth', 2);
title('Damped Oscillation');
grid on;
% Subplot 2: Scatter plot
subplot(2, 2, 2);
scatter(randn(100, 1), randn(100, 1), 50, 'filled');
title('Random Scatter');
grid on;
% Subplot 3: Bar chart
subplot(2, 2, 3);
categories = {'A', 'B', 'C', 'D', 'E'};
values = [45, 82, 61, 73, 88];
bar(categories, values);
title('Category Comparison');
ylabel('Value');
% Subplot 4: Heatmap
subplot(2, 2, 4);
data = [1, 2, 3; 4, 5, 6; 7, 8, 9];
imagesc(data);
colorbar;
title('Heatmap Example');Output: 2×2 grid of interactive Plotly subplots, each independently zoomable
What it demonstrates: Frequency-domain analysis, complex numbers, windowing
Agent request: "Generate a 5-component signal (10Hz, 50Hz, 100Hz, 200Hz, plus noise) and show me its FFT"
fs = 1000; % Sample rate
t = 0:1/fs:1; % 1 second
% Generate multi-frequency signal
signal = sin(2*pi*10*t) ...
+ 0.5*sin(2*pi*50*t) ...
+ 0.3*sin(2*pi*100*t) ...
+ 0.2*sin(2*pi*200*t) ...
+ 0.1*randn(size(t));
% Compute FFT
N = length(signal);
Y = fft(signal);
P = abs(Y(1:N/2)).^2 / N;
f = (0:N/2-1) * fs / N;
% Plot results
figure('Position', [100, 100, 1200, 500]);
subplot(1, 2, 1);
plot(t, signal);
xlabel('Time (s)');
ylabel('Amplitude');
title('Time Domain');
grid on;
subplot(1, 2, 2);
semilogy(f, P);
xlabel('Frequency (Hz)');
ylabel('Power');
title('Power Spectral Density (log scale)');
xlim([0, 300]);
grid on;Output:
- Left subplot: noisy multi-frequency signal
- Right subplot: log-scale power spectrum showing 4 peaks at 10, 50, 100, 200 Hz
Jobs exceeding sync_timeout (default 5 seconds) are automatically promoted to async background execution. Report progress via mcp_progress().
What it demonstrates: Async execution, progress reporting, job polling
Agent request: "Estimate π using a 2-million-point Monte Carlo simulation with progress updates"
num_trials = 2e6;
inside_circle = 0;
for i = 1:num_trials
x = rand();
y = rand();
if x^2 + y^2 <= 1
inside_circle = inside_circle + 1;
end
% Report progress every 200k trials
if mod(i, 2e5) == 0
percentage = (i / num_trials) * 100;
mcp_progress(__mcp_job_id__, percentage, ...
sprintf('Completed %d/%d trials', i, num_trials));
end
end
pi_estimate = 4 * inside_circle / num_trials;
fprintf('Estimated π: %.6f (error: %.4f%%)\n', ...
pi_estimate, abs(pi_estimate - pi) / pi * 100);Agent workflow:
- Submit code → gets job_id immediately (e.g.,
job-8f2a1b7c) - Poll via
get_job_status(job_id="job-8f2a1b7c"):- "Status: RUNNING, Progress: 10%"
- "Status: RUNNING, Progress: 50%"
- "Status: RUNNING, Progress: 90%"
- Once complete, fetch results via
get_job_result(job_id="job-8f2a1b7c")
Output:
Estimated π: 3.141824 (error: 0.0089%)
What it demonstrates: Long computation, iterative updates, convergence tracking
Agent request: "Solve a large linear system iteratively and show convergence"
n = 5000;
A = diag(10*ones(n, 1)) + diag(ones(n-1, 1), 1) + diag(ones(n-1, 1), -1);
b = ones(n, 1);
% Conjugate Gradient solver (MATLAB's pcg)
x = zeros(n, 1);
tol = 1e-6;
max_iter = 1000;
residuals = [];
for iter = 1:max_iter
r = b - A*x;
residual_norm = norm(r);
residuals = [residuals; residual_norm];
if residual_norm < tol
fprintf('Converged in %d iterations\n', iter);
break;
end
if iter == 1
p = r;
else
beta = (residual_norm^2) / (residuals(end-1)^2);
p = r + beta*p;
end
Ap = A*p;
alpha = (residual_norm^2) / (p' * Ap);
x = x + alpha*p;
if mod(iter, 50) == 0
mcp_progress(__mcp_job_id__, min(iter/max_iter*100, 99), ...
sprintf('Iteration %d: residual = %.2e', iter, residual_norm));
end
end
semilogy(1:length(residuals), residuals);
xlabel('Iteration');
ylabel('Residual Norm');
title('CG Solver Convergence');
grid on;Output:
Converged in 312 iterations
Plus a log-scale plot showing exponential convergence.
What it demonstrates: File I/O, matrix export, reading back data
Agent request: "Generate a random dataset, save it as CSV and MAT files, then verify what was saved"
% Generate synthetic dataset
n = 1000;
data = struct();
data.time = (1:n)';
data.signal = sin(2*pi*(1:n)'/100) + 0.1*randn(n, 1);
data.control = ones(n, 1);
% Save as MAT file
save(fullfile(__mcp_temp_dir__, 'data.mat'), '-struct', 'data');
% Save as CSV
csv_data = [data.time, data.signal, data.control];
writematrix(csv_data, fullfile(__mcp_temp_dir__, 'data.csv'));
fprintf('Files saved to: %s\n', __mcp_temp_dir__);
disp('Available files:');
ls(__mcp_temp_dir__);The agent can then call:
read_data(filename="data.mat", format="summary")
→ Variables: time (1000×1 double), signal (1000×1 double), control (1000×1 double)
read_data(filename="data.csv", format="summary")
→ [CSV preview with first 10 rows]
Agent uploads a CSV file, then requests: "Load the CSV file I just uploaded and compute summary statistics"
% Assume file was uploaded to __mcp_temp_dir__
csv_path = fullfile(__mcp_temp_dir__, 'mydata.csv');
data = readmatrix(csv_path);
fprintf('Dataset Shape: %d × %d\n', size(data));
fprintf('Column Means:\n');
disp(mean(data, 1));
fprintf('Column Std Devs:\n');
disp(std(data, 1));
fprintf('Min/Max per column:\n');
fprintf(' Min: '); disp(min(data, [], 1));
fprintf(' Max: '); disp(max(data, [], 1));Expose your own MATLAB functions as first-class MCP tools via config.yaml:
File: config.yaml
custom_tools:
- name: "analyze_signal"
matlab_function: "my_signal_analysis"
description: "Analyze a signal: compute FFT, power spectrum, and key frequencies"
parameters:
- name: "signal"
type: "array"
description: "Input signal vector"
required: true
- name: "fs"
type: "number"
description: "Sampling frequency (Hz)"
required: true
default: 1000
- name: "freq_bands"
type: "string"
description: "Comma-separated frequency bands to extract (e.g., '10-20,50-100')"
required: falseFile: my_signal_analysis.m (in MATLAB path)
function [fft_result, power_spectrum, dominant_freqs] = ...
my_signal_analysis(signal, fs, freq_bands)
N = length(signal);
Y = fft(signal);
P = abs(Y(1:N/2)).^2 / N;
freqs = (0:N/2-1) * fs / N;
% Dominant frequencies
[~, idx] = sort(P, 'descend');
dominant_freqs = freqs(idx(1:min(5, length(idx))));
fft_result = struct('frequencies', freqs', 'magnitude', abs(Y(1:N/2))');
power_spectrum = struct('frequencies', freqs', 'power', P');
endAgent usage:
analyze_signal(
signal=[0.1, 0.2, 0.15, ...],
fs=1000,
freq_bands="10-20,50-100"
)
→ {
fft_result: {frequencies: [...], magnitude: [...]},
power_spectrum: {frequencies: [...], power: [...]},
dominant_freqs: [45.3, 98.7, 12.1, 5.2, 0.8]
}
server:
transport: "stdio"
log_level: "info"
pool:
min_engines: 1
max_engines: 2
execution:
sync_timeout: 5
max_output_size_bytes: 1048576server:
transport: "sse"
host: "127.0.0.1"
port: 8765
pool:
min_engines: 4
max_engines: 16
startup_timeout: 60
execution:
sync_timeout: 10
async_job_timeout: 3600
security:
require_proxy_auth: true
blocked_functions:
- "system"
- "unix"
- "dos"
- "!eval"
sessions:
max_sessions: 50
idle_timeout: 1800
monitoring:
enabled: true
db_path: "/var/lib/matlab-mcp/metrics.db"
retention_days: 7Agent: "Try different values of lambda and show me the results"
lambdas = [0.1, 1, 10, 100];
results = [];
for lambda = lambdas
% Your experiment here
result = exp(-lambda * (1:100));
results = [results; result];
end
imagesc(results);
colorbar;
xlabel('Parameter');
ylabel('Lambda Value');
title('Sensitivity Analysis');Agent: "Check if the data is normally distributed, then apply either a parametric or non-parametric test"
data = randn(100, 1);
% Normality test
[h, p_value] = kstest((data - mean(data)) / std(data));
if h == 0 % Normal
[t_stat, p_test] = ttest(data);
fprintf('t-test p-value: %.4f\n', p_test);
else % Non-normal
p_test = ranksum(data, zeros(size(data)));
fprintf('Wilcoxon p-value: %.4f\n', p_test);
endSymptom: Agent says "Job submitted, job_id: job-xyz" but never completes
Fix: Add progress reporting every 10% of iterations:
for i = 1:1000000
% ... computation ...
if mod(i, 100000) == 0
mcp_progress(__mcp_job_id__, (i/1000000)*100, ...
sprintf('%d/%d', i, 1000000));
end
endSymptom: Figure created but shows blank
Fix: Ensure figure is visible and has data:
figure;
plot([1, 2, 3], [1, 4, 9], 'o-'); % Must have data
xlabel('x');
ylabel('y');
title('My Plot');
grid on;
% Don't close the figure — server captures itSymptom: "Result truncated" message
Fix: Save to file instead:
% Instead of disp(huge_matrix)
save(fullfile(__mcp_temp_dir__, 'results.mat'), 'huge_matrix');
fprintf('Results saved. Use read_data to retrieve.\n');See Configuration for detailed server setup and MCP-Tools-Reference for all available tools.