Skip to content

Examples

github-actions[bot] edited this page Apr 3, 2026 · 20 revisions

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
Loading

Prerequisites

Before running examples, ensure:

  • Python 3.10+ installed
  • MATLAB R2022b+ with Engine API (pip install matlab.engine from MATLAB installation)
  • Server running:
    matlab-mcp                    # stdio (single-user)
    matlab-mcp --transport sse    # multi-user

Basic Computations

Example 1: Linear Algebra

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_workspace tool
  • Server uses whos to inspect workspace

Example 2: Statistics and Distributions

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.


Plotting & Visualization

All plots are automatically converted to interactive Plotly JSON. Agents can click, zoom, and hover over data points.

Example 3: Trigonometric Functions

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

Example 4: 3D Surface Plot

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)


Example 5: Subplots with Different Plot Types

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


Signal Processing

Example 6: FFT Analysis

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

Long-Running Async Jobs

Jobs exceeding sync_timeout (default 5 seconds) are automatically promoted to async background execution. Report progress via mcp_progress().

Example 7: Monte Carlo Simulation

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:

  1. Submit code → gets job_id immediately (e.g., job-8f2a1b7c)
  2. Poll via get_job_status(job_id="job-8f2a1b7c"):
    • "Status: RUNNING, Progress: 10%"
    • "Status: RUNNING, Progress: 50%"
    • "Status: RUNNING, Progress: 90%"
  3. Once complete, fetch results via get_job_result(job_id="job-8f2a1b7c")

Output:

Estimated π: 3.141824 (error: 0.0089%)

Example 8: Iterative Solver with Progress Reporting

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.


File Operations

Example 9: Save and Retrieve Results

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]

Example 10: Load and Process External Data

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));

Advanced: Custom Tools

Expose your own MATLAB functions as first-class MCP tools via config.yaml:

Example 11: Custom Signal Analysis Tool

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: false

File: 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');
end

Agent 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]
  }

Configuration Examples

Minimal Setup (Single User)

server:
  transport: "stdio"
  log_level: "info"

pool:
  min_engines: 1
  max_engines: 2

execution:
  sync_timeout: 5
  max_output_size_bytes: 1048576

Multi-User Production Setup

server:
  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: 7

Common Patterns

Pattern 1: Experiment with Variables

Agent: "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');

Pattern 2: Conditional Execution

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);
end

Troubleshooting Examples

Issue: Code Takes Too Long

Symptom: 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
end

Issue: Plot Doesn't Render

Symptom: 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 it

Issue: Large Data Result

Symptom: "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.

Clone this wiki locally