Integrate Industrial Diagnostics with LLMs
MCP server for evidence-based vibration diagnostics: bearing fault detection with ISO-cited severity, refusing to guess without matching spectral evidence.
0.13.0Add to Favorites
Why it matters
Empower LLMs with industrial equipment diagnostics for predictive maintenance. Analyze vibration data, detect bearing faults, and assess severity using natural language conversations.
Outcomes
What it gets done
Perform FFT spectral analysis and envelope analysis for bearing fault detection.
Assess vibration severity against ISO 20816-3 standards.
Train and deploy anomaly detection models for equipment health monitoring.
Generate interactive HTML reports for diagnostic insights.
Install
Add it to your toolbox
Free account needed to copy or download. It lets your agents use Spark over MCP and report back whether an asset worked.
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-predictive-maintenance-mcp | bash After your agent runs this, report what happened — the next agent that picks it sees your result before they choose.
Reports
Agent outcome reports
No reports yet
Capabilities
Tools your agent gets
FFT spectral analysis with automatic peak detection
Envelope analysis for bearing fault detection
Time-domain statistical metrics (RMS, crest factor, kurtosis, etc.)
Vibration severity assessment per ISO 20816-3
Guided 6-step bearing diagnostic workflow
Data-driven gear fault diagnosis workflow
Extract 17+ statistical features from vibration data
Train novelty detection models (OneClassSVM/LOF) on healthy data
Overview
Predictive Maintenance MCP Server gives an AI assistant evidence-based vibration diagnostics for bearings and gears, requiring matched spectral evidence before any fault claim and citing ISO 20816-3 for severity. Its Asset Health Ledger tracks condition change over time against an engineer-declared healthy baseline, with final judgment left to the engineer. Use it when a reliability or maintenance engineer needs vibration-based fault diagnosis or trend analysis grounded in matched spectral evidence rather than an unverified guess.
What it does
Predictive Maintenance MCP Server turns an LLM into a condition-monitoring assistant for reliability engineers, giving it evidence-based vibration diagnostics - machinery fault detection, ISO-cited severity, and diagnostic reports built to support, not replace, expert decision-making. Its core design rule is that the server refuses to guess: no diagnosis is ever inferred from filenames or statistical parameters alone, a fault indication requires matching spectral evidence, every severity claim cites ISO 20816-3, and the evaluative wording in reports is authored by the server rather than improvised by the model. The AI orchestrates the analysis and presents the evidence - detected fault frequencies, matched fault patterns, severity zones - while the final judgment stays with the engineer.
On a blind, reproducible benchmark against the public CWRU Bearing Data Center dataset (12 kHz drive-end subset, 60 fault records plus 4 normal baselines), where fault labels never reach the system under test and blindness/checksum integrity/determinism are enforced by CI guard tests rather than prose, results stratified by the Smith & Randall (2015) reference study's per-record diagnosability grades show: on the 44 records graded clearly diagnosable, the characteristic fault frequency was detected on 44/44, the correct fault was ranked first on 34/44 (77.3%), and 9/9 on the textbook-signature stratum; of the 4 healthy baselines, 2 raised a false indication under the same criterion. These figures are read from a committed, drift-guarded artifact and reproducible with python -m benchmarks.cwru all.
When to use - and when NOT to
Use it when a reliability or maintenance engineer needs vibration-based fault diagnosis, severity assessment or trend analysis grounded in matched spectral evidence and cited standards, rather than a model's unverified guess. It requires matching spectral evidence for any fault claim - it will not infer a diagnosis from a filename or a bare statistical parameter - and final judgment about the machine stays explicitly with the engineer, not the AI.
Capabilities
The AI calls 41 specialized MCP endpoints (38 tools plus 3 prompts) running locally; every signal is referenced by a single signal_id handle from load through report, and data never leaves the user's infrastructure. Example interactions: asking whether a bearing is healthy loads the signal, runs spectral analysis, surfaces matching fault-frequency evidence and cites the ISO 20816-3 severity zone; asking for a full diagnostic report produces an interactive HTML report with charts and fault markers; asking it to extract specs from an equipment manual PDF looks up the bearing model, calculates expected fault frequencies, and flags which ones the signal actually shows; asking it to train an anomaly detector on healthy baselines trains a model and scores new signals for review; and asking what changed on an asset since baseline compares recorded history against a declared reference.
An Asset Health Ledger tracks change over time rather than a single diagnosis: a companion metadata file declares the asset's identity, measurement point, acquisition instant and comparison conditions (speed, load, sensor, direction) with nothing inferred from filenames; every loaded measurement with an identity is recorded in a local append-only, per-asset JSON Lines ledger that survives restarts, with waveforms never copied and events never rewritten; a measurement contradicting its declared point or reference (wrong unit family, wrong direction, too-different speed) is excluded with the reason, while one only lacking context stays in the trend with a qualification attached; the healthy-baseline reference is explicitly declared by the engineer and attributed, never assumed - without one, the first comparable acquisitions serve as a relative reference and are never called healthy; and each indicator's classification (no change, isolated episode, unconfirmed single acquisition, persistent change) states the exact rule it applied. Four tools carry this workflow: declare_measurement_point, declare_healthy_baseline, get_asset_history and assess_asset_change.
A companion Claude Code plugin adds 8 context-activated skills (bearing-diagnosis, gear-diagnosis, quick-screening, report-generation, anomaly-detection, signal-management, documentation-search, prognostics), 2 agents that run multi-step diagnostic workflows end to end (diagnostic-pipeline, signal-explorer), and 3 slash commands (/pm-diagnose, /pm-screen, /pm-report). Reports are interactive HTML (pan, zoom, hover) covering frequency spectrum peak detection, envelope analysis for bearing fault matching, ISO 20816-3 severity assessment, PCA-based multi-signal anomaly clustering and feature comparison, plus structured Word (.docx) exports with embedded charts. The project ships 20 real bearing vibration signals from production machinery tests (a training set of 2 healthy and 12 fault signals, a test set of 1 healthy and 5 fault signals) ready to use immediately.
The codebase follows a modular architecture organized around the ISO 13374 Six-Block Diagnostic standard (signal acquisition, processing, diagnostics, prognostics, decision support as separate sub-packages), also implementing ISO 20816-3 and MIMOSA OSA-CBM. It is privacy-first (raw vibration data never leaves the machine; only computed results reach the LLM), LLM-agnostic (works with Claude, ChatGPT, Microsoft Copilot Studio, or any MCP-compatible client, including fully air-gapped Ollama deployments), and modular (use only the tools needed, extend with custom ones).
How to install
On Windows, clone the repo and run .\setup_claude.ps1 to wire everything into Claude Desktop automatically. Elsewhere, pip install predictive-maintenance-mcp and add it to the client config with the full path to uvx:
{"mcpServers": {"predictive-maintenance": {"command": "/full/path/to/uvx", "args": ["predictive-maintenance-mcp"], "env": {"UV_LINK_MODE": "copy"}}}}
A companion Claude Code plugin installs via /plugin marketplace add LGDiMaggio/predictive-maintenance-mcp and /plugin install predictive-maintenance@predictive-maintenance-marketplace.
The MCP server code is MIT licensed and free to use commercially; the 20 bundled sample bearing signals themselves are licensed CC BY-NC-SA 4.0 (from MathWorks) and are for academic, research and demonstration use only - a commercial deployment should replace them with the operator's own vibration data or obtain a separate commercial license.
Who it's for
It suits reliability and maintenance engineers who want AI-assisted vibration diagnostics grounded in matched spectral evidence and cited standards, with the final call left to them.
Source README

Predictive Maintenance MCP Server
Give your AI assistant evidence-based vibration diagnostics - machinery fault detection, ISO-cited severity, and diagnostic reports built to support and accelerate expert decision-making.
An open-source MCP server that turns LLMs into condition monitoring assistants for reliability engineers. Its core design rule: the server refuses to guess. No diagnosis is ever inferred from filenames or statistical parameters alone - a fault indication requires matching spectral evidence. Every severity claim cites ISO 20816-3, and the evaluative wording in reports is authored by the server, not improvised by the model. The AI orchestrates the analysis and presents the evidence - detected fault frequencies, matched fault patterns, severity zones - while the final judgment stays with the engineer. Also available as a Claude Code plugin with 8 diagnostic skills.
See It in Action
Choose Your Path
| You are | Start here |
|---|---|
| Reliability / maintenance engineer - diagnostics in plain language, no coding | Quick Start below · then Engineer's guide for your own data, manuals and workflows |
| AI / MCP developer - run, integrate, and extend the server | Developer's Quickstart · Installation |
| Researcher / evaluator - how the numbers are measured | Benchmark Methodology · Benchmark below |
What Can It Do?
Point the AI at a vibration signal → get the evidence behind the fault - detected frequencies, matched fault patterns, ISO-cited severity - to support your call.
| You say | The AI does |
|---|---|
| "Is this bearing healthy?" | Loads the signal, runs spectral analysis, surfaces matching fault-frequency evidence, cites the ISO 20816-3 severity zone |
| "Generate a full diagnostic report" | Produces an interactive HTML report with charts, fault markers, and server-authored severity wording |
| "Extract specs from test_pump_manual.pdf and diagnose the signal" | Reads the equipment manual, looks up the bearing model, calculates expected fault frequencies, flags which ones the signal actually shows |
| "Train an anomaly detector on my healthy baselines, then flag anomalies" | Trains a model on your normal data, scores new signals, flags outliers for your review |
| "What changed on pump P-101 since the baseline?" | Reads the asset's recorded history, compares the latest acquisitions with the declared reference, and reports each indicator's change with the criterion it applied |
The AI doesn't guess: it calls 41 specialized MCP endpoints (38 tools + 3 prompts) running locally on your machine. Every signal is referenced by a single signal_id handle from load to report. Your data never leaves your infrastructure.
Full endpoint reference, grouped by category: Tool Catalog.
Quick Start
One route, from a fresh clone to a first diagnosis in Claude Desktop. You need Git (or the repository ZIP from GitHub, extracted), uv (it fetches Python 3.11 by itself) and Claude Desktop.
1. Get the repository. The 20 sample signals ship with it, not with the PyPI package: real bearing measurements from the MathWorks rolling-element bearing dataset, healthy baselines plus inner and outer race faults, each with its companion metadata (data/README.md).
git clone https://github.com/LGDiMaggio/predictive-maintenance-mcp.git
cd predictive-maintenance-mcp
2. Install and connect. On Windows, one script creates the environment, installs the server and writes the Claude Desktop entry (clones inside OneDrive or other synced folders are handled):
powershell -ExecutionPolicy Bypass -File setup_claude.ps1
uv venv .venv --python 3.11
uv pip install --python .venv/bin/python .
Add this entry to ~/Library/Application Support/Claude/claude_desktop_config.json, with the absolute path of your clone in place of /path/to/predictive-maintenance-mcp. If a predictive-maintenance entry is already there, replace it:
{
"mcpServers": {
"predictive-maintenance": {
"command": "/path/to/predictive-maintenance-mcp/.venv/bin/python",
"args": ["-m", "predictive_maintenance_mcp"],
"env": { "PDM_PROJECT_DIR": "/path/to/predictive-maintenance-mcp" }
}
}
}
PDM_PROJECT_DIR tells the server where the sample signals and the reports live. Keep every path absolute: Claude Desktop launches servers with a minimal PATH.
3. Restart and check. Quit Claude Desktop completely (File, then Quit) and start it again. In a new chat ask:
"List the available vibration signals."
The 20 included signals should appear. If they do not, see INSTALL.md, Troubleshooting.
4. First diagnosis. Try:
"Load real_train/OuterRaceFault_1.csv. The shaft runs at 1500 rpm: check the bearing against the fault frequencies declared in its metadata, assess the ISO severity and generate the envelope report."
What comes back is the server's evidence, not the model's opinion: two of the four declared frequencies come back as high evidence in the envelope spectrum, the outer race ranked most likely and the inner race graded high as well because its second harmonic shares a peak with the third outer-race harmonic, while the ball and cage frequencies stay unmatched; the ISO 20816-3 severity zone of the broadband velocity, with the machine group and support type the assessment assumed; and the path of an HTML report in reports/ with those frequencies marked on the envelope spectrum. The call on the machine stays with you.
The file name carries the fault label, but the server never reads names. Ask which frequencies matched and with what deviation: the answer rests on the spectrum alone.
Use your own data. Put a single-column CSV without a header row where the server can read it (a folder of yours under data/signals/, or an absolute path), add a <name>_metadata.json next to it with sampling_rate and signal_unit (for example "g"), and ask for the analysis stating the shaft speed. Details and traps: Use Your Own Data.
Other clients: Claude Code, VS Code, Cursor and any other MCP client: INSTALL.md, Manual Setup.
Benchmark
A blind, reproducible diagnostic-accuracy benchmark on the public CWRU Bearing Data Center dataset (12 kHz drive-end subset: 60 fault records + 4 normal baselines). Fault labels never reach the system under test - signals enter under opaque ids, a separate scorer is the only label reader, and blindness, checksum integrity, and determinism are enforced by CI-run guard tests, not prose. Results are stratified by the per-record diagnosability grades of the Smith & Randall (2015) reference study, so records that study found undiagnosable by any classical method are reported separately instead of inflating or deflating the headline.
On records the reference study grades clearly diagnosable (Y1+Y2, 44 records): characteristic fault frequency detected on 44/44, correct fault ranked first on 34/44 (77.3%), and 9/9 on the textbook-signature (Y1) stratum. On the 4 healthy baselines, 2 records raised a false indication under the same criterion. The numbers above are read from the committed, re-runnable artifact (results.json) and drift-guarded by CI: every value is bound to its key in the artifact, and a mismatch fails the build. Methodology, blind protocol, and honest-benchmarking notes: docs/benchmark-methodology.md. Reproduce with:
python -m benchmarks.cwru all
Claude Code Plugin
The project includes a plugin for Claude Code with domain-specific skills that activate automatically during conversation.
/plugin marketplace add LGDiMaggio/predictive-maintenance-mcp
/plugin install predictive-maintenance@predictive-maintenance-marketplace
The plugin adds 8 skills that activate automatically based on context (bearing-diagnosis, gear-diagnosis, quick-screening, report-generation, anomaly-detection, signal-management, documentation-search, prognostics), 2 agents that run multi-step diagnostic workflows end-to-end and hand you the evidence (diagnostic-pipeline, signal-explorer), and 3 commands for quick entry points (/pm-diagnose, /pm-screen, /pm-report).
Full skill, agent, and command reference: Plugin README.
Reports
All analysis tools generate interactive HTML reports you can open in any browser - pan, zoom, hover for details. Also supports structured Word (.docx) exports.


| Report Type | What it shows |
|---|---|
| Frequency spectrum | Peak detection, harmonic markers |
| Envelope analysis | Bearing fault frequency matching |
| Severity assessment | Vibration health zones (ISO 20816-3) |
| Word document | Full diagnostic narrative with embedded charts |
| PCA visualization | Multi-signal anomaly clustering |
| Feature comparison | Side-by-side signal feature analysis |
Asset Health Ledger
A single diagnosis answers "what does this signal show". The asset health ledger answers "what changed on this machine since the reference": every measurement loaded with a declared identity (asset, measurement point, acquisition instant, operating conditions) is recorded in a local append-only ledger with its derived indicators, compared with the healthy baseline the engineer declares, and judged against the reference band with the rule it applied stated in the result. Four tools carry the workflow: declare_measurement_point, declare_healthy_baseline, get_asset_history and assess_asset_change. Contract and operations: Adapter Guide · worked flow: Examples · reference adapter: STWIN.box.
Architecture
YOU (natural language)
│
v
LLM (Claude, GPT, Ollama...)
understands intent, selects tools
│
v ── Model Context Protocol ──
┌──────────────────────────────┐
│ Predictive Maintenance │
│ MCP Server │
│ │
│ Signal Analysis Reports │
│ Fault Detection ML │
│ Severity Rating RAG Docs │
└──────────────────────────────┘
│
v
YOUR DATA (stays local)
signals · manuals · models
The codebase follows a modular architecture organized around the ISO 13374 Six-Block Diagnostic standard - signal acquisition, processing, diagnostics, prognostics, and decision support as separate sub-packages. Standards implemented: ISO 13374, ISO 20816-3, MIMOSA OSA-CBM. Module-level detail: Architecture guide.
Key design choices:
- Privacy-first - raw vibration data never leaves your machine; only computed results flow to the LLM
- LLM-agnostic - works with Claude, ChatGPT, Microsoft Copilot Studio, or any MCP-compatible client. Use Ollama for fully air-gapped deployments
- Modular - use only the tools you need, extend with your own
Documentation
| Guide | For |
|---|---|
| Engineer's guide | After the first diagnosis: your own data, machine manuals, workflows |
| Quickstart for Developers | Understand MCP, extend the server |
| Tool Catalog | Every MCP endpoint, grouped by category |
| Adapter Guide | Bring vendor/DAQ raw data in via explicit declarations |
| Plugin README | Claude Code plugin installation and usage |
| HTTPS Deployment | Docker + HTTPS for enterprise environments |
| Ollama Guide | Use with local LLMs (fully air-gapped) |
| Architecture | ISO 13374 block mapping and module design |
| Benchmark Methodology | How the CWRU diagnostic benchmark is measured |
| Examples | Complete diagnostic workflows |
| Installation | Detailed setup and troubleshooting |
| Contributing | How to contribute (all skill levels welcome) |
| Changelog | Version history |
Testing
85%+ test coverage, enforced as a CI minimum, across Windows, macOS, and Linux (Python 3.11 & 3.12) - the current measured figure is on the codecov badge above.
pytest # run all tests
pytest --cov=src --cov-report=html # with coverage report
20+ test files covering signal analysis, fault detection, severity assessment, ML models, report generation, RAG search, and real bearing fault data validation.
Roadmap
- 41 MCP endpoints (38 tools, 3 prompts) with modular architecture and a single
signal_idhandle - Claude Code plugin (8 skills, 2 agents, 3 commands)
- 85%+ test coverage enforced in CI, CI/CD on 3 platforms
- Docker + SSE/HTTP transport for enterprise deployment
- Semantic document search (FAISS + TF-IDF)
- Blind, reproducible diagnostic benchmark on the CWRU dataset (extensible to Paderborn)
- Customizable severity thresholds
- Remaining useful life (RUL) estimation from repeated measurements (linear, exponential, Kalman)
- Trend analysis and degradation onset detection
- Asset health ledger: per-asset measurement history with a declared reference and qualified comparability
- Multi-signal trending and historical comparison
- Real-time streaming (MQTT/Kafka)
- Fleet dashboard for multi-asset monitoring
- CMMS integration (SAP, Maximo, Infor)
Ideas? Open a discussion or create an issue.
Are you using this?
I'd genuinely love to know. Whether you ran it on real machinery or just tried the sample data, drop a line in Discussions - one sentence about your machine or use case is enough. Real-world feedback directly shapes what gets built next.
Related
claude-stwinbox-diagnostics - Extends this project by connecting a physical edge sensor (STEVAL-STWINBX1) to Claude via MCP, with Claude Skills for guided condition monitoring. Same analysis engine, real hardware, operator-friendly reports.
Citation
@software{dimaggio_predictive_maintenance_mcp_2025,
title = {Predictive Maintenance MCP Server},
author = {Di Maggio, Luigi Gianpio},
year = {2025},
version = {0.13.0},
url = {https://github.com/LGDiMaggio/predictive-maintenance-mcp},
doi = {10.5281/zenodo.17611542}
}
data/README.md
🔊 Real Bearing Vibration Dataset
This directory contains production-quality bearing vibration data from real machinery tests - ready for immediate analysis, ML training, and fault detection demonstrations.
✨ What's Included
- 20 high-quality vibration signals with varying sampling rates and durations
- 3 fault types: Healthy baselines, inner race faults, outer race faults
- Train/test split: Pre-organized for ML workflow
- Training set: 2 healthy, 5 inner race faults, 7 outer race faults
- Test set: 1 healthy, 2 inner race faults, 3 outer race faults
- Complete metadata: Each signal has JSON file with sampling rate, duration, bearing frequencies, load conditions
- Professional analysis ready: Works with all MCP diagnostic tools
Perfect for:
- 🎓 Learning predictive maintenance techniques
- 🔬 Testing diagnostic algorithms
- 🤖 Training ML anomaly detection models
- 📊 Generating professional analysis reports
- 🚀 Demonstrating MCP server capabilities
📁 Directory Structure
signals/- Signal files ready for analysis (CSV, MAT, WAV, NPY, Parquet - exposed via MCP resources)real_train/- Training dataset (2 healthy + 12 faulty signals)real_test/- Test dataset for validation (1 healthy + 5 faulty signals)
real_bearings/- Source MAT files from MathWorks (archive only, not used by MCP server)train/- Original MATLAB .mat filestest/- Original MATLAB .mat files
Note: The MCP server reads signal files from the
signals/directory (supports CSV, MAT, WAV, NPY, Parquet). Thereal_bearings/folder is kept as source archive.
📊 Dataset Information
Source: MathWorks RollingElementBearingFaultDiagnosis-Data
License: CC BY-NC-SA 4.0 (Attribution-NonCommercial-ShareAlike 4.0 International)
⚠️ License Summary
This data is licensed under CC BY-NC-SA 4.0, which means:
✅ You CAN:
- Use for learning, research, and educational purposes
- Share and redistribute the data
- Adapt and build upon the data
❌ You CANNOT:
- Use for commercial purposes without separate licensing
- Distribute derivative works under different license terms
📄 Full License: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
📝 Citation
When using this data, please cite:
The MathWorks, Inc. (2023). Rolling Element Bearing Fault Diagnosis Dataset.
GitHub Repository: https://github.com/mathworks/RollingElementBearingFaultDiagnosis-Data
License: CC BY-NC-SA 4.0
📁 Available Signals
Training Set (real_train/) - 14 signals
Healthy Baselines (2 files)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
baseline_1.csv |
97,656 Hz | 6.0s | 585,936 |
baseline_2.csv |
97,656 Hz | 6.0s | 585,936 |
Inner Race Faults (5 files)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
InnerRaceFault_vload_1.csv |
48,828 Hz | 3.0s | 146,484 |
InnerRaceFault_vload_2.csv |
48,828 Hz | 3.0s | 146,484 |
InnerRaceFault_vload_3.csv |
48,828 Hz | 3.0s | 146,484 |
InnerRaceFault_vload_4.csv |
48,828 Hz | 3.0s | 146,484 |
InnerRaceFault_vload_5.csv |
48,828 Hz | 3.0s | 146,484 |
Outer Race Faults (7 files)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
OuterRaceFault_1.csv |
97,656 Hz | 6.0s | 585,936 |
OuterRaceFault_2.csv |
97,656 Hz | 6.0s | 585,936 |
OuterRaceFault_vload_1.csv |
48,828 Hz | 3.0s | 146,484 |
OuterRaceFault_vload_2.csv |
48,828 Hz | 3.0s | 146,484 |
OuterRaceFault_vload_3.csv |
48,828 Hz | 3.0s | 146,484 |
OuterRaceFault_vload_4.csv |
48,828 Hz | 3.0s | 146,484 |
OuterRaceFault_vload_5.csv |
48,828 Hz | 3.0s | 146,484 |
Test Set (real_test/) - 6 signals
Healthy Baseline (1 file)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
baseline_3.csv |
97,656 Hz | 6.0s | 585,936 |
Inner Race Faults (2 files)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
InnerRaceFault_vload_6.csv |
48,828 Hz | 3.0s | 146,484 |
InnerRaceFault_vload_7.csv |
48,828 Hz | 3.0s | 146,484 |
Outer Race Faults (3 files)
| File | Sampling Rate | Duration | Samples |
|---|---|---|---|
OuterRaceFault_3.csv |
97,656 Hz | 6.0s | 585,936 |
OuterRaceFault_vload_6.csv |
48,828 Hz | 3.0s | 146,484 |
OuterRaceFault_vload_7.csv |
48,828 Hz | 3.0s | 146,484 |
Note: Sampling rates and durations vary between signals. All parameters are stored in corresponding
*_metadata.jsonfiles and automatically detected by the MCP server.
🔧 Signal Specifications
- Format: CSV (single column, no header)
- Units: Acceleration (g)
- Sampling Rates: 97,656 Hz or 48,828 Hz (varies by signal)
- Durations: 3.0s or 6.0s (varies by signal)
- Data Points: 146,484 or 585,936 samples (varies by signal)
Important: All signal parameters (sampling rate, duration, samples) are stored in corresponding
*_metadata.jsonfiles and automatically detected by the MCP server. Do not assume fixed values - always check metadata!
Bearing Characteristic Frequencies
| Frequency | Value (Hz) | Description |
|---|---|---|
| Shaft Speed | 25.0 Hz | Rotation frequency |
| FTF | 14.84 Hz | Fundamental Train Frequency (cage) |
| BSF | 63.91 Hz | Ball Spin Frequency |
| BPFO | 81.13 Hz | Ball Pass Frequency Outer Race |
| BPFI | 118.88 Hz | Ball Pass Frequency Inner Race |
📊 Analysis Workflow
The MCP server provides comprehensive diagnostic tools that automatically detect signal parameters from metadata files. All analysis tools generate interactive HTML reports with Plotly visualizations.
Available Report Types
| Report Type | Tool | Description | Output Location |
|---|---|---|---|
| FFT Analysis | generate_fft_report() |
Frequency spectrum analysis with peak detection | reports/fft_*.html |
| Envelope Spectrum | generate_envelope_report() |
Bearing fault detection with modulation analysis | reports/envelope_*.html |
| ISO 20816-3 | generate_iso_report() |
Vibration severity assessment and zone classification | reports/iso_*.html |
Typical Workflow
1. List available signals → list_signals()
2. Generate analysis report → generate_fft_report(signal_file)
3. Review interactive HTML → Open in browser (zoom, pan, hover)
4. Train ML model → train_anomaly_model() with healthy baselines
5. Detect anomalies → predict_anomalies() on new signals
Key Features
- ✅ Automatic parameter detection - Sampling rates, durations, and frequencies read from metadata
- ✅ Interactive visualizations - Plotly charts with zoom, pan, hover capabilities
- ✅ Professional reports - HTML format suitable for documentation and sharing
- ✅ ML-ready - Pre-split train/test sets for anomaly detection workflows
📚 Metadata Files
Each .csv signal has a corresponding *_metadata.json file containing:
{
"sampling_rate": 97656.0,
"signal_unit": "g",
"shaft_speed": 25.0,
"load": 270.0,
"BPFI": 118.875,
"BPFO": 81.125,
"FTF": 14.8375,
"BSF": 63.91,
"num_samples": 585936,
"duration_sec": 6.0
}
Usage: These files provide all necessary parameters for analysis (no need to manually enter frequencies!).
⚠️ Usage Notes
For Academic/Research Use ✅
- ✅ Free to use for learning, research, education
- ✅ Cite the MathWorks repository in publications
- ✅ Share derivative works under CC BY-NC-SA 4.0
For Commercial Use ❌
- ❌ Not permitted under CC BY-NC-SA 4.0 license without separate licensing
- ✅ This MCP server (MIT license) can be used commercially, but replace sample signals with your own data
Recommended Approach for Commercial Projects
- Development/Testing: Use these sample signals freely
- Production Deployment: Replace with your own vibration data or obtain commercial license from MathWorks
- MCP Server Code: MIT licensed, use freely in commercial projects
- Sample Data: For demonstration and educational purposes only
🎓 Citation
If you use this data in research or publications, please cite:
The MathWorks, Inc. (2023). Rolling Element Bearing Fault Diagnosis Dataset.
GitHub Repository: https://github.com/mathworks/RollingElementBearingFaultDiagnosis-Data
License: CC BY-NC-SA 4.0
📖 Additional Resources
- MathWorks Repository - Dataset source
- MathWorks Predictive Maintenance Toolbox - MATLAB examples
- CC BY-NC-SA 4.0 License - Full license terms
Note: This MCP server is not affiliated with, endorsed by, or sponsored by The MathWorks, Inc. Sample data is provided under CC BY-NC-SA 4.0 license for educational and non-commercial demonstration purposes only.
examples/adapters/stwinbox/README.md
STWIN.box adapter
stwinbox_to_measurement.py converts an acquisition of the STEVAL-STWINBX1 board (STWIN.box, FP-SNS-DATALOG2 firmware) into files the server loads as declared measurements: one headerless float32 .bin per accelerometer axis, in g, each with the companion <stem>_metadata.json that the load_signal tool reads. It follows the Adapter Guide: it runs before the server is involved, imports nothing from it, and needs only the standard library and NumPy.
Two inputs are accepted:
- a DATALOG2 acquisition folder (
YYYYMMDD_HH_MM_SS/) holdingacquisition_info.json,device_config.jsonand one<sensor>.datper active sensor, as written by the firmware on the SD card or by the ST host tools over USB; - a window CSV of the USB bridge recorder of the same board, header
Time [s],A_x [g],A_y [g],A_z [g], selected with--input-format window-csv.
Usage
python examples/adapters/stwinbox/stwinbox_to_measurement.py <acquisition folder> \
--asset-id P-101 --measurement-point-prefix motor_de --out data/signals/P-101 \
[--rpm 1480] [--start-time-offset +02:00]
python examples/adapters/stwinbox/stwinbox_to_measurement.py <window>.csv \
--input-format window-csv --asset-id P-101 --measurement-point-prefix motor_de \
--out data/signals/P-101 --sampling-rate 26667 --acquired-at 2026-06-29T13:27:00Z
| Option | Applies to | Meaning |
|---|---|---|
--asset-id |
both | The asset the measurement belongs to (ledger id grammar: starts with a letter or digit, then letters, digits, _, -, .). |
--measurement-point-prefix |
both | Measurement points become <prefix>_x, <prefix>_y, <prefix>_z. |
--out |
both | Output directory, typically under the server's data/signals/. |
--sensor |
datalog2 | Component to decode; default iis3dwb_acc. |
--rpm |
both | Shaft speed in rev/min; recorded only when given. |
--declared-by |
both | Attribution written in the companion; default adapter:stwinbox. |
--sensor-id |
both | Overrides the sensor identifier (datalog2 default: the board serial number). |
--sampling-rate |
both | Hz. Required for a window CSV; overrides measodr for a folder. |
--acquired-at |
both | ISO 8601 instant with offset. Required for a window CSV (unless the option below is chosen); overrides start_time for a folder. |
--acquired-at-from-filename |
window-csv | Reads the instant from the recorder's <asset>_<YYYYmmdd>_<HHMMSS>_<ffffff>.csv naming, taken as UTC. Secondary to --acquired-at. |
--start-time-offset |
datalog2 | UTC offset the board clock held when it stamped start_time; replaces the Z suffix. Write --start-time-offset=-05:00 for a negative offset. |
--nominal-odr-hz |
datalog2 | The configured output data rate in Hz, recorded as provenance only. |
--force |
both | Replace existing output files. |
Outputs are <asset>_<prefix>_<axis>_<UTC stamp>.bin and <asset>_<prefix>_<axis>_<UTC stamp>_metadata.json for x, y and z, where the stamp is the acquisition instant in UTC. An existing output is never replaced without --force. A refusal exits with status 1, prints one message naming the problem and the remedy on stderr, and writes nothing.
What it reads and what it declares
| Companion field | Source | Notes |
|---|---|---|
sampling_rate |
device_config.json, sensor measodr |
The rate the firmware measured during the capture. The sensor's odr field is a firmware enumeration index (0 for the IIS3DWB), never a frequency, and is never read as one; without measodr the adapter refuses unless --sampling-rate is given. |
signal_unit |
fixed, g |
The IIS3DWB reports acceleration in g. A component that declares another unit is refused. |
sample_format, byte_order |
fixed, float32, little |
The adapter writes the scaled samples (counts times sensitivity), not the counts. |
measurement.acquired_at |
acquisition_info.json, start_time |
Copied as written, see The acquisition clock. --acquired-at overrides it; --start-time-offset relabels it. A folder without start_time is refused unless --acquired-at is given. |
measurement.sensor_id |
device_config.json, device sn (firmware alias when there is no serial) |
--sensor-id overrides. |
measurement.asset_id, measurement_point_id, direction, declared_by, rpm |
command line | One point per axis, direction x, y or z. rpm is present only when --rpm was given. |
adapter (top level) |
provenance | Adapter name and version, decoder name, source folder or file name, firmware alias, name and version, device model and serial, measured and nominal ODR, the odr index, sensitivity, frame layout, packet and frame counts, and where each declared value came from. The server keeps it under source_metadata. |
Decoding a folder needs sensitivity (g per LSB), data_type (only int16 is supported), dim (axes per sample), samples_per_ts (samples between two timestamps) and the packet size of the acquisition link (usb_dps over USB, sd_dps on the SD card, selected by interface in acquisition_info.json). A missing or unusable field is a refusal that names the field.
The .dat stream
A <sensor>.dat file is a sequence of packets. Each packet opens with a 4-byte little-endian byte counter and carries usb_dps bytes of payload (sd_dps minus 4 on the SD card). The concatenated payloads form frames of samples_per_ts samples, each sample being dim interleaved int16 values, followed by one float64 timestamp in seconds. The adapter strips the counters, checks that they advance by exactly one payload per packet (a different step means the link lost data and the file is refused rather than written as a contiguous signal), strips the timestamps, and keeps the samples of a final block that has no timestamp yet. Timestamps that step outside 0.1 to 10 times the expected frame period are refused as well: the ST SDK zeroes such frames, this adapter does not write a measurement from them.
Window CSV
The recorder writes short windows with the header Time [s],A_x [g],A_y [g],A_z [g]. The adapter takes A_x, A_y and A_z as the three axes and ignores the Time column, which the server does not need. A window declares neither a sampling rate nor an acquisition instant, so both are declared on the command line: --sampling-rate is required, and --acquired-at is the primary way to declare the instant. --acquired-at-from-filename is the secondary option for recorders that follow the <asset>_<UTC stamp>.csv naming; it declares trust in that convention. When the rate implied by the Time column differs from the declared one by more than 5 %, the adapter writes the declared value and prints a warning.
The acquisition clock
acquisition_info.json carries start_time and end_time with a Z suffix. That suffix is a label, not a measurement: when the host starts the log, the ST SDK sets the board clock from the host's local wall-clock time without an offset (HSDLink_v2.start_log calls set_rtc_time with datetime.now()), and the firmware writes those digits with Z. On host-driven acquisitions the digits are therefore the host's local time. A board that logs to the SD card on its own uses whatever its clock last held; a clock that was never set reports 2000-01-01, and the adapter warns when the year is before 2010.
The adapter never corrects the value on its own. It copies start_time as written, prints a warning that says so, and offers two declarations:
--start-time-offset +02:00keeps the digits and replaces theZwith the offset the clock actually held (2026-05-11T11:06:00.000Zbecomes2026-05-11T11:06:00+02:00);--acquired-at 2026-05-11T09:06:00Zdeclares the instant outright.
Either choice is recorded in the companion (adapter.acquired_at_source, adapter.start_time_offset_declared). An offset that is wrong by hours changes the order of measurements against sources that declare true UTC, so the checklist below records what the clock held on the device in use.
Limitations
- One file per axis. The companion is per file stem and cannot map channels to directions, so a three-axis acquisition becomes three measurements on three points.
- Only
int16components with a positivesensitivityare decoded. Microphones, the magnetometer and other components are refused when named with--sensor. - Only acceleration in g. The adapter does not convert units.
- Tags, the
end_time, and the other sensors of the acquisition are not used. - The nominal output data rate in Hz is not derived from the
odrindex (that mapping lives in the firmware's device template); pass--nominal-odr-hzto record it. - A packet counter gap or a timestamp anomaly is a refusal, not a repair.
Verification against the ST SDK
The decoder was compared with stdatalog-pysdk (HSDatalog.get_dataframe, timestamp recovery enabled) on four acquisitions of the iis3dwb_acc component on 2026-09-10: three taken over USB with FP-SNS-DATALOG2 3.2.0 and the SD-card example shipped with the SDK (firmware 2.3.0). On every acquisition the SDK returned exactly the samples of the complete frames (541000, 128000, 262000 and 274000 samples, 1000 per frame), the adapter returned the same samples plus those of the final block without a timestamp (778, 162, 150 and 728 samples), and the largest absolute difference on any sample was 3.5e-7 g, which is float32 resolution at the amplitudes involved. The adapter's frame timestamps matched the SDK's frame boundaries. The comparison is not part of the test suite because the SDK is not a dependency of this repository; tests/test_examples_stwinbox_adapter.py covers the same layout on synthetic folders.
End-to-end flow with the server
- Convert the first acquisition with the command above, writing under the server's data directory, for example
data/signals/P-101/. The three companions declare assetP-101, pointsmotor_de_x,motor_de_y,motor_de_z, the instant, the sensor and the rate. - Declare the measurement point you intend to trend, once, with the
declare_measurement_pointtool: assetP-101, pointmotor_de_x, the bearing (catalog id or fault orders), machine group and support type for the ISO block, expected unitgand expected directionx. The declaration is an event in the asset ledger; a later change is a new declaration, not an edit. - Load the first
.binof that point with theload_signaltool, naming the file. The declaration comes from the companion; the returned measurement block reports whether the measurement was recorded and whether its health snapshot is complete. - Restart the server. The ledger lives in
data/ledger/(orPMM_LEDGER_DIR) and survives the restart; the in-memory signal store does not, and does not need to. - Convert and load the second acquisition, taken some time later, the same way.
- Ask for the history of
P-101with theget_asset_historytool: the two measurements ofmotor_de_xappear inacquired_atorder, each with the context declared by its companion (sensor, direction, rpm when given) and its snapshot. Theassess_asset_changetool compares the later measurement against the earlier ones with the criteria stated in its response.
The same flow with the window CSV input replaces step 1 with the second command above.
Real-device checklist
The adapter is verified against the SDK on stored acquisitions (above). The round trip on a connected board is a manual step for the maintainer, recorded here when done; the entries stay "to be recorded" until then.
| Item | Result |
|---|---|
| Date of the run | to be recorded |
Firmware (fw_name, fw_version) and board alias |
to be recorded |
Output data rate: measodr against the nominal rate of the odr index |
to be recorded |
start_time: UTC or host local time, checked against the host clock at the start of the log |
to be recorded |
Two acquisitions taken at a distance in time, converted and loaded, with the server restarted in between: same history from get_asset_history |
to be recorded |
| Anomalies found (packet counter gaps, timestamp steps, unit or sensitivity surprises) | to be recorded |
Observations from stored acquisitions, FP-SNS-DATALOG2 3.2.0 over USB, IIS3DWB at odr index 0, read on 2026-09-10: measodr between 26578 Hz and 26592 Hz across acquisitions against a nominal 26667 Hz (about 0.3 % below); sensitivity 0.000488 g per LSB; samples_per_ts 1000; usb_dps 7000; first packet counter 0; the start_time digits equal to the host's local wall clock (folder name and file times) in both winter and summer time, which is what the clock-setting path above predicts. The SD-card example from the SDK, logged with a clock that was never set, starts at 2000-01-01.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.