Goal: Understand how MCP works, run the server, and create your first custom diagnostic tool in under 20 minutes.
By the end of this guide, you will:
- ✅ Understand the Model Context Protocol (MCP) architecture
- ✅ Run the server and inspect its tools interactively
- ✅ Read and understand the server codebase
- ✅ Know how to create a new diagnostic tool from scratch
- ✅ Have a clear path to contributing
Industrial machines generate terabytes of sensor data — vibration, temperature, pressure, acoustics. Expert analysts can interpret this data to predict failures before they happen, saving thousands of euros per avoided downtime. But these experts are rare and expensive.
LLMs are excellent at reasoning, planning, and communicating — but they don't know signal processing. Signal processing libraries (NumPy, SciPy, scikit-learn) are excellent at computation — but they can't reason or communicate.
The Model Context Protocol is the bridge. It's an open standard (by Anthropic) that defines how an LLM can discover and invoke external tools. Think of it as a universal plugin system:
┌─────────────┐ MCP Protocol ┌──────────────────┐
│ │ ◄──────────────────── │ │
│ LLM │ "What tools exist?" │ MCP Server │
│ (Claude) │ ────────────────────► │ (This project) │
│ │ "Call analyze_fft" │ │
│ │ ◄──────────────────── │ • analyze_fft │
│ │ {peaks: [...]} │ • envelope │
│ │ │ • iso_20816 │
│ │ │ • ml_anomaly │
└─────────────┘ └──────────────────┘
The LLM has no idea what FFT is. It just knows:
- "There's a tool called
analyze_fft" - "It takes a file path and sampling rate"
- "It returns peaks and frequencies"
This is the same pattern you can use for any domain: medical imaging, financial analysis, climate modeling, robotics. This project is a production-quality reference implementation for the predictive maintenance domain.
# Clone and install with dev dependencies
git clone https://github.com/LGDiMaggio/predictive-maintenance-mcp.git
cd predictive-maintenance-mcp
python -m venv .venv
# Activate
.venv\Scripts\activate # Windows
source .venv/bin/activate # macOS/Linux
# Install (includes pytest, black, mypy, flake8)
pip install -e ".[dev]"
# Verify everything works
python validate_server.py
pytest -vpredictive-maintenance-mcp/
├── src/
│ ├── machinery_diagnostics_server.py ← THE SERVER (all MCP tools defined here)
│ ├── document_reader.py ← PDF/manual processing module (pypdf)
│ ├── report_generator.py ← HTML report generation (Plotly)
│ └── html_templates.py ← Report HTML templates
├── data/
│ └── signals/ ← Vibration data (CSV/MAT/WAV/NPY/Parquet + metadata)
│ ├── real_train/ ← 14 signals for training
│ └── real_test/ ← 6 signals for validation
├── resources/
│ ├── machine_manuals/ ← Equipment manuals (PDF/TXT)
│ ├── bearing_catalogs/ ← Bearing geometry database
│ └── cache/ ← Auto-cached manual extractions
├── skills/ ← Copilot Skills (guided diagnostic workflows)
│ ├── bearing-diagnosis/ ← 8-step bearing fault detection
│ ├── quick-screening/ ← Fast health screening
│ └── report-generation/ ← Professional report orchestration
├── models/ ← Trained ML models (joblib)
├── reports/ ← Generated HTML reports
└── tests/ ← Comprehensive test suite
This single file contains the entire MCP server. Open it and you'll see a very clean pattern:
from mcp.server.fastmcp import FastMCP
# Create the server
mcp = FastMCP("Predictive Maintenance Server")
# Define a RESOURCE (direct data access for the LLM)
@mcp.resource("signal://list")
def list_signals() -> str:
"""List all available vibration signals."""
# ... returns signal listing
# Define a TOOL (computation the LLM can invoke)
@mcp.tool()
def analyze_fft(file_path: str, sampling_rate: float = None, ...) -> dict:
"""FFT spectrum analysis with automatic peak detection."""
# ... performs actual signal processing
# ... returns structured resultsThat's it. A @mcp.tool() decorator + a Python function = an LLM-accessible tool.
| Concept | Purpose | Example | When to Use |
|---|---|---|---|
| Resource | Read-only data access | signal://list |
LLM needs to browse/read data |
| Tool | Computation & side effects | analyze_fft() |
LLM needs to compute something |
Resources are like GET endpoints. Tools are like POST endpoints. The LLM uses Resources to gather context and Tools to take action.
The best way to understand the server is to see it live:
npx @modelcontextprotocol/inspector npx predictive-maintenance-mcpOr from source:
uv run mcp dev src/machinery_diagnostics_server.pyThis opens a web UI where you can:
- Browse all registered Resources and Tools
- See each tool's parameters, types, and documentation
- Call tools with test data and see the results
- Understand exactly what the LLM sees
Configure the server in Claude Desktop (see INSTALL.md) and try:
What tools do you have available for vibration analysis?
Claude will describe every tool, its parameters, and what it does — because MCP exposes this metadata automatically.
Let's add a new tool: thermographic analysis (simplified example). This demonstrates the pattern for any new diagnostic capability.
Add to src/machinery_diagnostics_server.py:
@mcp.tool()
def analyze_temperature_trend(
temperatures: list[float],
timestamps: list[str],
warning_threshold: float = 80.0,
critical_threshold: float = 100.0
) -> dict:
"""
Analyze temperature trend data for thermal anomalies.
Detects overheating patterns, calculates rate of change,
and classifies severity based on configurable thresholds.
Args:
temperatures: List of temperature readings in °C
timestamps: List of ISO timestamps for each reading
warning_threshold: Warning temperature in °C (default: 80.0)
critical_threshold: Critical temperature in °C (default: 100.0)
Returns:
Dictionary with trend analysis, anomaly detection, and severity
"""
import numpy as np
temps = np.array(temperatures)
# Calculate statistics
current = temps[-1]
rate_of_change = np.gradient(temps).mean() # °C per sample
# Classify severity
if current >= critical_threshold:
severity = "CRITICAL"
recommendation = "Immediate shutdown recommended"
elif current >= warning_threshold:
severity = "WARNING"
recommendation = "Schedule inspection within 24 hours"
else:
severity = "NORMAL"
recommendation = "No action required"
return {
"current_temperature": float(current),
"max_temperature": float(temps.max()),
"min_temperature": float(temps.min()),
"mean_temperature": float(temps.mean()),
"rate_of_change": float(rate_of_change),
"severity": severity,
"recommendation": recommendation,
"samples_analyzed": len(temps)
}Create tests/test_temperature.py:
import pytest
def test_analyze_temperature_normal():
"""Test normal temperature classification."""
from machinery_diagnostics_server import analyze_temperature_trend
result = analyze_temperature_trend(
temperatures=[45.0, 46.0, 45.5, 46.2, 45.8],
timestamps=["2025-01-01T00:00", "2025-01-01T01:00",
"2025-01-01T02:00", "2025-01-01T03:00",
"2025-01-01T04:00"]
)
assert result["severity"] == "NORMAL"
assert result["current_temperature"] == pytest.approx(45.8)
def test_analyze_temperature_critical():
"""Test critical temperature detection."""
from machinery_diagnostics_server import analyze_temperature_trend
result = analyze_temperature_trend(
temperatures=[60.0, 75.0, 90.0, 105.0, 110.0],
timestamps=["2025-01-01T00:00", "2025-01-01T01:00",
"2025-01-01T02:00", "2025-01-01T03:00",
"2025-01-01T04:00"]
)
assert result["severity"] == "CRITICAL"
assert "shutdown" in result["recommendation"].lower()pytest tests/test_temperature.py -vRestart Claude Desktop and try:
I have these temperature readings from a pump motor:
45, 52, 61, 73, 85, 92, 98, 103 °C
taken hourly. Analyze the trend.
Claude will automatically discover and call your new tool.
That's it. You just extended an industrial AI system with a new diagnostic capability.
| Pattern | Where | What You'll Learn |
|---|---|---|
| Tool with auto-detection | analyze_fft() |
How to load metadata and infer parameters |
| Report generation | generate_fft_report() |
How to create interactive Plotly HTML reports |
| ML pipeline | train_anomaly_model() |
How to build scikit-learn pipelines as MCP tools |
| Caching | extract_manual_specs() |
How to cache expensive operations (PDF parsing) |
| Resource + Tool combo | signal://read + analyze_fft |
How Resources and Tools work together |
-
One file, one server — The entire MCP interface is in
machinery_diagnostics_server.py. This makes it easy to understand, test, and deploy. -
Tools are pure functions — Each tool takes parameters, does computation, returns structured data. No side effects except file I/O (reports, models).
-
Metadata-driven — Sampling rates, bearing frequencies, signal units are auto-detected from metadata JSON files. No hardcoded assumptions.
-
Fail gracefully — Tools return meaningful error messages, not stack traces. The LLM can relay these to the user in natural language.
These are tasks specifically designed to be completable by someone new to the project:
| Task | Skills Needed | Impact |
|---|---|---|
| ✅ Done in v0.5.0 (CSV, MAT, WAV, NPY, Parquet all supported) | ||
| Make ISO report thresholds configurable | Python | Enables different machine classes (pumps vs turbines) |
| Add unit conversion tool (mil ↔ mm/s ↔ g) | Python, vibration basics | Helps users with data in different unit systems |
| Improve error messages for missing metadata | Python | Better UX for new users |
| Add more bearings to the catalog | JSON editing | Expands bearing frequency lookup without writing code |
Browse all open issues: GitHub Issues — filter by good first issue label.
- Docker containerization — Package the whole server into a single
docker runcommand - Vector search for manuals — Integrate ChromaDB for semantic search over large PDFs
- Streaming signal support — Real-time vibration monitoring through Server-Sent Events
- Deep learning models — Replace OneClassSVM with autoencoders or transformers
- Multi-modal fusion — Combine vibration + temperature + current data
- Transfer learning — Pre-trained models that work across different machine types
| Resource | URL |
|---|---|
| MCP Specification | modelcontextprotocol.io |
| FastMCP Framework | github.com/jlowin/fastmcp |
| MCP Inspector | github.com/modelcontextprotocol/inspector |
| Project Issues | GitHub Issues |
| Contributing Guide | CONTRIBUTING.md |
- Read the full examples: EXAMPLES.md — 7 complete workflows showing every tool
- Browse the server code:
src/machinery_diagnostics_server.pyis well-documented - Pick an issue: Issues · good first issue
- Read the contributing guide: CONTRIBUTING.md
- Think bigger: What domain could YOU build an MCP server for?
This project is a template. The real power is what you build next.