Skip to content

Examples

github-actions[bot] edited this page Mar 23, 2026 · 20 revisions

Examples

Ready-to-run examples are in the examples/ directory. You don't run these directly—ask your AI agent to execute them through the MCP server!

Basic MATLAB Operations

Simple Calculations

"Calculate the eigenvalues of a 3×3 magic square"

A = magic(3);
eigenvalues = eig(A);
disp(eigenvalues);

What this demonstrates: Basic matrix creation, function calls, and output display. The server captures the disp output and returns it to the agent.


Matrix Operations and Linear Algebra

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

What this demonstrates: Matrix multiplication, built-in functions (trace), and formatted output with fprintf.


Solving Linear Systems

"Solve this 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('Solution:');
disp(x);

What this demonstrates: The backslash operator for linear system solving, matrix construction, and solution display.


Basic Statistics

"Generate 1000 random samples and compute mean, std, and quantiles"

data = randn(1000, 1);
fprintf('Mean: %.4f\n', mean(data));
fprintf('Std: %.4f\n', std(data));
fprintf('Median: %.4f\n', median(data));
fprintf('IQR: %.4f\n', iqr(data));

What this demonstrates: Statistical functions and formatted numerical output.


String Operations and Tables

"Create a table with names and ages, then display it"

names = {'Alice'; 'Bob'; 'Charlie'};
ages = [28; 35; 42];
scores = [92.5; 87.3; 95.1];

T = table(ages, scores, 'RowNames', names);
disp(T);

What this demonstrates: Table creation, array operations, and structured data display.


Plotting and Visualization

All figures are automatically converted to interactive Plotly JSON and static PNG thumbnails.

Line Plot

"Plot sin(x) from 0 to 2π with labels and grid"

x = linspace(0, 2*pi, 200);
y = sin(x);
plot(x, y, 'LineWidth', 2);
xlabel('x'); 
ylabel('sin(x)');
title('Sine Wave');
grid on;

What this demonstrates: Basic 2D line plotting with styling, labels, and grid. The server automatically captures and converts to Plotly.


Scatter Plot with Customization

"Create a scatter plot of 100 random points colored by distance from origin"

N = 100;
x = randn(N, 1);
y = randn(N, 1);
d = sqrt(x.^2 + y.^2);
scatter(x, y, 50, d, 'filled');
colorbar;
title('Random Points Colored by Distance');
xlabel('X'); ylabel('Y');

What this demonstrates: Scatter plots with color mapping and colorbars.


3D Surface Plot

"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');
xlabel('X'); ylabel('Y'); zlabel('Z');

What this demonstrates: 3D surface visualization with interpolated shading and colorbars.


Bar Chart

"Compare sales data across quarters"

quarters = {'Q1', 'Q2', 'Q3', 'Q4'};
sales = [150000, 175000, 200000, 225000];
bar(categorical(quarters), sales, 'FaceColor', '#2E86AB');
ylabel('Sales ($)');
title('Quarterly Sales');
grid on;

What this demonstrates: Bar charts with categorical data and color customization.


Histogram

"Show the distribution of 10,000 normally distributed samples"

data = randn(10000, 1);
histogram(data, 50, 'EdgeColor', 'black', 'FaceColor', '#A23B72');
title('Normal Distribution');
xlabel('Value');
ylabel('Frequency');

What this demonstrates: Histograms with bin control and styling.


Multiple Subplots

"Plot 4 different frequency sine waves side-by-side"

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)));
    xlabel('Time (s)');
    ylabel('Amplitude');
end
sgtitle('Sine Waves at Different Frequencies');

What this demonstrates: Subplot layouts with multiple axes, automatic Plotly conversion preserves subplot structure.


Heatmap

"Display a correlation matrix as a heatmap"

% Generate sample data
data = randn(100, 5);
corr_matrix = corrcoef(data);

% Create heatmap
imagesc(corr_matrix);
colorbar;
colormap jet;
title('Correlation Matrix');
set(gca, 'XTick', 1:5, 'YTick', 1:5);
set(gca, 'XTickLabel', {'A', 'B', 'C', 'D', 'E'});
set(gca, 'YTickLabel', {'A', 'B', 'C', 'D', 'E'});

What this demonstrates: Image-based heatmaps with colormaps and labeled axes.


Signal Processing

FFT Analysis

"Generate a noisy 440Hz signal, compute its FFT, and show both time and frequency domains"

fs = 8000;           % Sample rate
duration = 0.1;      % 100 ms
t = 0:1/fs:duration;

% Signal: 440Hz sine + noise
signal = sin(2*pi*440*t) + 0.3*randn(size(t));

% 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: 440Hz Signal + Noise');
xlabel('Time (ms)'); ylabel('Amplitude');

% Plot frequency domain
subplot(2, 1, 2);
plot(f(1:N/2), abs(Y(1:N/2))/N, 'r', 'LineWidth', 1);
title('Frequency Domain: FFT Magnitude');
xlabel('Frequency (Hz)'); ylabel('Magnitude');
xlim([0, 2000]);

Prerequisites: Basic signal processing knowledge. The FFT is automatically computed and visualized.

What this demonstrates: Frequency-domain analysis, subplot layouts with different plot types.


Butterworth Filter Design and Application

"Design a 4th-order lowpass Butterworth filter at 1000 Hz and filter a signal"

fs = 8000;           % Sample rate
fc = 1000;           % Cutoff frequency
order = 4;

% Design filter (requires Signal Processing Toolbox)
[b, a] = butter(order, fc/(fs/2));

% Generate test signal: 440Hz + 3000Hz
t = 0:1/fs:0.5;
signal = sin(2*pi*440*t) + 0.5*sin(2*pi*3000*t);

% Apply filter
filtered = filter(b, a, signal);

% Plot
subplot(2, 1, 1);
plot(t, signal); title('Original Signal');
subplot(2, 1, 2);
plot(t, filtered); title('Filtered Signal (1kHz cutoff)');

Prerequisites: Signal Processing Toolbox must be available (add to toolbox whitelist in config).

What this demonstrates: Filter design, frequency-domain signal conditioning, signal comparison via subplots.


Spectrogram Analysis

"Compute and visualize a spectrogram of a chirp signal"

fs = 1000;
t = 0:1/fs:5;

% Chirp signal: frequency sweeps from 10Hz to 200Hz
f_start = 10;
f_end = 200;
signal = chirp(t, f_start, t(end), f_end);

% Compute spectrogram
spectrogram(signal, 256, 250, 256, fs, 'yaxis');
title('Spectrogram of Chirp Signal');
colorbar;

Prerequisites: Signal Processing Toolbox for chirp and spectrogram.

What this demonstrates: Time-frequency analysis, visualization of signal evolution over time.


Async Jobs and Long-Running Computations

Jobs exceeding sync_timeout (default 30 seconds) are automatically promoted to async background execution. Use the mcp_progress() helper to report progress.

sequenceDiagram
    participant Agent as AI Agent
    participant Server as MCP Server
    participant Engine as MATLAB Engine
    
    Agent->>Server: execute_code(code)
    Server->>Engine: Start background job
    Server-->>Agent: status="pending", job_id="abc123"
    
    loop Progress polling
        Agent->>Server: get_job_status(job_id)
        Server->>Engine: Read progress file
        Server-->>Agent: status="running", progress=45%
    end
    
    Engine->>Engine: Completes
    Agent->>Server: get_job_status(job_id)
    Server-->>Agent: status="completed", result={...}
Loading

Monte Carlo Pi Estimation with Progress Reporting

"Estimate π using Monte Carlo with 1 million trials, showing progress updates every 100k trials"

n_trials = 1e6;
inside_circle = 0;

for i = 1:n_trials
    % Generate random point in [0,1]²
    x = rand();
    y = rand();
    
    % Check if inside unit circle
    if sqrt(x^2 + y^2) <= 1
        inside_circle = inside_circle + 1;
    end
    
    % Report progress every 100k trials
    if mod(i, 1e5) == 0
        pct = (i / n_trials) * 100;
        msg = sprintf('Trials: %d / %d', i, n_trials);
        mcp_progress(__mcp_job_id__, pct, msg);
    end
end

% Final estimate
pi_estimate = 4 * inside_circle / n_trials;
fprintf('π ≈ %.6f (error: %.6f)\n', pi_estimate, abs(pi_estimate - pi));

Expected runtime: ~5–10 seconds depending on system. Auto-promoted to async on timeout.

Progress updates visible to agent:

  • "Trials: 100000 / 1000000" (10%)
  • "Trials: 500000 / 1000000" (50%)
  • "Trials: 1000000 / 1000000" (100%)

Large Matrix SVD Decomposition

"Compute SVD of a 5000×5000 random matrix and report progress"

n = 5000;
fprintf('Generating %d x %d random matrix...\n', n, n);
A = randn(n, n);

fprintf('Computing SVD...\n');
mcp_progress(__mcp_job_id__, 0, 'SVD: Initializing...');

[U, S, V] = svd(A);

fprintf('SVD complete.\n');
fprintf('Condition number: %.2e\n', S(1) / S(n));
fprintf('Singular value range: [%.2e, %.2e]\n', S(n), S(1));

mcp_progress(__mcp_job_id__, 100, 'SVD complete');

Expected runtime: ~15–30 seconds depending on system resources.

What this demonstrates: Memory-intensive computation, progress reporting for long operations.


Iterative Solver with Convergence Tracking

"Solve Ax=b using conjugate gradient with convergence monitoring"

n = 1000;
A = sprand(n, n, 0.01);
A = A * A';           % Make symmetric positive definite
b = rand(n, 1);

mcp_progress(__mcp_job_id__, 0, 'CG Solver: Starting');

% Conjugate gradient
x = zeros(n, 1);
r = b - A*x;
p = r;
rsold = r' * r;

max_iters = min(n, 200);
for i = 1:max_iters
    Ap = A * p;
    alpha = rsold / (p' * Ap);
    x = x + alpha * p;
    r = r - alpha * Ap;
    rsnew = r' * r;
    
    if mod(i, 10) == 0
        residual = sqrt(rsnew);
        pct = (i / max_iters) * 100;
        msg = sprintf('Iter %d: residual=%.2e', i, residual);
        mcp_progress(__mcp_job_id__, pct, msg);
    end
    
    if sqrt(rsnew) < 1e-8
        fprintf('Converged in %d iterations\n', i);
        break;
    end
    
    beta = rsnew / rsold;
    p = r + beta * p;
    rsold = rsnew;
end

fprintf('Final residual: %.2e\n', sqrt(rsnew));

What this demonstrates: Iterative numerical algorithms with per-iteration progress reporting.


File Operations

The server provides tools to upload and download files. These reside in the session's isolated temp directory.

Reading a MATLAB Script

The agent calls:

read_script(filename="my_analysis.m")

Returns the .m file content as inline text.


Reading Data File Summary

To inspect a .mat file without downloading raw bytes:

read_data(filename="results.mat", format="summary")

Returns variable names, sizes, and types via MATLAB whos:

Name              Size            Bytes  Class
==================================================
output_signal    1000x1            8000  double
timestamps       1000x1            8000  double
metadata         1x1              1024  struct

Reading CSV Data

read_data(filename="output.csv", format="summary")

Returns the CSV content as inline text:

Time,Temperature,Pressure
0.0,20.1,101.3
0.1,20.2,101.4
0.2,20.3,101.5

Viewing Generated Images

The agent calls:

read_image(filename="result_plot.png")

Returns the image as an inline content block that renders directly in agent UIs (Claude Desktop, Cursor, etc.).

Supported formats: .png, .jpg, .gif


Configuration Examples

Minimal Single-User Setup

For development or personal use with stdio transport:

# config_minimal.yaml
server:
  name: "matlab-mcp-dev"
  transport: "stdio"
  log_level: "debug"

pool:
  min_engines: 1
  max_engines: 2
  health_check_interval: 30

execution:
  sync_timeout: 30
  max_execution_time: 3600

security:
  blocked_functions_enabled: true

Start the server:

matlab-mcp --config examples/config_minimal.yaml

Multi-User Team Deployment

For shared server with multiple team members:

# config_multiuser.yaml
server:
  name: "matlab-mcp-team"
  transport: "sse"
  host: "127.0.0.1"
  port: 8765
  log_level: "info"

pool:
  min_engines: 4
  max_engines: 16
  scale_down_idle_timeout: 1800
  health_check_interval: 30

execution:
  sync_timeout: 30
  max_execution_time: 86400
  workspace_isolation: true

security:
  blocked_functions_enabled: true
  require_proxy_auth: true
  max_upload_size_mb: 500

sessions:
  max_sessions: 100
  session_timeout: 7200
  job_retention_seconds: 172800  # 2 days

monitoring:
  enabled: true
  sample_interval: 10
  retention_days: 30
  dashboard_enabled: true

Deploy behind nginx reverse proxy with OAuth:

upstream matlab_mcp {
    server 127.0.0.1:8765;
}

server {
    listen 443 ssl;
    server_name matlab-mcp.company.com;
    
    ssl_certificate /etc/ssl/certs/server.crt;
    ssl_certificate_key /etc/ssl/private/server.key;
    
    # OAuth2 Proxy authentication
    auth_request /oauth2/auth;
    error_page 401 = /oauth2/sign_in;
    
    location / {
        proxy_pass http://matlab_mcp;
        proxy_http_version 1.1;
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
    }
}

Custom Tools Example

Define your own MATLAB functions as first-class MCP tools in custom_tools.yaml:

# custom_tools.yaml

tools:
  - name: "signal_analysis"
    function_name: "my_signal_analysis"
    description: "Analyze a signal and return spectral features"
    parameters:
      - name: "signal"
        type: "list"
        description: "Signal samples as array of floats"
        required: true
      - name: "fs"
        type: "float"
        description: "Sampling frequency (Hz)"
        default: 1000
    returns:
      description: "Dict with peak_frequency, snr, spectral_entropy"

  - name: "image_processing"
    function_name: "process_image_custom"
    description: "Apply custom image filters"
    parameters:
      - name: "image_path"
        type: "string"
        description: "Path to image file"
        required: true
      - name: "filter_type"
        type: "string"
        description: "gaussian, median, or laplacian"
        default: "gaussian"
    returns:
      description: "Base64-encoded filtered image"

Then the agent can call:

signal_analysis(signal=[1.0, 2.0, 3.0, ...], fs=8000)

Architecture Overview

graph TB
    Agent["AI Agent<br/>(Claude, Cursor)"]
    
    Agent -->|stdio or SSE| FastMCP["FastMCP Server<br/>(MCP Protocol Handler)"]
    
    FastMCP --> ToolRouter["Tool Router<br/>(20 Built-in + Custom)"]
    
    ToolRouter -->|Code Execution| Executor["Job Executor"]
    ToolRouter -->|File Ops| FileTools["File Tools<br/>(upload/download/list)"]
    ToolRouter -->|Discovery| Discovery["Discovery Tools<br/>(list toolboxes/functions)"]
    ToolRouter -->|Admin| Admin["Admin Tools<br/>(pool status, health)"]
    
    Executor --> Validator["Security Validator<br/>(Blocklist Check)"]
    Validator --> Pool["Engine Pool Manager<br/>(Min/Max Scaling)"]
    
    Pool -->|Acquire/Release| Engine1["MATLAB Engine<br/>Instance 1"]
    Pool -->|Acquire/Release| Engine2["MATLAB Engine<br/>Instance 2"]
    Pool -->|Acquire/Release| EngineN["MATLAB Engine<br/>Instance N"]
    
    Executor --> Tracker["Job Tracker<br/>(Status, Progress)"]
    Executor --> Formatter["Result Formatter<br/>(Text, JSON, Files)"]
    Executor --> Plotly["Plotly Converter<br/>(Figures → Interactive JSON)"]
    
    Agent -->|Poll Progress| Tracker
    Agent -->|Read Results| Formatter
    
    Formatter -->|Optional| Monitoring["Metrics & Health<br/>(Collector, Store, Dashboard)"]
Loading

Agent Workflow Example

sequenceDiagram
    participant Claude as Claude (AI Agent)
    participant MCP as MCP Server
    participant Validator as Security Validator
    participant Pool as Engine Pool
    participant MATLAB as MATLAB Engine
    participant Tracker as Job Tracker
    
    Claude->>MCP: execute_code("x = rand(5)")
    MCP->>Validator: check_code("x = rand(5)")
    Validator-->>MCP: OK (not blocked)
    MCP->>Pool: acquire()
    Pool-->>MCP: engine_1
    MCP->>MATLAB: eval("x = rand(5)")
    MATLAB-->>MCP: ans = [0.4 0.6 ... ]
    MCP->>Tracker: create_job("code", result)
    MCP-->>Claude: {status: "completed", output: "..."}
    
    Claude->>MCP: execute_code("long_running_code")
    MCP->>Pool: acquire()
    Pool-->>MCP: engine_2
    MCP->>MATLAB: eval(..., background=True)
    MCP->>Tracker: create_job("pending")
    MCP-->>Claude: {status: "pending", job_id: "abc123"}
    
    loop Progress Polling
        Claude->>MCP: get_job_status("abc123")
        MCP->>Tracker: lookup("abc123")
        Tracker-->>MCP: {progress: 50%, message: "..."}
        MCP-->>Claude: {progress: 50%, message: "..."}
    end
    
    MATLAB->>MATLAB: (completes)
    Claude->>MCP: get_job_result("abc123")
    MCP->>Tracker: lookup("abc123")
    Tracker-->>MCP: {status: "completed", output: "..."}
    MCP-->>Claude: {output: "...", execution_time: 45.2}
Loading

Next Steps

  • Explore the Tools Reference for detailed tool parameters and responses
  • Configure Custom Tools to expose your own MATLAB libraries
  • Learn about Async Jobs for long-running computations
  • Review Security best practices for team deployments

Clone this wiki locally