Predictive Maintenance MCP Server
This server turns AI assistants into predictive maintenance experts, providing end-to-end vibration analysis, fault detection, severity assessment, anomaly detection, prognostics, and reporting through natural language conversation. It processes all data locally for privacy and is LLM-agnostic.
Signal Management
Load signals from CSV, WAV, MAT, NPY, or Parquet files into an in-memory repository
List signals on disk or in memory, inspect metadata, generate synthetic test signals (bearing fault, gear fault, imbalance, normal), and clear the cache
Spectral & Statistical Analysis
FFT with automatic peak detection, envelope analysis (Hilbert transform + bandpass filtering), statistical analysis (RMS, kurtosis, crest factor, skewness), Power Spectral Density (Welch method), STFT spectrograms, and 17-feature time-domain extraction
Fault Detection & Diagnostics
Check bearing characteristic frequencies (BPFO, BPFI, BSF, FTF) against signal peaks with harmonic detection
Search a built-in bearing catalog (~20 ISO 6200–6310 series bearings), calculate geometry-based fault frequencies, and run full integrated diagnosis (FFT + PSD + STFT + bearing faults + ISO severity) in one call
Severity Assessment
ISO 20816-3 zone classification (A/B/C/D) for machine classes I–IV
Check RMS velocity against ISO 10816 or custom warning/alarm/danger thresholds
Anomaly Detection
Train unsupervised models (OneClassSVM, LocalOutlierFactor) on healthy baselines and score new signals as Healthy/Suspicious/Faulty
Equipment Documentation
List, search (RAG-based semantic search via FAISS or TF-IDF), and read excerpts from machine manuals and bearing catalogs (PDFs/text files)
Automatically extract structured specs (bearing designations, RPM, power ratings) from PDFs
Prognostics
Estimate Remaining Useful Life (RUL) using linear, exponential, Weibull, or Kalman degradation models
Analyze feature trends over time and detect degradation onset
Reporting & Visualization
Interactive HTML plots: time-domain signals, FFT spectra, envelope spectra, ISO severity zone charts, PCA scatter plots, and feature comparison violin plots
Professional Word (.docx) diagnostic reports with statistics, FFT peaks, bearing frequencies, and diagnosis narrative
List and inspect generated reports without consuming tokens on HTML content
Decision Support
Generate maintenance recommendations based on ISO severity zone and detected fault types
Guided Workflows (3 Prompts)
Complete decision-tree workflows for bearing fault diagnosis, gear fault detection, and quick health screening
Allows the MCP server to be used with local LLMs (via Ollama) for predictive maintenance diagnostics, keeping data local and avoiding cloud dependency.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Predictive Maintenance MCP ServerCheck if bearing is healthy from vibration data"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
Related MCP server: Auto-Manager MCP
Choose Your Path
You are | Start here |
Reliability / maintenance engineer — diagnostics in plain language, no coding | |
AI / MCP developer — run, integrate, and extend the server | Developer's Quickstart · Quick Start below |
Researcher / evaluator — how the numbers are measured | Benchmark Methodology · Benchmark below |
Quick Start
Get running in ~3 minutes. On Windows, one script wires everything into Claude Desktop — it installs the venv, pre-compiles dependencies, and writes claude_desktop_config.json for you (OneDrive / cloud-sync paths included):
git clone https://github.com/LGDiMaggio/predictive-maintenance-mcp.git
cd predictive-maintenance-mcp
.\setup_claude.ps1Restart Claude Desktop, then try:
"Load real_train/OuterRaceFault_1.csv and check if the bearing is healthy."
Install the package:
pip install predictive-maintenance-mcpFind the full path to uvx (which uvx on macOS/Linux, where uvx on Windows), then add to your client config — ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"predictive-maintenance": {
"command": "/full/path/to/uvx",
"args": ["predictive-maintenance-mcp"],
"env": { "UV_LINK_MODE": "copy" }
}
}
}Why the full path? Claude Desktop launches servers with a minimal
PATHthat often omits user-local tool directories (e.g.~/.local/bin). Using the full path touvxavoids a silent "command not found" failure. On Windows the typical path isC:\Users\<you>\.local\bin\uvx.exe.
More options: install from source · VS Code setup · Docker / HTTPS deployment · use with local LLMs (Ollama)
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 allWhat 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 |
The AI doesn't guess — it calls 37 specialized MCP endpoints (34 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.
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-marketplaceThe 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 |
Sample Data Included
The project ships with 20 real bearing vibration signals from production machinery tests — ready to use out of the box: a training set (2 healthy baselines + 12 fault signals, inner and outer race) and a test set (1 healthy baseline + 5 fault signals).
Try: "Load real_train/OuterRaceFault_1.csv and diagnose the bearing fault."
Full dataset documentation: data/README.md
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 · modelsThe 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 |
Get results fast, no coding required | |
Understand MCP, extend the server | |
Every MCP endpoint, grouped by category | |
Bring vendor/DAQ raw data in via explicit declarations | |
Claude Code plugin installation and usage | |
Docker + HTTPS for enterprise environments | |
Use with local LLMs (fully air-gapped) | |
ISO 13374 block mapping and module design | |
How the CWRU diagnostic benchmark is measured | |
Complete diagnostic workflows | |
Detailed setup and troubleshooting | |
How to contribute (all skill levels welcome) | |
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 report20+ test files covering signal analysis, fault detection, severity assessment, ML models, report generation, RAG search, and real bearing fault data validation.
Roadmap
37 MCP endpoints (34 tools, 3 prompts) with modular architecture and a single
signal_idhandleClaude 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
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.
Contributing
Contributions welcome from everyone — not just programmers. Domain experts, technical writers, and testers are equally valued. See CONTRIBUTING.md for paths tailored to your background.
Quick start: browse Issues for good first issue or help wanted labels.
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}
}License
MIT — see LICENSE. Sample data is CC BY-NC-SA 4.0 (non-commercial); for commercial use, replace with your own machinery data.
Acknowledgments
MCP Python SDK (descended from FastMCP) · Model Context Protocol by Anthropic · Sample data from MathWorks · Core development assisted by Claude
An open-source predictive maintenance AI agent and condition monitoring copilot — built to support reliability engineers and the developer community.
Available Tools
34 toolsanalyze_envelopeA
Envelope-spectrum analysis of a stored signal (bearing fault screening).
THE unified envelope tool: bandpass filter -> Hilbert
envelope -> mean subtraction + Hann window -> FFT -> top peaks.
The mean subtraction/window step is an intentional U9 fix: the
envelope's DC leakage used to bury the low-frequency FTF zone.
Requires the signal loaded via load_signal() first; the sampling
rate comes from the stored signal metadata.
The requested band must fit the signal: an invalid band (low <= 0,
low >= high, high > Nyquist) raises a ValueError — it is NEVER
silently clamped. The band used is echoed in the result.
By default analyzes the LEADING 1.0-second segment (deterministic:
two identical calls return identical results). Set
segment_duration=None to analyze the entire signal, or pass
random_seed to sample a seeded random segment position instead.
No reference bearing frequencies are assumed: compare the returned
peaks against frequencies computed for the actual bearing and
shaft speed (check_bearing_faults or
calculate_bearing_characteristic_frequencies).
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of the stored signal (from load_signal).
filter_low: Bandpass low edge in Hz (default: 500).
filter_high: Bandpass high edge in Hz (default: 5000). Must
not exceed the signal's Nyquist frequency.
num_peaks: Number of top peaks to return (default: 5).
segment_duration: Duration in seconds to analyze (default:
leading 1.0 s). None analyzes the full signal.
random_seed: Seed for random segment position (default: None =
deterministic leading segment).
Returns:
EnvelopeResult with the band actually used, top peaks, and
comparison guidance.
Raises:
ValueError: If the signal_id is not loaded, the stored signal
has no sampling rate, or the band is invalid vs Nyquist.
| Name | Required | Description | Default |
|---|---|---|---|
| num_peaks | No | ||
| signal_id | Yes | ||
| filter_low | No | ||
| filter_high | No | ||
| random_seed | No | ||
| segment_duration | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| diagnosis | Yes | Peak listing and comparison guidance. No reference bearing frequencies are assumed — compare against frequencies computed for the actual bearing and shaft speed. |
| signal_id | Yes | Signal identifier used |
| top_peaks | Yes | Top peaks in the envelope spectrum, sorted by frequency |
| filter_band | Yes | Bandpass filter band (Hz) actually used — echoed from the request |
| num_samples | Yes | Number of samples analyzed (envelope length) |
| sampling_rate | Yes | Sampling rate (Hz) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels. It discloses the intentional U9 fix (mean subtraction/window) and why it exists ('DC leakage used to bury the low-frequency FTF zone'), states invalid bands raise ValueError and are 'NEVER silently clamped', notes the band is echoed in the result, and explains the deterministic default (leading 1.0-s segment) and random_seed behavior. Also clarifies no reference frequencies are assumed, preventing false expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: algorithm, rationale, requirements, constraints, defaults, and comparison guidance. It uses a clear structure (intro, behavior, Args, Returns, Raises) and front-loads the purpose. No fluff or repetition; the 'THE unified envelope tool' line, while emphatic, reinforces its role among siblings.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (6 parameters, prerequisites, error conditions, segment selection) and the description covers all aspects: preconditions (signal must be loaded), constraints (band vs Nyquist), deterministic vs random behavior, no assumed bearing frequencies, and error types. The output schema exists, so it appropriately keeps return details brief ('EnvelopeResult with the band actually used, top peaks, and comparison guidance').
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must fully compensate. It explains every parameter: signal_id (ID from load_signal), filter_low/filter_high (edges in Hz with defaults, Nyquist constraint), num_peaks (count of top peaks), segment_duration (duration, default leading 1.0s, None for full signal), random_seed (seed for random position, None = deterministic). It also adds error semantics for invalid values, going far beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: 'Envelope-spectrum analysis of a stored signal (bearing fault screening)' and details the algorithm ('bandpass filter -> Hilbert envelope -> mean subtraction + Hann window -> FFT -> top peaks'). It clearly distinguishes itself from siblings like analyze_fft and check_bearing_faults by positioning itself as 'THE unified envelope tool' and referencing the comparison tools for subsequent analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Requires the signal loaded via load_signal() first', explains when to use the tool (bearing fault screening), and gives alternative/next-step guidance: 'compare the returned peaks against frequencies computed for the actual bearing and shaft speed (check_bearing_faults or calculate_bearing_characteristic_frequencies)'. It also clarifies segment selection options and when to pass None or random_seed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyze_fftA
Perform FFT (Fast Fourier Transform) analysis on a stored signal.
FFT analysis converts the signal from time domain to frequency domain,
allowing identification of harmonic components and faults that manifest
at specific frequencies. Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
By default analyzes the LEADING 1.0-second segment (deterministic:
two identical calls return identical results). Set
segment_duration=None to analyze the entire signal, or pass
random_seed to sample a seeded random segment position instead.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of the stored signal (from load_signal).
max_frequency: Maximum frequency to analyze (default: Nyquist frequency)
segment_duration: Duration in seconds to analyze (default: leading
1.0 s). Set to None to analyze the full signal.
random_seed: Seed for random segment position (default: None =
deterministic leading segment).
Returns:
FFTResult with top peaks, dominant peak, and spectrum stats.
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes | ||
| random_seed | No | ||
| max_frequency | No | ||
| segment_duration | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| top_peaks | Yes | Top spectral peaks sorted by magnitude |
| total_bins | Yes | Total number of FFT bins computed |
| num_samples | Yes | Number of analyzed samples |
| rms_spectral | Yes | RMS of the magnitude spectrum |
| freq_range_hz | Yes | [min_freq, max_freq] of the spectrum |
| sampling_rate | Yes | Sampling frequency (Hz) |
| peak_frequency | Yes | Dominant peak frequency (Hz) |
| peak_magnitude | Yes | Dominant peak magnitude |
| frequency_resolution | Yes | Frequency resolution (Hz) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is rich with behavioral detail: deterministic leading-segment default, segment_duration=None for full signal, random_seed for sampling, error conditions if signal not loaded or lacks sampling rate. It also notes ctx is unused, providing logging context. This compensates for the lack of annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with narrative and explicit args/returns/raises sections. It is slightly redundant (e.g., default segment duration appears twice) but every section adds needed clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers prerequisites, parameter semantics, return value, and exceptions. Given the output schema exists and the tool has 4 params, this description is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no parameter descriptions (0% coverage), but the description explains every parameter's purpose, default, and special values (e.g., segment_duration=None for full signal, random_seed determinism). This fully compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb-resource statement: 'Perform FFT analysis on a stored signal.' It elaborates on the purpose (time to frequency domain, harmonic detection) but doesn't explicitly differentiate among sibling analysis tools like compute_spectrogram_stft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use it: for identifying harmonic components and faults manifesting at specific frequencies. It also specifies the prerequisite that the signal must be loaded via load_signal() first. However, it doesn't discuss alternatives or exclusion criteria, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyze_signal_trendA
Within-recording screening: feature trend + degradation onset.
THE unified screening tool: feature trend AND degradation
onset in one call. Segments a single recording
(seconds of data), extracts the requested feature per segment,
tests whether the per-segment values show a statistically
significant trend (slope p < 0.05), and detects the first segment
AFTER the baseline window (first half of the series) whose value
exceeds baseline mean + onset_threshold_sigma standard deviations.
Onset inside the baseline window cannot be detected (the baseline
defines "normal"). Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
This is a SCREENING tool, not a prognosis: a trend inside seconds
of signal says whether the recording is stationary, not how long
the machine will live. For Remaining Useful Life, collect repeated
measurements over days/weeks (one recording per session) and pass
them to estimate_rul — this tool returns the per-segment feature
series so each recording can be reduced to one measurement point.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of the stored signal (from load_signal).
feature_name: Time-domain feature to analyze (default: "rms").
segment_duration: Duration of each segment in seconds.
overlap_ratio: Overlap between segments (0-1).
onset_threshold_sigma: Baseline standard deviations above the
baseline mean that trigger onset detection (default: 3.0).
Returns:
TrendAnalysisResult with slope, direction (p-value based),
fit quality, the (truncated) per-segment feature series, and
the onset-detection outcome (onset_detected,
onset_segment_index, onset_time_s, baseline_segments).
Raises:
ValueError: If the signal_id is not loaded, or the stored
signal has no sampling rate.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes | ||
| feature_name | No | rms | |
| overlap_ratio | No | ||
| segment_duration | No | ||
| onset_threshold_sigma | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| slope | Yes | Trend slope in feature units per second (within the recording) |
| p_value | No | Two-sided p-value of the slope (None when not computable) |
| intercept | Yes | Trend intercept |
| r_squared | Yes | R-squared goodness of fit of the linear trend |
| feature_name | Yes | Feature analyzed |
| num_segments | Yes | Number of segments analyzed |
| onset_time_s | No | Center time (s) of the onset segment within the recording |
| analysis_scope | Yes | Always 'within_recording_screening': this trend spans seconds of one recording, not the machine's life |
| feature_series | Yes | Per-segment feature values (evenly subsampled to at most 50 points). One recording yields ONE point for estimate_rul (e.g. the recording's overall feature value) — accumulate recordings over time to build its input series. |
| onset_detected | Yes | Whether a degradation onset was detected after the baseline window (first value exceeding baseline mean + onset_threshold_sigma * std) |
| segment_times_s | Yes | Segment center times in seconds for feature_series (same subsampling) |
| trend_direction | Yes | increasing, decreasing, or stable — based on the slope significance test (p < 0.05), not on an R-squared cutoff |
| series_truncated | Yes | True when feature_series was subsampled to the 50-point cap |
| baseline_segments | Yes | Number of leading segments used as the baseline window. Onset is only searched AFTER this window; degradation starting inside the baseline cannot be detected by this method. |
| onset_segment_index | No | Segment index where degradation starts (always >= baseline_segments); None when no onset detected |
| onset_threshold_sigma | Yes | Baseline standard deviations used as the onset trigger |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does so thoroughly: it explains the statistical test (slope p < 0.05), the onset detection logic (segment after baseline, baseline mean plus threshold standard deviations), the limitation that onset inside the baseline cannot be detected, and the prerequisite of a loaded signal with sampling rate. It also discloses that ctx is unused and the error conditions that raise ValueError. This is exemplary transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a summary, methodology explanation, usage caveats, and Args/Returns/Raises sections. It is front-loaded with the core purpose. However, there is minor redundancy between the first sentence and the second ('Within-recording screening...' and 'THE unified screening tool: feature trend AND degradation onset in one call.'). Overall, it is appropriately sized for the tool's complexity, but slightly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of annotations, and the bare schema, the description is exceptionally complete. It covers the algorithm, statistical methods, input requirements, output structure, error conditions, and usage caveats. It even explains why this is a screening tool and how to use it for RUL, leaving no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. The Args section provides clear semantic meaning for each parameter: signal_id is the ID from load_signal, feature_name is a time-domain feature with default 'rms', segment_duration is in seconds, overlap_ratio is a 0-1 ratio, and onset_threshold_sigma is the number of standard deviations above the baseline mean. This fully compensates for the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific and informative summary: 'Within-recording screening: feature trend + degradation onset.' It clearly states the tool's function: segmenting a recording, extracting features, testing for statistical trends, and detecting onset. It also distinguishes itself from sibling tools by positioning itself as 'THE unified screening tool' and explicitly contrasting with estimate_rul for prognosis, making its unique purpose clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage guidance is explicit: it states the tool is for screening within a single recording, not for prognosis, and directs users to estimate_rul for Remaining Useful Life. It also notes the prerequisite of calling load_signal() first and explains how to use the per-segment series for RUL analysis. This clearly tells the agent when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyze_statisticsA
Calculate statistical parameters of a stored signal for diagnostics.
Statistical parameters are key indicators for diagnostics:
- RMS: Effective value, correlated to signal energy
- Crest Factor: Indicates presence of impulses (high = possible faults)
- Kurtosis: Measures impulsiveness (excess kurtosis; >0 = non-Gaussian, >3 = strong impulses)
- Peak-to-Peak: Signal range
Requires the signal loaded via load_signal() first. Statistical
parameters are screening indicators, not definitive diagnostics —
combine with frequency-domain evidence.
**Signal units:** all values are in the signal's native unit. The unit
is reported only when DECLARED — load_signal(signal_unit=...) or the
companion _metadata.json — and never guessed from signal amplitude.
ISO 20816-3 severity tools refuse to produce a verdict until the unit
is declared.
Args:
signal_id: ID of the stored signal (from load_signal).
Returns:
StatisticalResult with all statistical parameters
Raises:
ValueError: If the signal_id is not loaded.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| rms | Yes | Root Mean Square (effective value) |
| mean | Yes | Mean value |
| peak | Yes | Peak value |
| std_dev | Yes | Standard deviation |
| kurtosis | Yes | Kurtosis (measure of impulsiveness) |
| skewness | Yes | Skewness (asymmetry) |
| unit_note | Yes | Unit declaration status and how to declare the unit for ISO severity assessment |
| signal_unit | No | Declared signal unit ('g', 'm/s2', 'mm/s', 'm/s') from companion metadata — never guessed from amplitude. None when not declared. |
| crest_factor | Yes | Crest Factor (Peak/RMS) |
| peak_to_peak | Yes | Peak-to-peak value |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels. It discloses that the signal must be loaded first, that units are only reported when declared (and never guessed), that severity tools need unit declaration, and that a ValueError is raised for unloaded signal IDs. It also explains the diagnostic meaning of each output parameter, going far beyond a basic 'calculate' operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening line, a helpful bullet list of statistical parameters, and concise Args/Returns/Raises sections. Every sentence adds value: the parameter explanations inform interpretation, and the unit caveat prevents misuse. It is appropriately sized for a diagnostics tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter, the presence of an output schema (StatisticalResult), and no annotations, the description is remarkably complete. It covers prerequisites, limitations, unit handling, error cases, and the nature of the results. No critical contextual gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only provides type/title for signal_id, but the description adds essential semantics: 'ID of the stored signal (from load_signal)' and explicitly ties it to the load_signal prerequisite. It also states the ValueError condition, clarifying that the parameter must reference a previously loaded signal. This fully compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Calculate statistical parameters of a stored signal for diagnostics.' It uses a specific verb (calculate), identifies the resource (statistical parameters of a stored signal), and distinguishes itself from siblings like analyze_fft (frequency-domain) and check_bearing_faults (fault-specific) by focusing on statistical indicators.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: 'Requires the signal loaded via load_signal() first' and 'Statistical parameters are screening indicators, not definitive diagnostics — combine with frequency-domain evidence.' This states when to use the tool, a prerequisite, and a clear recommendation to pair with alternative frequency-domain analysis, fulfilling the when/when-not/alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assess_severityA
Assess vibration severity (ISO 20816-3 zones A-D) and alert level.
THE unified severity tool: ISO zone assessment and alert
classification in one call. Zone boundary values are those of
ISO 10816-3:2009 (ISO 20816-3:2022 merges zones A/B — provenance is
noted in the result). Scope: machines rated above 15 kW; a declared
machine_power_kw below 15 kW is refused.
Input routes (exactly ONE required):
- signal_id: a stored signal (load_signal first). Sampling rate AND
declared unit come from the stored metadata; an undeclared unit is
refused, never guessed from amplitude.
- rms_velocity_mm_s: a direct broadband RMS velocity reading in mm/s
(e.g. from a portable instrument) — no unit declaration needed.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of the stored signal (mutually exclusive with
rms_velocity_mm_s).
rms_velocity_mm_s: Direct broadband RMS velocity in mm/s
(mutually exclusive with signal_id).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW).
Ignored when custom thresholds are given. Default 2.
support_type: 'rigid' or 'flexible'. Ignored when custom
thresholds are given. Default 'rigid'.
thresholds: Optional custom zone boundaries {'warning': A/B,
'alarm': B/C, 'danger': C/D} in mm/s, strictly increasing —
replaces the ISO table for this call.
machine_power_kw: Rated machine power, if known. Declared values
below 15 kW are refused (out of ISO scope); None means
unknown and is not refused.
rpm: Operating speed in RPM (signal route only: selects the 2 Hz
band lower edge below 600 RPM).
Returns:
VibrationSeverityResult (status='assessed') with zone, severity,
boundaries, derived alert_level/exceeded_threshold, and threshold
provenance.
Raises:
ValueError: On route misuse (both/neither inputs), undeclared
signal unit, missing sampling rate, Nyquist below the ISO
band, declared power below 15 kW, negative RMS, or invalid
custom thresholds.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | No | ||
| signal_id | No | ||
| thresholds | No | ||
| support_type | No | rigid | |
| machine_group | No | ||
| machine_power_kw | No | ||
| rms_velocity_mm_s | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| axis | No | Measurement axis (informational) |
| zone | Yes | ISO zone: A, B, C, or D |
| status | No | Always 'assessed' — discriminates from a refused result |
| signal_id | No | Signal identifier used (None for a direct rms_velocity_mm_s reading) |
| boundaries | Yes | Zone boundaries {AB, BC, CD} in mm/s (ISO or custom) |
| color_code | Yes | green, yellow, orange, or red |
| alert_level | No | Alert level derived from the zone: A=none, B=warning, C=alarm, D=danger (filled automatically) |
| support_type | Yes | Support type: 'rigid' or 'flexible' |
| machine_group | Yes | ISO 20816-3 machine group: 1 (large, >300 kW) or 2 (medium, 15-300 kW) |
| original_unit | No | Original signal unit before conversion |
| severity_level | Yes | Good, Acceptable, Unsatisfactory, or Unacceptable |
| frequency_range | Yes | Actual evaluation band used (may be narrower than the ISO nominal 10-1000 Hz when fs limits it); 'not applicable' for direct RMS readings |
| machine_power_kw | No | Declared rated machine power in kW, when provided. Values below 15 kW are refused as out of ISO 20816-3 scope. |
| zone_description | Yes | Zone description |
| rms_velocity_mm_s | Yes | RMS velocity in mm/s |
| exceeded_threshold | No | The boundary (mm/s) exceeded by the reading (None in zone A; filled automatically from zone + boundaries) |
| operating_speed_rpm | No | Operating speed in RPM, when provided (selects the band's lower edge) |
| threshold_provenance | Yes | Provenance of the zone boundary values (ISO edition note, or custom-threshold note) |
| unit_conversion_performed | Yes | Whether acceleration-to-velocity conversion was done |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full transparency burden and excels: it covers unit handling (never guessed), standard provenance, mutual exclusivity, custom threshold behavior, rpm band selection, refusal conditions, and detailed ValueError cases. It even notes that ctx is unused and references logging. This is exemplary behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, input routes, args, returns, raises) and front-loaded. It is long but justified given complexity. Minor redundancy exists: signal_id and rms_velocity_mm_s are described both in 'Input routes' and 'Args,' but this aids readability rather than wasting space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, two usage routes, custom thresholds, and many error conditions, the description covers everything needed: prerequisites, metadata requirements, return structure (VibrationSeverityResult fields), and error cases. The presence of an output schema further reduces the need to explain return values, and the description still lists key output fields. Complete for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain all 7 parameters. It does so thoroughly: mutual exclusion, defaults, units, custom threshold structure, power refusal, and conditional behavior (e.g., 'Ignored when custom thresholds are given'). Every parameter's meaning is expanded well beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: 'Assess vibration severity (ISO 20816-3 zones A-D) and alert level.' It clearly defines the tool's purpose and standard, and positions itself as 'THE unified severity tool,' distinguishing it from other analysis and reporting tools in the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: it explains the two mutually exclusive input routes (signal_id vs. rms_velocity_mm_s), requires 'exactly ONE,' and notes prerequisites like 'load_signal first.' It also defines scope with the >15 kW refusal. However, it does not explicitly name alternative tools to avoid using, so it misses the 'versus alternatives' clause.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_bearing_characteristic_frequenciesA
Calculate bearing characteristic frequencies from geometry.
Standard rolling-element kinematic formulas (Randall & Antoni 2011,
"Rolling element bearing diagnostics — A tutorial", MSSP 25(2)).
Requires the EXACT geometry — from the manual, the catalog
(search_bearing_catalog), or the user; never guessed. Deep-groove
ball bearings have contact_angle_deg = 0.
Args:
num_balls: Number of rolling elements (Z)
ball_diameter_mm: Ball/roller diameter (Bd) in mm
pitch_diameter_mm: Pitch circle diameter (Pd) in mm
contact_angle_deg: Contact angle (alpha) in degrees
rpm: Shaft rotation speed in RPM
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with BPFO, BPFI, BSF, FTF in Hz.
Example:
>>> # 6205 geometry (CWRU Bearing Data Center) at 1797 RPM
>>> freqs = calculate_bearing_characteristic_frequencies(
... num_balls=9, ball_diameter_mm=7.94,
... pitch_diameter_mm=39.04, rpm=1797
... )
>>> round(freqs['BPFO'], 2)
107.36
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | No | ||
| num_balls | Yes | ||
| ball_diameter_mm | Yes | ||
| contact_angle_deg | No | ||
| pitch_diameter_mm | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently specifies the exactness requirement ('never guessed'), identifies the formula source, states that ctx is unused, and lists the return dictionary. This is solid but not exhaustive; it omits error conditions or edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the purpose. Each section—usage note, args, returns, example—earns its place. The example is relevant and compact, showing a typical call and output. No redundancy; length is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema, the description need not elaborate on return values, but it still notes they are in Hz. It covers input sourcing, formula reference, defaults, and includes a worked example. Missing are the physical meanings of each characteristic frequency and any valid range or error handling, but for a calculation tool this is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates by providing symbols, meanings, and units for every parameter (e.g., 'num_balls: Number of rolling elements (Z)'). It also clarifies the default for contact_angle_deg and notes ctx is unused. This is exemplary parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Calculate bearing characteristic frequencies from geometry.' It names the exact outputs (BPFO, BPFI, BSF, FTF) and cites a standard reference, making its purpose unmistakable and distinct from sibling analysis tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states when it should be used: when exact geometry is available from the manual, catalog, or user, and cautions against guessing. It also notes the deep-groove ball bearing contact angle default. However, it does not explicitly mention when not to use it or propose alternatives, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_bearing_faultsA
Check expected fault frequencies in a stored signal's envelope spectrum.
THE unified bearing-check tool: catalog lookup, explicit
frequencies, or explicit geometry in one call. Requires the signal
loaded via load_signal() first.
Expected-frequency routes (exactly ONE required):
- bearing_id: catalog lookup (verified entries only) — BPFO/BPFI/BSF/
FTF computed from the catalog geometry; the entry's source citation
is echoed in the result.
- frequencies: explicit {label: hz} dict — for bearings not in the
catalog or non-bearing checks such as a gearbox GMF
(e.g. {"GMF": 350.0}). Labels BPFO/BPFI/BSF/FTF map to the
canonical fault vocabulary; other labels have no canonical form.
- explicit geometry: num_balls + ball_diameter_mm + pitch_diameter_mm
(+ contact_angle_deg) — frequencies computed from user-provided
geometry (out-of-catalog path).
Each check reports fault_type_canonical (outer_race / inner_race /
ball / cage) alongside the acronym.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of the stored signal.
rpm: Shaft speed in RPM.
bearing_id: Bearing designation (e.g. '6205', 'SKF 6205-2RS').
frequencies: Explicit expected frequencies {label: hz}, all > 0.
num_balls: Number of rolling elements (explicit-geometry route).
ball_diameter_mm: Ball/roller diameter Bd in mm.
pitch_diameter_mm: Pitch circle diameter Pd in mm.
contact_angle_deg: Contact angle in degrees (default 0.0).
tolerance_pct: Frequency matching tolerance in percent (default 5).
Returns:
BearingFaultsSummary with one check per expected frequency,
overall assessment, most likely fault (+ canonical form), and the
provenance of the expected frequencies (`source`).
Raises:
ValueError: If the signal is not loaded / has no sampling rate, if
not exactly one route is given, if the geometry is incomplete,
if the bearing is not in the catalog, or if frequencies is
empty / non-positive.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | Yes | ||
| num_balls | No | ||
| signal_id | Yes | ||
| bearing_id | No | ||
| frequencies | No | ||
| tolerance_pct | No | ||
| ball_diameter_mm | No | ||
| contact_angle_deg | No | ||
| pitch_diameter_mm | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| rpm | Yes | Shaft speed (RPM) |
| source | No | Provenance of the expected frequencies: the catalog entry's source citation (bearing_id route), or a note for user-provided geometry/frequencies |
| signal_id | Yes | Signal identifier used |
| bearing_id | No | Bearing designation (catalog route); None for the explicit-frequencies and explicit-geometry routes |
| fault_checks | Yes | Results for each checked frequency |
| most_likely_fault | No | Most likely fault label if any |
| overall_assessment | Yes | Summary assessment text |
| shaft_frequency_hz | Yes | Shaft frequency (Hz) |
| bearing_frequencies | Yes | Expected frequencies checked (Hz), plus shaft_freq_hz |
| most_likely_fault_canonical | No | Canonical form of most_likely_fault (None for arbitrary labels) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so thoroughly. It discloses route exclusivity, verified catalog entries, canonical fault vocabulary mapping, provenance echoing, return summary contents, and a comprehensive Raises section listing all error conditions. The only minor gap is not explicitly stating whether the envelope spectrum must be pre-computed or is computed internally, but this is not a significant omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with headers, bullet lists, and an Args section, front-loading the purpose in the first line. It is appropriately sized for a tool with 9 parameters and three routes. Minor redundancy exists (e.g., route descriptions partly restated in Args), and the internal note about ctx being unused is extra detail that an agent doesn't need for selection/invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity, missing annotations, and empty schema descriptions, the description covers all essential aspects: what the tool does, prerequisites, route selection rules, parameter meanings, return type (BearingFaultsSummary with provenance), and error behavior. The output schema exists and is well-summarized, so no further return-value detail is necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no parameter descriptions (0% coverage), but the description's Args section thoroughly compensates. It provides units (RPM, mm, Hz, percent), defaults (contact_angle_deg=0, tolerance_pct=5), constraints (frequencies all > 0), and explains the role of each parameter within the three routes, including an example dictionary. This is far beyond what the bare schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence clearly states the verb and resource: 'Check expected fault frequencies in a stored signal's envelope spectrum.' It also brands itself as 'THE unified bearing-check tool' and enumerates three distinct routes, which distinguishes it from siblings like calculate_bearing_characteristic_frequencies and analyze_envelope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the prerequisite (signal loaded via load_signal()) and that exactly one expected-frequency route must be provided. It explains when to use each route: catalog lookup for verified bearings, explicit frequencies for non-catalog or non-bearing checks like gearbox GMF, and explicit geometry for out-of-catalog cases. However, it does not explicitly contrast with sibling tools such as calculate_bearing_characteristic_frequencies, so it lacks a direct when-not-to-use statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_signalsA
Remove one signal — or all signals — from the in-memory repository.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID to remove; None (default) clears the whole cache.
Returns:
Dict with cleared_count, plus signal_id and status ('removed' or
'not_found') for single-signal calls.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for disclosing behavior. It clearly states the destructive nature ('Remove', 'clears the whole cache') and clarifies that operations affect only the in-memory repository. It also explains the return dict (cleared_count, signal_id, status), which is valuable behavioral context beyond what the schema provides. Minor gap: it doesn't explicitly state whether removed signals are recoverable, but the in-memory qualifier helps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and concise. It starts with a clear one-sentence purpose, then follows with an Args section and Returns section. Every sentence adds useful information — even the note about `ctx` being unused is relevant for understanding behavior. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, output schema present), the description is complete. It covers purpose, parameter semantics, return values, and the in-memory scope. The output schema fills in the exact return structure, so the description doesn't need to repeat it. For a destructive tool with no annotations, it sufficiently informs the agent about behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema for signal_id is bare (no description, 0% coverage), but the description adds crucial meaning: 'ID to remove; None (default) clears the whole cache.' This explains the parameter's semantics, default behavior, and the distinction between removing a specific signal versus all signals. Without this, the schema alone would be ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Remove one signal — or all signals — from the in-memory repository.' It clearly states the action (removing signals) and the scope (in-memory repository), distinguishing it from sibling tools like get_signal_info, list_signals, and generate_test_signal which are non-destructive.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: use this tool when you need to delete signals or clear the cache. It provides context about the default behavior (None clears the whole cache) but does not explicitly mention alternatives or when not to use it. Given that no other removal tool exists among siblings, the guidance is implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_power_spectral_densityA
Compute Power Spectral Density (Welch method) for a stored signal.
Requires signal loaded via load_signal() first.
Args:
signal_id: ID of the stored signal.
nperseg: Samples per FFT segment (default 256).
noverlap: Overlap between segments (default 128).
window: Window function (default 'hann').
| Name | Required | Description | Default |
|---|---|---|---|
| window | No | hann | |
| nperseg | No | ||
| noverlap | No | ||
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| window | Yes | Window function used |
| nperseg | Yes | Samples per segment |
| noverlap | Yes | Overlap between segments |
| signal_id | Yes | Signal identifier used |
| top_peaks | Yes | Top spectral peaks by power |
| num_samples | Yes | Number of samples analyzed |
| total_power | Yes | Total integrated power |
| freq_range_hz | Yes | [min_freq, max_freq] |
| sampling_rate | Yes | Sampling rate (Hz) |
| frequency_resolution | Yes | Frequency resolution (Hz) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It mentions the Welch method and the load_signal prerequisite, but does not describe potential errors, side effects (likely none), or output specifics. Given that an output schema exists, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a one-line summary, a prerequisite, and a clearly formatted Args list. Every sentence contributes useful information with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema, return values are covered. The description includes the essential prerequisite and parameter semantics, enough for a moderate-complexity tool with 4 parameters. However, it omits edge-case behavior (e.g., invalid signal_id, constraints on nperseg Vs noverlap), so a 4 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description's Args section fully compensates by explaining each parameter's meaning (samples per FFT segment, overlap, window function) and listing defaults. This adds significant value beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Compute Power Spectral Density (Welch method) for a stored signal' with a specific verb, resource, and method. It distinguishes this from sibling tools like compute_spectrogram_stft and analyze_fft, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear prerequisite ('Requires signal loaded via load_signal() first'), establishing context for when the tool should be used. However, it does not explicitly contrast with alternatives or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_spectrogram_stftA
Compute STFT spectrogram for a stored signal.
Returns time-frequency summary (no full 2D array). Use for detecting
time-varying frequency content (transient faults, speed changes).
Args:
signal_id: ID of the stored signal.
nperseg: Samples per STFT segment (default 256).
noverlap: Overlap between segments (default 128).
window: Window function (default 'hann').
| Name | Required | Description | Default |
|---|---|---|---|
| window | No | hann | |
| nperseg | No | ||
| noverlap | No | ||
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| window | Yes | Window function used |
| nperseg | Yes | Samples per segment |
| noverlap | Yes | Overlap between segments |
| signal_id | Yes | Signal identifier used |
| num_samples | Yes | Number of samples analyzed |
| time_range_s | Yes | [start_time, end_time] |
| freq_range_hz | Yes | [min_freq, max_freq] |
| num_freq_bins | Yes | Number of frequency bins |
| num_time_bins | Yes | Number of time bins |
| sampling_rate | Yes | Sampling rate (Hz) |
| energy_per_band | Yes | Energy in predefined frequency bands |
| max_power_time_s | Yes | Time of maximum power |
| max_power_freq_hz | Yes | Frequency with maximum power |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses a key behavioral trait: the return is a time-frequency summary, not a full 2D array. However, it does not mention side effects, prerequisites (e.g., signal must exist), or potential errors, which are relevant for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately concise: a short purpose statement, a usage note, and a bulleted parameter list. No redundant sentences; every element contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, return values do not need explanation. The description covers purpose, usage, and parameters adequately. It could add constraints or error conditions, but for a compute tool with this schema richness, it is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains all four parameters: signal_id, nperseg, noverlap, and window, including defaults. It does not cover constraints like nperseg > noverlap or valid window types, but it provides enough meaning for basic usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool computes an STFT spectrogram for a stored signal, using a specific verb and resource. It also distinguishes itself from siblings by emphasizing time-frequency analysis and noting the output is a summary, not a full 2D array.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use it: 'Use for detecting time-varying frequency content (transient faults, speed changes).' Does not explicitly mention alternatives or exclusions, but the context and sibling names make alternatives clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnose_vibrationA
Full integrated diagnosis: FFT + PSD + STFT + bearing faults + ISO severity.
Comprehensive vibration diagnostic pipeline. Loads signal from repository,
runs all analyses, and synthesizes results into an actionable report.
The ISO severity block uses ISO 20816-3 machine group/support type
(zone boundaries from ISO 10816-3:2009, provenance noted in output).
The diagnosis DEGRADES instead of failing when the ISO verdict cannot
be produced honestly: if the stored signal has no declared unit (or
the sampling rate cannot cover the ISO evaluation band), the
iso_severity block is a structured refusal (status='refused' with
reason and remedy) while the spectral, bearing, and anomaly blocks
still run. Units are never guessed from amplitude — declare them via
load_signal(signal_unit=...) or the companion _metadata.json.
Args:
signal_id: ID of the stored signal.
rpm: Machine operating speed in RPM.
bearing_id: Bearing designation for fault detection (optional).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW).
Default 2.
support_type: 'rigid' or 'flexible'. Default 'rigid'.
Raises:
ValueError: If the stored signal has no sampling rate.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | Yes | ||
| signal_id | Yes | ||
| bearing_id | No | ||
| support_type | No | rigid | |
| machine_group | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| rpm | Yes | Machine speed (RPM) |
| signal_id | Yes | Signal identifier used |
| bearing_id | No | Bearing used (if any) |
| fft_summary | Yes | FFT key findings |
| psd_summary | Yes | PSD key findings |
| iso_severity | Yes | ISO severity assessment, or a structured refusal (status='refused' with reason + remedy) when the verdict cannot be produced honestly — e.g. undeclared signal unit or Nyquist below the ISO evaluation band. The other diagnosis blocks (spectral, bearing, anomaly) still run. |
| stft_summary | Yes | STFT key findings |
| support_type | Yes | Support type used for severity: 'rigid' or 'flexible' |
| machine_group | Yes | ISO 20816-3 machine group used for severity: 1 (large) or 2 (medium) |
| bearing_faults | No | Bearing fault results |
| recommendations | Yes | Recommended actions |
| anomaly_detection | No | Anomaly detection results (health, ratio, score) |
| evidence_strength | Yes | Strength of corroborating fault evidence: 'none', 'weak', 'moderate', or 'strong'. Derived from the number and quality of independent findings (bearing fault frequency matches, shaft signatures, anomaly detection, ISO severity) — NOT from severity alone and NOT a probability. 'none' means no fault evidence was found (machine appears healthy). |
| overall_diagnosis | Yes | Combined diagnostic text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral burden. It thoroughly discloses the graceful degradation behavior, structured refusal for ISO severity (status='refused' with reason and remedy), the rule of never guessing units, and the ValueError condition. This gives the agent critical runtime expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a summary line, detailed behavior explanation, and an Args block. It is lengthy but every sentence provides necessary information. The only minor loss is slight redundancy in the ISO severity explanation, but it remains readable and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and that an output schema exists, the description covers purpose, parameters, behavioral edge cases, error conditions, and output semantics (e.g., the iso_severity block). It leaves no critical ambiguity for an agent deciding to use or invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains every parameter: signal_id, rpm, bearing_id, machine_group, support_type, including enum meanings, defaults, and how to properly declare units via load_signal. This is essential context the schema alone lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Full integrated diagnosis' and lists specific analyses (FFT, PSD, STFT, bearing faults, ISO severity), clearly stating the tool's role as a comprehensive pipeline. This distinguishes it from sibling tools like analyze_fft or compute_power_spectral_density, which are single-purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for complete vibration diagnosis, mentioning loading signals from the repository and synthesizing results into an actionable report. It does not explicitly name alternatives or state when not to use this tool, but the 'full integrated' framing provides clear context for its primary use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
estimate_rulA
Estimate Remaining Useful Life from repeated measurements over time.
RUL is only physically meaningful when fitted on a degradation trend
across MULTIPLE measurements of the same machine taken at different
times (days/weeks/months apart). This tool refuses a single
recording or single point — for within-recording screening use
analyze_signal_trend instead.
Two mutually exclusive input routes (both need `timestamps`, one
entry per measurement, strictly increasing, in `time_unit`):
1. `feature_values`: the degradation indicator already measured
externally (e.g. RMS velocity trended by a data collector).
2. `signal_ids`: one stored signal per measurement session (loaded
via load_signal); each recording is reduced to a single
`feature_name` value.
The degradation indicator is assumed to RISE toward
`failure_threshold`. A statistically significant increasing trend
(slope p-value < 0.05) is required before any RUL is computed; a
flat/insignificant series returns status 'no_degradation_trend'
with no RUL number.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
failure_threshold: Indicator value considered as failure, in the
same units as the feature values. No universal default is
imposed — but when the indicator is broadband VELOCITY RMS
in mm/s, the standard choice is the ISO 10816-3:2009 zone
C/D boundary that assess_severity / get_zone_boundaries()
reports for the machine's group and support (single source
of truth — no boundaries restated here).
timestamps: Measurement times in `time_unit`, strictly
increasing (e.g. hours since first measurement).
feature_values: Indicator values, one per measurement
(mutually exclusive with signal_ids).
signal_ids: Stored signal IDs, one per measurement session
(mutually exclusive with feature_values).
feature_name: Time-domain feature used to reduce each signal
(default: "rms"). Ignored for feature_values input.
method: "linear" (default), "exponential", or "kalman"
(kalman needs approximately uniform measurement spacing).
time_unit: Label for the time axis; RUL and
observation_horizon are expressed in this unit.
Returns:
RULEstimationResult with status, rul (only when estimated),
fit_r_squared (goodness of fit — NOT a confidence),
observation_horizon, and a plain-language message.
| Name | Required | Description | Default |
|---|---|---|---|
| method | No | linear | |
| time_unit | No | hours | |
| signal_ids | No | ||
| timestamps | Yes | ||
| feature_name | No | rms | |
| feature_values | No | ||
| failure_threshold | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| rul | No | Estimated remaining useful life in time_unit (only when status='estimated') |
| method | Yes | Estimation method used: linear, exponential, or kalman |
| status | Yes | 'estimated' (RUL computed), 'no_degradation_trend' (no statistically significant trend toward the threshold — healthy outcome, no RUL number), or 'threshold_already_exceeded' (last measurement is at/above the failure threshold). |
| message | Yes | Human-readable explanation of the outcome and its caveats |
| time_unit | Yes | Unit of timestamps, observation_horizon, and rul |
| feature_name | Yes | Degradation indicator tracked (e.g. 'rms') |
| current_value | Yes | Most recent measured indicator value |
| fit_r_squared | No | R-squared of the fitted degradation curve on the observed data. Goodness of fit only — NOT a confidence or probability. None for the kalman method. |
| trend_p_value | No | Two-sided p-value of the series' linear slope (None when not computable). The trend gate requires p < 0.05. |
| estimated_rate | No | Estimated degradation rate in feature units per time_unit (linear/kalman) |
| rul_interval_95 | No | [lower, upper] approximate 95% interval from the delta-method variance (kalman only). Coverage not validated — treat as an order-of-magnitude band. |
| num_measurements | Yes | Number of measurements in the series |
| failure_threshold | Yes | Indicator value considered as failure |
| observation_horizon | Yes | Time span covered by the measurement series (last minus first timestamp), in time_unit. RUL estimates far beyond this horizon are extrapolations with low reliability. |
| precision_heuristic | No | Heuristic in [0,1]: 1 - rul_std/rul, clipped (kalman only). This is a heuristic, NOT a statistical confidence — do not present it as a probability of correctness. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure and does so thoroughly. It discloses that the tool refuses single-point input, requires a statistically significant increasing trend (p<0.05), and returns status 'no_degradation_trend' otherwise. It also explains the assumption that the indicator rises toward the failure threshold, defines fit_r_squared as not a confidence measure, and references ISO 10816-3 boundaries externally, leaving no hidden behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured, with clear sections for purpose, usage restrictions, input routes, behavioral assumptions, parameter details, and return values. Each sentence contributes necessary information given the complexity of the tool (7 parameters, nuanced degradation logic). It could be slightly tightened, but the length is justified and the front-loaded purpose statement ensures immediate clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high complexity of the tool, an output schema presence, and no annotations, the description is exceptionally complete. It covers prerequisites (multiple measurements), input alternatives, statistical requirements, parameter semantics, and return behavior (status, rul conditional, observation_horizon). The only missing detail is the exact shape of the output object, but that is covered by the output schema, so the description meets the completeness bar.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides zero parameter descriptions, so the description must compensate fully—and it does. Each parameter is explained with its role, units, defaults, and constraints: failure_threshold in same units as feature values, timestamps strictly increasing, feature_values and signal_ids mutually exclusive, feature_name default 'rms' and ignored for feature_values, method enum with linear default and kalman spacing requirement, time_unit as the label for RUL expression. This adds substantial meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource statement: 'Estimate Remaining Useful Life from repeated measurements over time.' It explicitly distinguishes itself from the sibling tool analyze_signal_trend by stating it refuses single-point data, while also specifying that it operates on multi-session degradation trends. This gives the agent a precise understanding of the tool's scope and differentiates it from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance: it refuses a single recording or point and directs the agent to 'analyze_signal_trend instead' for within-recording screening. It also details two mutually exclusive input routes (feature_values vs signal_ids) and notes the condition that kalman needs approximately uniform measurement spacing, giving clear criteria for selecting this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_features_from_signalA
Extract time-domain features from a stored signal using sliding windows.
Segments the signal into overlapping windows and extracts 17 statistical features
from each segment. Features include: mean, std, RMS, kurtosis, crest factor, entropy, etc.
Requires the signal loaded via load_signal() first; the sampling rate
comes from the stored signal metadata. Returns an in-memory summary
only — no CSV is written to data/signals/.
Args:
signal_id: ID of the stored signal (from load_signal).
segment_duration: Duration of each segment in seconds (default: 0.1)
overlap_ratio: Overlap between segments, 0-1 (default: 0.5 = 50%)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
FeatureExtractionResult with features matrix and metadata
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
extract_features_from_signal(
"healthy_motor",
segment_duration=0.2,
overlap_ratio=0.5
)
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes | ||
| overlap_ratio | No | ||
| segment_duration | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| num_segments | Yes | Number of segments extracted |
| feature_names | Yes | Names of extracted features |
| overlap_ratio | Yes | Overlap ratio between segments |
| features_shape | Yes | Shape of feature matrix [num_segments, num_features] |
| features_preview | Yes | First 5 segments features (preview) |
| segment_duration_s | Yes | Duration of each segment in seconds |
| segment_length_samples | Yes | Samples per segment |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the requirement of a loaded signal and sampling rate from metadata, the return type (FeatureExtractionResult), potential ValueError conditions, and the side-effect of not writing CSV files. This gives a clear behavioral profile without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections for Args, Returns, Raises, and an Example. The opening sentence is concise, and each additional sentence provides necessary information about behavior, prerequisites, or errors—no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete enough for an agent to invoke the tool correctly. It covers prerequisites, parameter semantics, return type, error conditions, and includes an example. It does not need to explain the output schema in detail because an output schema is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates with an Args section explaining each parameter: signal_id is 'ID of the stored signal (from load_signal)', segment_duration is 'duration in seconds' with default 0.1, and overlap_ratio is 'overlap between segments, 0-1' with default 0.5. It also includes units and defaults beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Extract time-domain features from a stored signal using sliding windows.' It clearly distinguishes this from sibling tools like analyze_fft or compute_power_spectral_density by focusing on time-domain features and sliding-window segmentation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a clear prerequisite: 'Requires the signal loaded via load_signal() first.' It also notes that the tool returns an in-memory summary and explicitly says 'no CSV is written to data/signals/', signaling when not to use it if a file output is expected. However, it does not name alternative tools, so it falls short of explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_manual_specsA
Extract machine specifications from an equipment manual (PDF).
Extracts bearing designations (e.g. SKF 6205), operating speeds
(RPM), power ratings (kW/HP/MW), and a text excerpt. Results are
cached. If a bearing's geometry is not in the manual, follow up
with search_bearing_catalog(bearing_id=...); if it is not in the
catalog either, ask the user for the geometry — never invent it.
Args:
file_name: Manual filename in resources/machine_manuals/
use_cache: Use cached extraction if available (default: True)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with extracted specifications and text excerpt.
Raises:
FileNotFoundError: If the manual does not exist (the message
lists the available manuals).
| Name | Required | Description | Default |
|---|---|---|---|
| file_name | Yes | ||
| use_cache | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral transparency burden. It discloses caching, the 'never invent' constraint, and potential `FileNotFoundError`. It also clarifies that `ctx` is unused, which prevents confusion. It does not mention permissions or rate limits, but these are less critical for a PDF extraction tool. Overall, it provides solid behavioral context beyond what schema offers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately sized but well-organized into description, Args, Returns, and Raises sections. Each section adds value. The mention of `ctx` may be unnecessary since it's not in the schema, and the Returns section partly repeats the opening sentence. Still, the structure aids readability and nothing is extraneous.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description doesn't need to detail return values, but it does summarize them. It covers error handling with `FileNotFoundError` and mentions that the error message lists available manuals. It could have mentioned `list_machine_manuals` as a prerequisite, but the error handling covers discovery. Overall, it is sufficiently complete for a 2-parameter tool with an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description must explain parameters. It does: `file_name` specifies the location under `resources/machine_manuals/`, and `use_cache` explains caching behavior with its default. This adds meaningful semantics beyond the bare schema, which only shows types and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Extract') and resource ('machine specifications from an equipment manual (PDF)'), and enumerates example outputs (bearing designations, speeds, power ratings, text excerpt). It distinguishes itself from siblings like `search_bearing_catalog` by focusing on extraction from manuals, and from `read_manual_excerpt` by covering specifications rather than arbitrary excerpts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit follow-up guidance: if a bearing's geometry is not in the manual, use `search_bearing_catalog(bearing_id=...)`, and if not there either, ask the user—never invent. It also explains caching behavior and that `use_cache` controls it, which tells the agent when to disable caching. This makes usage context and alternatives clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_diagnostic_reportA
Generate the integrated diagnostic report — one document, whole case.
Runs the full diagnosis, then renders signal overview, ISO severity,
anomaly state, characteristic-frequency matching, spectral energy, an
annotated envelope spectrum, and recommended actions into a single
self-contained document.
AUTHORSHIP CONTRACT — this matters more than it may appear. Every
evaluative sentence in the returned ``statements`` list was written by
this server. Reuse them verbatim when presenting the result. Do NOT coin
standard names, machine classes, severity zones, or confidence levels of
your own: this server deliberately publishes no confidence figure, and
the standards caveat that travels with every severity verdict must not be
dropped or paraphrased. If a question is not answered by these
statements, say so rather than filling the gap.
Unlike ``generate_diagnostic_report_docx``, this tool takes no content
sections from the caller. Supply the analysis inputs; the wording is the
server's.
Args:
signal_id: ID of the stored signal (from load_signal).
rpm: Machine operating speed in RPM.
bearing_id: Bearing designation for characteristic-frequency
matching. Omitted means the matching section states why it was
not attempted rather than disappearing.
machine_group: ISO 20816-3 group — 1 (large, >300 kW) or 2 (medium,
15-300 kW). Default 2.
support_type: 'rigid' or 'flexible'. Default 'rigid'.
baseline_signal_id: Optional stored signal from the same machine in a
known-good state. Supplying it turns absolute readings into
deltas, which is what tells a reader whether a condition is new
or stable.
formats: Renderings to produce — any of 'html', 'pdf'. Defaults to
['html']. 'pdf' requires
``pip install predictive-maintenance-mcp[pdf]``.
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dict with ``statements`` (every authored sentence, in document
order), ``files`` (one entry per rendering), ``verdict``,
``evidence_strength``, and ``provenance``.
Raises:
ValueError: If a signal id is not loaded, has no sampling rate, or an
unsupported format is requested.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | Yes | ||
| formats | No | ||
| signal_id | Yes | ||
| bearing_id | No | ||
| support_type | No | rigid | |
| machine_group | No | ||
| baseline_signal_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden. It discloses the authorship contract, the absence of confidence figures, the requirement to preserve the standards caveat, and that the server alone writes evaluative sentences. It also documents exceptions and the pdf dependency, going well beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured into clear sections (summary, authorship contract, args, returns, raises) and, while long, every part serves a purpose for such a complex tool. The front-loaded summary gives immediate orientation without wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description is complete: it covers return semantics, exceptions, dependencies, and behavior for omitted parameters. It is fully self-sufficient and leaves no critical gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates with a detailed Args block explaining each parameter, including defaults, enum choices, and behavior for omitted bearing_id. This adds meaning far beyond the raw schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Generate the integrated diagnostic report — one document, whole case.' It enumerates the sections rendered and explicitly distinguishes itself from generate_diagnostic_report_docx by noting it takes no caller content sections.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly contrasts this tool with generate_diagnostic_report_docx, and explains when to supply baseline_signal_id for delta readings. The 'AUTHORSHIP CONTRACT' provides clear instructions on how to handle output, making the usage context thorough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_diagnostic_report_docxA
Generate a structured Word (.docx) diagnostic report for a stored signal.
Requires: ``pip install predictive-maintenance-mcp[docx]``
``sections`` is a dict whose keys define what to include (all optional):
- statistics: dict (RMS, Kurtosis, Crest Factor …)
- fft_peaks: list [{frequency, magnitude_db, note}, …]
- envelope_peaks: list [{frequency, magnitude_db, match}, …]
- bearing_frequencies: dict {BPFO, BPFI, BSF, FTF}
- iso: dict (mapped from assess_severity output)
- diagnosis: str (free-text diagnostic summary)
Args:
signal_id: ID of the stored signal (from load_signal); used for
the report title / filename.
sections: Content sections to include (see above)
title: Optional custom report title
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file_path, file_name, and per-section summary.
Raises:
ValueError: If the signal_id is not loaded, or python-docx is
not installed.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| sections | Yes | ||
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and meets it: it discloses prerequisites (pip install), error conditions (ValueError for missing signal or python-docx), the return type (dictionary with file_path, file_name, summary), and notes that ctx is unused. This exceeds typical transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening summary, a detailed but organized sections breakdown, and concise Args/Returns/Raises. Every sentence adds value, and the structure is front-loaded with the main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with nested objects, 3 parameters, and no annotations, the description is comprehensive: it covers prerequisites, errors, return format, and parameter details. The presence of an output schema does not reduce the need for this clarity, and the description fully delivers.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only types and a generic sections object, while the description supplies rich semantics: it enumerates the allowed section keys (statistics, fft_peaks, etc.), expected types and shapes, and explains how signal_id and title are used (report title/filename). This fully compensates for the 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Generate a structured Word (.docx) diagnostic report for a stored signal.' The .docx format and diagnostic report scope clearly distinguish it from sibling tools like generate_diagnostic_report or generate_fft_report, even without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states the prerequisite that the signal must be stored (from load_signal) and requires an install. It also clarifies that 'sections' is optional, implying usage context. However, it does not explicitly mention alternatives or when not to use, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_envelope_reportA
Generate professional envelope analysis report (HTML) for a stored signal.
Generates a professional HTML report file instead of inline content.
Saves to reports/ directory. Requires the signal loaded via
load_signal() first; the sampling rate comes from the stored signal
metadata. Reference bearing frequencies (BPFO/BPFI/BSF/FTF) can be
passed explicitly or, if omitted, are read from the source file's
companion _metadata.json when present.
Args:
signal_id: ID of the stored signal (from load_signal).
filter_low: Bandpass filter low cutoff (Hz). Default 500 Hz
filter_high: Bandpass filter high cutoff (Hz). Default (None)
adapts to the signal: min(5000, Nyquist-1). An explicit value
above Nyquist is rejected, never clamped.
max_freq: Max envelope spectrum frequency to display. Default 500 Hz
num_peaks: Number of peaks to detect. Default 15
bearing_freqs: Optional dict with BPFO, BPFI, BSF, FTF
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
>>> # Bearing frequencies computed for YOUR bearing/rpm (here: 6205
>>> # per CWRU geometry at 1797 RPM)
>>> result = generate_envelope_report(
... "real_train_OuterRaceFault_1",
... bearing_freqs={"BPFO": 107.36, "BPFI": 162.19, "BSF": 70.58, "FTF": 11.93}
... )
| Name | Required | Description | Default |
|---|---|---|---|
| max_freq | No | ||
| num_peaks | No | ||
| signal_id | Yes | ||
| filter_low | No | ||
| filter_high | No | ||
| bearing_freqs | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries the full burden and does so thoroughly. It discloses that the tool writes a file to reports/, depends on prior load_signal(), uses metadata for sampling rate, reads optional bearing_freqs from _metadata.json, rejects rather than clamps filter_high above Nyquist, and returns a dictionary without HTML content. It also lists exceptions and notes ctx is unused.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place. It front-loads the core purpose in the first line, then progressively provides necessary detail on prerequisites, parameters, returns, and exceptions. The example is compact and illustrative. There is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers prerequisites, side effects, return value format, error conditions, parameter defaults, and edge cases. Even though an output schema exists, it goes beyond that by explaining the dictionary structure. Given the tool's complexity (6 params, file output, dependencies), this is a complete and self-contained description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the Args section explains all six parameters with meanings, defaults, and constraints. For example, filter_high: 'Default (None) adapts to the signal: min(5000, Nyquist-1). An explicit value above Nyquist is rejected, never clamped.' The example also demonstrates bearing_freqs structure, fully compensating for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific statement: 'Generate professional envelope analysis report (HTML) for a stored signal.' It identifies the resource (envelope analysis report), format (HTML), and context (stored signal). This distinguishes it from sibling tools like generate_fft_report or generate_iso_report, and the phrase 'instead of inline content' further differentiates it from analyze_envelope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: it requires the signal to be loaded via load_signal() first, states that it saves to a reports/ directory, and explains how bearing frequencies are handled. It does not explicitly name alternatives or exclusion scenarios, but the prerequisites and output format give a solid sense of when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_feature_comparison_reportA
Generate feature comparison report with violin plots comparing time-domain features.
Creates interactive HTML report with violin plots showing distribution of 17
time-domain features across different signal groups (e.g., Healthy vs Faulty).
Requires every signal loaded via load_signal() first; each signal's
sampling rate comes from its stored metadata.
**Strategy**: Same HTML report approach as other reports. Useful for understanding
which features are most discriminative for fault detection.
Args:
signal_groups: Dictionary mapping group names to lists of stored
signal IDs.
Example: {"Healthy": ["real_train_baseline_1"],
"Faulty": ["real_train_OuterRaceFault_1"]}
segment_duration: Segment duration in seconds (default: 0.1s for ML)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
features_to_plot: List of feature names to plot (default: all 17 features)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file path, metadata, and summary
Raises:
ValueError: If a signal_id is not loaded or has no sampling rate.
Example:
>>> generate_feature_comparison_report(
... signal_groups={
... "Healthy": ["real_train_baseline_1", "real_train_baseline_2"],
... "Inner Fault": ["real_train_InnerRaceFault_vload_1"],
... "Outer Fault": ["real_train_OuterRaceFault_1"]
... }
... )
| Name | Required | Description | Default |
|---|---|---|---|
| overlap_ratio | No | ||
| signal_groups | Yes | ||
| features_to_plot | No | ||
| segment_duration | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of disclosing behavior. It states the tool creates an interactive HTML report, depends on signals' stored sampling-rate metadata, raises ValueError for unloaded signals, and returns a dictionary with file path, metadata, and summary. This provides meaningful context beyond the schema, though it does not detail filesystem side effects like overwrite behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: intro, strategy, args, returns, raises, and example. Every sentence provides value, the main purpose is front-loaded, and the example is compact yet illustrative. There is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 4 parameters, no annotations, and an output schema, the description covers prerequisites, dependencies on load_signal, return shape, error conditions, and a usage example. It also integrates with the sibling tool family by noting the shared HTML report approach. This is effectively complete for an agent to invoke and understand the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 0% description coverage, but the description's Args section thoroughly explains all four parameters, including defaults, types, and the signal_groups structure with a concrete example. It also clarifies the semantics of features_to_plot (null means all 17 features). This fully compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'generate feature comparison report with violin plots comparing time-domain features.' It clearly scopes the tool to comparing features across signal groups and differentiates it from sibling report generators like generate_fft_report or generate_envelope_report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states the tool requires signals loaded via load_signal() first and notes the shared 'same HTML report approach as other reports.' It implies usage is for feature discrimination analysis, but it does not explicitly state when NOT to use this tool versus alternatives, so it misses the 5-level criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_fft_reportA
Generate an interactive FFT spectrum report (HTML) for a stored signal.
Saves a self-contained Plotly HTML report (spectrum in dB, automatic
peak detection, harmonic labels) to the reports/ directory with a
timestamped filename — consecutive runs produce distinct files.
Requires the signal loaded via load_signal() first; the sampling
rate comes from the stored signal metadata.
Args:
signal_id: ID of the stored signal (from load_signal).
max_freq: Maximum frequency to display (Hz). Default 5000 Hz
num_peaks: Number of peaks to detect and label. Default 15
rpm: Optional shaft speed in RPM — peaks at integer multiples
of rpm/60 Hz are labeled as 1x/2x/... harmonics.
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | No | ||
| max_freq | No | ||
| num_peaks | No | ||
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool saves a self-contained Plotly HTML report to reports/ with timestamped filenames, consecutive runs produce distinct files, and the return value contains no HTML content (just path, metadata, summary). It also documents error conditions (ValueError for unloaded signal or missing sampling rate). This is extensive behavioral disclosure beyond what the schema provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a one-sentence summary, a prerequisite note, then Args/Returns/Raises sections. Every sentence adds useful information: file naming behavior, sampling rate source, parameter meanings, return structure, and error conditions. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 parameters, no annotations), the description fully covers the prerequisite (loaded signal), the output behavior (file path, metadata, summary), error conditions, and parameter semantics. It is complete enough for an agent to invoke the tool correctly and interpret the result without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, but the description compensates fully with an Args section explaining each parameter: signal_id, max_freq (with default), num_peaks (with default), rpm (with harmonic labeling semantics), and ctx (unused). It adds meaning beyond the schema by explaining the harmonic labeling behavior (rpm/60 Hz multiples as 1x/2x/...) and the default values for max_freq and num_peaks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Generate an interactive FFT spectrum report (HTML) for a stored signal.' This clearly distinguishes it from sibling report generators (envelope, ISO, PCA, etc.) by naming the FFT spectrum focus. The phrase 'FFT spectrum report' is unambiguous and aligns with the tool name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states a clear prerequisite: 'Requires the signal loaded via load_signal() first; the sampling rate comes from the stored signal metadata.' This gives the agent context on when the tool can be invoked. However, it doesn't explicitly contrast with alternatives like generate_envelope_report or analyze_fft, so it lacks explicit exclusions/alternative guidance. The context is strong enough to warrant a 4 rather than 3.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_iso_reportA
Generate an ISO 20816-3 evaluation report (HTML) for a stored signal.
Saves a self-contained Plotly HTML report (color-coded A-D zone
chart with the measured RMS marker, boundaries, severity text) to
the reports/ directory with a timestamped filename. The evaluation
itself is delegated to assess_severity — requires the signal loaded
via load_signal() first with sampling rate AND a declared unit
(units are never guessed).
Args:
signal_id: ID of the stored signal (from load_signal).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW)
support_type: 'rigid' or 'flexible'
rpm: Operating speed in RPM (optional; selects the ISO band's
lower edge below 600 RPM)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate or no declared unit.
| Name | Required | Description | Default |
|---|---|---|---|
| rpm | No | ||
| signal_id | Yes | ||
| support_type | No | rigid | |
| machine_group | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and delivers: it discloses the file side-effect (saves to reports/ with timestamped filename), chart contents, delegation to assess_severity, the 'units are never guessed' rule, return shape (dictionary with NO HTML content), and ValueError conditions for unloaded signals or missing sampling rate/unit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first line, followed by a clear Args/Returns/Raises structure that is scannable. The description is longer than average, but every sentence earns its place given zero schema descriptions — including the transparent note that ctx is unused.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema, no annotations, and 0% schema description coverage, this description is complete: it covers prerequisites, side-effects, error conditions, parameter meanings, delegation, and return shape. Nothing critical is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description compensates well: machine_group gets kW ranges (large >300 kW / medium 15-300 kW), rpm gets behavioral semantics (selects ISO band's lower edge below 600 RPM), and signal_id gets source context (from load_signal). support_type is merely repeated from the enum without explaining rigid vs flexible, leaving a minor gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Generate an ISO 20816-3 evaluation report (HTML) for a stored signal.' It further details the output (color-coded A-D zone chart with RMS marker, boundaries, severity text), which clearly distinguishes it from sibling report generators like generate_fft_report or generate_diagnostic_report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context is provided: the signal must be loaded via load_signal() first with sampling rate and a declared unit. It also notes the evaluation is delegated to assess_severity, implying that tool handles evaluation-only use cases. However, it does not explicitly name alternatives or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_maintenance_recommendationsA
Generate maintenance recommendations based on severity and detected faults.
Combines ISO zone-based urgency with fault-specific maintenance
actions. This tool intentionally does NOT accept a confidence
value: any number supplied by the caller would be echoed into
advisory output without evidential basis.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
severity_zone: ISO zone letter — "A", "B", "C", or "D".
fault_types: Detected fault types from the closed canonical
vocabulary — outer_race/inner_race/ball/cage for bearings
(NOT the BPFO/BPFI/BSF/FTF acronyms) plus misalignment/
unbalance/looseness. None for zone-only advice.
Returns:
Formatted string listing all maintenance recommendations.
Raises:
ValueError: If any fault type is outside the canonical
vocabulary (the message lists the allowed values —
unknown values are never dropped silently).
| Name | Required | Description | Default |
|---|---|---|---|
| fault_types | No | ||
| severity_zone | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description fully carries the behavioral transparency burden. It discloses the confidence value behavior (echoed without evidential basis), the error handling (ValueError with allowed values, never silent), and the fact that ctx is unused. This goes beyond basic operation and explains underlying logic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every element serves a purpose: purpose statement, behavioral caveat, structured Args/Returns/Raises. The front-loaded summary gives immediate understanding, and the structured format makes scanning easy without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two parameters and important constraints, the description covers all necessary context: inputs, output format, error behavior, and usage nuances. Output schema exists, so return details are handled there. The description is fully adequate for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate entirely. It does so thoroughly: severity_zone is explained as ISO zone letters, and fault_types is described with the canonical vocabulary, the explicit exclusion of BPFO/BPFI/BSF/FTF acronyms, and the meaning of None. This adds meaning well beyond the schema's enum lists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Generate maintenance recommendations based on severity and detected faults.' It further specifies the uniqueness by combining ISO zone-based urgency with fault-specific actions, distinguishing it from sibling tools like assess_severity or diagnostic report generators.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on inputs: allowed fault types, the warning against using BPFO acronyms, and the 'None' option for zone-only advice. It also explicitly states the tool does NOT accept a confidence value, which is a clear exclusion. However, it does not compare to alternative sibling tools, leaving some ambiguity about when to choose this over other diagnostic tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_pca_visualization_reportA
Generate PCA visualization HTML report showing test data in 2D PCA space.
Creates interactive scatter plot with:
- Test/prediction data (green = predicted healthy, red = predicted anomaly)
- PC1 vs PC2 axes with variance explained
- Hover information showing segment details and prediction status
**IMPORTANT**: Labels show MODEL PREDICTIONS, not ground truth. Use `true_labels`
parameter to provide actual labels for validation visualization.
Requires the test signals loaded via load_signal() first; each
signal's sampling rate comes from its stored metadata.
Args:
model_name: Name of trained model (e.g., 'bearing_health_model')
test_signal_ids: Optional list of stored signal IDs to predict and visualize
true_labels: Optional dict mapping signal_ids to true labels.
Format: {"real_test_baseline_3": "healthy",
"real_test_InnerRaceFault_vload_6": "faulty"}
When provided, legend shows both true and predicted labels for validation.
segment_duration: Segment duration in seconds (default: 0.1s for ML)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with file path, metadata, and summary (includes validation metrics if true_labels provided)
Raises:
FileNotFoundError: If the model does not exist.
ValueError: If a signal_id is not loaded or has no sampling rate.
Example (with validation):
>>> generate_pca_visualization_report(
... model_name="bearing_health_model",
... test_signal_ids=["real_test_baseline_3", "real_test_InnerRaceFault_vload_6"],
... true_labels={"real_test_baseline_3": "healthy",
... "real_test_InnerRaceFault_vload_6": "faulty"}
... )
| Name | Required | Description | Default |
|---|---|---|---|
| model_name | Yes | ||
| true_labels | No | ||
| overlap_ratio | No | ||
| test_signal_ids | No | ||
| segment_duration | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosure. It honestly warns that labels are model predictions, not ground truth, and explains the need for `true_labels`. It also lists error conditions (FileNotFoundError, ValueError) and prerequisites. It only omits explicit details about where the HTML file is saved, but this is a minor gap given the return value mentions a file path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (overview, important note, args, returns, raises, example) and is front-loaded with the core purpose. Every sentence provides necessary information, though it is slightly longer than strictly needed. The example is valuable but adds length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all essential aspects for using this tool correctly: purpose, prerequisites, parameter meanings, return value, error cases, and a concrete example. Since an output schema is available (per context), the return description is a bonus. The only minor omission is the exact file output location, which is not critical for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description's Args section provides thorough semantics for every parameter: model_name includes an example, test_signal_ids explains optionality, true_labels includes format and example mapping, segment_duration gives unit and default, overlap_ratio gives range and default. This fully compensates for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Generate PCA visualization HTML report') and resource ('test data in 2D PCA space'), distinguishing it from sibling report tools like FFT/envelope/ISO reports. The mention of 'interactive scatter plot' and prediction labels makes its unique purpose explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool, including the prerequisite that test signals must be loaded via load_signal() first. It also explains when to use the `true_labels` parameter for validation. However, it does not explicitly contrast this tool with alternative report tools or state when not to use it, so it misses exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_test_signalA
Generate a synthetic test signal, save it, and load it into the repository.
The signal is written to data/signals/ with a timestamped filename and a
companion _metadata.json declaring sampling_rate and signal_unit='g'
(synthetic acceleration), then auto-registered in the repository — the
returned signal_id is immediately usable by every analysis, diagnosis,
and ISO severity tool with no manual steps.
Signal content: 'bearing_fault' = 10 Hz impacts modulating a 1 kHz
carrier; 'gear_fault' = 200 Hz mesh tone + harmonics; 'imbalance' =
25 Hz (1500 RPM) tone; 'normal' = broadband noise.
Args:
signal_type: Synthetic fault pattern to generate.
duration: Signal duration in seconds (10 s gives 0.1 Hz resolution).
sampling_rate: Sampling frequency in Hz.
noise_level: Additive white-noise amplitude.
random_seed: Seed for reproducible noise (None = non-deterministic).
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
StoredSignalInfo of the auto-loaded signal (signal_id, declared
sampling_rate and unit 'g').
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | ||
| noise_level | No | ||
| random_seed | No | ||
| signal_type | No | bearing_fault | |
| sampling_rate | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| shape | Yes | Shape of the signal array |
| filepath | Yes | Original file path |
| signal_id | Yes | Unique identifier for the stored signal |
| duration_s | No | Duration in seconds |
| raw_format | No | EFFECTIVE raw-binary decode parameters (sample_format, byte_order, n_channels, channel_index, header_offset, scale_factor) after the explicit > companion > default merge — recorded as provenance so get_signal_info can answer 'how was this file decoded'. None for self-describing formats. |
| size_bytes | Yes | Approximate memory size in bytes |
| num_samples | Yes | Number of samples |
| signal_unit | No | DECLARED signal unit — from load_signal(signal_unit=...) or the companion _metadata.json ('signal_unit' field). Never guessed. None means undeclared: ISO severity verdicts will be refused until the unit is declared. |
| sampling_rate | No | Sampling rate in Hz (must be positive when set) |
| load_timestamp | Yes | ISO 8601 timestamp when signal was loaded |
| source_metadata | No | Complete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden and does well: it discloses file writing (data/signals/ with timestamp), companion metadata, auto-registration, and the return value. It does not mention potential overwrite behavior or access requirements, but the timestamped naming implies no overwrites, and these are acceptable gaps for a generation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently structured: a one-sentence overview, a paragraph on side effects, a bullet-like list of signal content, and a clear Args/Returns breakdown. Every sentence serves a purpose, no filler, and key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no annotations, the description provides a complete picture: outputs, files written, auto-registration, signal patterns, parameter details, and return type. It fully covers the complexity of a 5-parameter tool with no schema descriptions, making it self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate entirely, and it does. Every parameter is explained: signal_type gives all enum values with their waveform patterns, duration notes the resolution trade-off, sampling_rate, noise_level, and random_seed with reproducibility. This adds substantial meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('Generate'), a resource ('synthetic test signal'), and the full workflow (save, load, auto-register). It distinguishes itself from the many analysis/loading sibling tools by being the only signal-generation tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this tool (to create synthetic test signals for downstream analysis tools), noted by 'immediately usable by every analysis, diagnosis, and ISO severity tool with no manual steps.' It does not explicitly name alternatives or exclusions, but given the sibling set, the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_signal_infoA
Get metadata for a stored signal without loading the full array.
Includes the COMPLETE companion-metadata dict (source_metadata: rpm/
shaft_speed, reference frequencies, ...) alongside the repository
fields (sampling_rate, declared signal_unit, shape, timestamps).
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
signal_id: ID of a signal previously loaded via load_signal.
Returns:
StoredSignalInfo with source_metadata populated from the companion
_metadata.json (empty dict when the file has none).
Raises:
ValueError: If the signal_id is not in the repository.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| shape | Yes | Shape of the signal array |
| filepath | Yes | Original file path |
| signal_id | Yes | Unique identifier for the stored signal |
| duration_s | No | Duration in seconds |
| raw_format | No | EFFECTIVE raw-binary decode parameters (sample_format, byte_order, n_channels, channel_index, header_offset, scale_factor) after the explicit > companion > default merge — recorded as provenance so get_signal_info can answer 'how was this file decoded'. None for self-describing formats. |
| size_bytes | Yes | Approximate memory size in bytes |
| num_samples | Yes | Number of samples |
| signal_unit | No | DECLARED signal unit — from load_signal(signal_unit=...) or the companion _metadata.json ('signal_unit' field). Never guessed. None means undeclared: ISO severity verdicts will be refused until the unit is declared. |
| sampling_rate | No | Sampling rate in Hz (must be positive when set) |
| load_timestamp | Yes | ISO 8601 timestamp when signal was loaded |
| source_metadata | No | Complete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the full burden of behavioral disclosure. It does well by detailing what is returned (StoredSignalInfo with source_metadata populated), the source of that metadata (_metadata.json), the empty-dict fallback, and the ValueError condition. It also notes that ctx is unused. This is transparent and useful, though it does not explicitly state the operation is read-only (which is obvious from 'get').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a concise summary followed by Args, Returns, and Raises sections. Every sentence earns its place, providing key details without fluff. The main purpose is front-loaded, making it easy for an agent to quickly assess relevance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and an output schema, this description is complete. It explains the purpose, parameter semantics, return value, and error behavior. The output schema already covers the return structure, so the description does not need to over-explain. No gaps are evident.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no description for signal_id (0% coverage), so the description compensates by explaining it as 'ID of a signal previously loaded via load_signal.' This adds critical context beyond the raw schema. The mention of ctx is confusing because it does not appear in the schema, but it is clearly marked as unused, so it does not harm overall clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'Get metadata for a stored signal without loading the full array.' This distinguishes it from load_signal (which loads the full array) and list_signals (which lists signals), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'without loading the full array' clearly signals when to use this tool instead of loading the entire signal. It also states a prerequisite: signal_id must be from a signal 'previously loaded via load_signal.' However, it does not explicitly name alternative tools or state when not to use it, so it falls short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_html_reportsA
List HTML reports, or get one report's embedded metadata.
Without file_name: lists every report in reports/ with file name,
type, signal, and size. With file_name: returns that report's
embedded metadata block (absorbed get_report_info). Never returns
HTML content — metadata only, to avoid token consumption.
Args:
file_name: Optional report filename inside reports/ — returns
its metadata instead of the listing.
Returns:
List of report summaries (no file_name), or a dict with the
single report's metadata (file_name given).
Raises:
ValueError: If file_name escapes the reports directory, does
not exist, or carries no metadata block.
| Name | Required | Description | Default |
|---|---|---|---|
| file_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it delivers: it details what is returned (list vs dict), what is not returned (HTML content), the token-saving behavior, and specific error conditions (ValueError for path escape, missing file, or missing metadata). This is thorough and goes beyond the bare minimum.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a summary sentence, then explanatory paragraphs for modes, arguments, returns, and raises. Every sentence adds meaningful information, and the docstring-like format makes it easy to parse. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having only one optional parameter, the description covers all aspects: purpose, modes, parameter validation, return types, and error handling. The output schema may provide additional structural detail, but the description alone is sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, file_name, has 0% schema description coverage, so the description must compensate. It does: 'Optional report filename inside reports/ — returns its metadata instead of the listing' explains both the path constraint and the behavioral switch. The Raises section adds validation semantics, making the parameter's role fully clear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource statement: 'List HTML reports, or get one report's embedded metadata.' It distinguishes two modes (with and without file_name) and explicitly states it never returns HTML content, setting it apart from sibling tools that probably handle report generation or content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use each mode: without file_name for a listing of all reports, with file_name for a single report's metadata. It also says 'Never returns HTML content — metadata only, to avoid token consumption,' giving a clear when-not and rationale. The mention of 'absorbed get_report_info' signals that this tool replaces that function, providing alternative context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_machine_manualsA
List all machine manuals in resources/machine_manuals/ (PDF/TXT).
Use before read_manual_excerpt / extract_manual_specs, and pass the
returned filenames exactly as-is.
Returns:
List of dicts with filename, size_mb, modified, and path.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently states the operation is a list, the location, the file types, and the exact return fields. It doesn't mention sorting or pagination, but for a read-only listing tool this is adequate; no side effects or permissions are implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences, with the main purpose first and usage guidance second. Every clause adds value: location, file types, usage context, and return format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with no parameters, and an output schema exists. The description covers the tool's purpose, location, and return format, and includes a crucial usage instruction about passing filenames exactly as-is. It is fully adequate for an agent to select and invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, and the schema is empty, so the baseline is 4. The description adds no parameter-specific information because there are none to explain, and the return-value note helps clarify output but that's not parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List all machine manuals in resources/machine_manuals/ (PDF/TXT)', providing a specific verb, resource, and scope. It distinguishes itself from sibling tools by focusing on listing rather than reading or extracting, and explicitly names usage with siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use before read_manual_excerpt / extract_manual_specs', providing clear context for when to invoke this tool. It also instructs to 'pass the returned filenames exactly as-is', which guides the agent on how to use the output. No alternative for 'when not to use' is given, but the guidance is sufficient for this simple listing operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_signalsA
List signal files on disk or signals loaded in the repository.
scope='disk' (default): files under data/signals/ that load_signal can
open — use before loading. scope='memory': signals currently cached in
the in-memory repository with their metadata (signal_id, sampling_rate,
declared unit) — use to see which signal_ids are available for analysis.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
scope: 'disk' for loadable files, 'memory' for loaded signal_ids.
Returns:
Dict with scope, count, and either 'files' (relative paths, disk)
or 'signals' (StoredSignalInfo entries, memory).
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | disk |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It explains the default scope, the return structure (Dict with scope, count, and files/signals), and notes that ctx is unused. It implies a read-only listing operation, though it never explicitly states there are no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear first-line summary, followed by Args and Returns sections. Each part contributes value, but the 'ctx: MCP context. Unused...' note is a minor tangential detail that prevents a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter list tool with an output schema, the description covers the default behavior, valid parameter values, return format, and usage intent. There are no significant gaps in context for an agent to invoke and interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description fully explains the only parameter, scope, by defining each enum value ('disk' vs 'memory') and its behavioral consequences. This adds significant semantic meaning beyond the raw schema enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List signal files on disk or signals loaded in the repository.' It explicitly distinguishes the disk and memory scopes, making it clear what this tool does and differentiating it from related tools like load_signal and clear_signals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: disk scope is for 'use before loading' and memory scope is for 'seeing which signal_ids are available for analysis.' It does not explicitly name alternative tools or when not to use this tool, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_signalA
Load one signal — or a batch — into the in-memory repository.
Once loaded, reference the signal by its signal_id in every analysis,
diagnosis, report, and prognostics tool (the load -> analyze ->
diagnose -> report flow uses signal_id as the single handle).
Batch form: pass a LIST of file paths (e.g. for training sets). The
batch is fail-fast and atomic — all paths and derived ids are
validated up front, and on the first problem ONE error names the
offending entries and nothing is loaded. One declared sampling_rate/
signal_unit applies to all files; per-file metadata wins only when
the parameter is omitted. Custom signal_id is not allowed for a
batch (ids derive from each file's relative path).
signal_id default: the path relative to data/signals/ with separators
replaced by underscores — 'real_train/baseline_1.csv' loads as
'real_train_baseline_1', so same-named files in different folders
never collide silently. Re-loading a path whose id already exists is
an explicit error unless overwrite=True.
Signal unit discipline: ISO 20816-3 severity verdicts require a
DECLARED unit — either via this parameter or a 'signal_unit' field in
the companion _metadata.json (explicit parameter wins). Units are
never guessed from signal amplitude; without a declared unit the ISO
severity block is refused with a structured reason and remedy.
Raw binary files (.bin/.raw/.dat): a headerless raw waveform loads
only with a declared decode contract — sample_format AND
sampling_rate are REQUIRED, either as explicit parameters here or as
fields of the companion <stem>_metadata.json next to the file
(explicit parameter wins). The other raw parameters carry documented
defaults, applied by the repository after that merge: byte_order
'little', n_channels 1, channel_index 0, header_offset 0, no
scale_factor. Integer sample formats (int16/int32) decode to raw ADC
counts — declare scale_factor to convert counts into the declared
physical unit (there is no implicit normalization). In a batch the
raw parameters broadcast to ALL files, exactly like sampling_rate.
Declaring raw parameters for a self-describing format (.csv, .npy,
...) is refused as a contradiction. With n_channels > 1 each load
extracts ONE channel and the DERIVED id gains a _ch<channel_index>
suffix; an explicit signal_id is used verbatim — no suffix applies.
Args:
ctx: MCP context. Unused — see this module's docstring on logging.
filepath: Filename relative to data/signals/ or absolute path —
or a list of such paths for an atomic batch load.
signal_id: Custom ID (single-file loads only; default derives
from the relative path).
sampling_rate: Sampling rate in Hz (overrides metadata file).
Required for raw binary files (here or in the companion).
signal_unit: Declared signal unit — 'g' or 'm/s2' (acceleration),
'mm/s' or 'm/s' (velocity). Overrides the metadata file.
overwrite: Replace existing entries on signal_id collision
instead of raising.
sample_format: Raw files only — declared sample dtype ('float32',
'float64', 'int16', 'int32'). REQUIRED for .bin/.raw/.dat
(here or in the companion metadata).
byte_order: Raw files only — declared endianness ('little' or
'big'); documented default 'little'.
n_channels: Raw files only — interleaved channel count in the
file; documented default 1.
channel_index: Raw files only — 0-based channel to extract;
documented default 0.
header_offset: Raw files only — bytes to skip before the first
sample; documented default 0.
scale_factor: Raw files only — optional multiplier applied after
decoding (e.g. ADC counts -> physical unit); default: no
scaling.
Returns:
StoredSignalInfo for a single load; a list of StoredSignalInfo
(input order) for a batch. Raw loads record the effective decode
parameters under raw_format.
Raises:
ValueError: If signal_unit is invalid, the signal data cannot be
loaded, a signal_id collides without overwrite=True, a batch
contains any invalid entry (nothing is loaded), a raw binary
file is missing a required declaration (ONE message names
everything missing plus both remedies), or raw parameters
are declared for a self-describing format.
| Name | Required | Description | Default |
|---|---|---|---|
| filepath | Yes | ||
| overwrite | No | ||
| signal_id | No | ||
| byte_order | No | ||
| n_channels | No | ||
| signal_unit | No | ||
| scale_factor | No | ||
| channel_index | No | ||
| header_offset | No | ||
| sample_format | No | ||
| sampling_rate | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: atomic batch fail-fast behavior, automatic signal_id derivation, overwrite semantics, raw decode contracts, unit declaration requirements, channel suffix behavior, and explicit refusal of raw params for self-describing formats. It also lists all exception conditions and return formats, providing complete transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but appropriately so for a tool with 11 parameters, batch behavior, raw decoding, and complex edge cases. It is well-structured with clear paragraphs, an Args list, Returns, and Raises sections. The core purpose is front-loaded, and each sentence contributes meaningful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the lack of annotations or schema descriptions, the description is remarkably complete. It covers parameter semantics, return values, error scenarios, and the broader load->analyze->diagnose->report flow. The output schema exists but the description still explains StoredSignalInfo for single and batch loads, making it self-sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description extensively documents every parameter: filepath for single or batch, signal_id custom vs derived, sampling_rate and signal_unit overrides, raw file parameters with defaults, and overwrite behavior. It explains relationships between parameters (e.g., raw parameters broadcast in batch) and provides context for each one, fully compensating for the missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool's function: 'Load one signal — or a batch — into the in-memory repository.' It clearly distinguishes this from sibling tools like list_signals or get_signal_info by focusing on the loading operation and the subsequent flow of using signal_id. The verb 'load' and resource 'signal' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong usage context: it explains that once loaded, the signal is referenced by signal_id in every analysis, diagnosis, report, and prognostics tool, positioning this tool as the entry point for data ingestion. It details batch usage, raw file handling, and metadata merging, making the when-to-use clear. However, it does not explicitly name sibling tools as alternatives or state when not to use this tool, which prevents a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plot_signalA
Generate interactive time-domain plot for a stored signal.
Creates an interactive HTML plot showing the signal in the time domain.
Useful for inspecting signal quality, identifying anomalies, and
visualizing transients. Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
Args:
signal_id: ID of the stored signal (from load_signal).
time_range: [start_time, end_time] in seconds to zoom on a portion (optional)
show_statistics: Show RMS, peak levels as horizontal lines (default: True)
title: Custom plot title (optional)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Path to generated HTML file
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
plot_signal(
"bearing_signal",
time_range=[0.1, 0.3], # Zoom on 100-300 ms
show_statistics=True
)
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| signal_id | Yes | ||
| time_range | No | ||
| show_statistics | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses that the tool generates an HTML file, requires a loaded signal, raises ValueError on invalid input, and returns a file path. It also notes the sampling rate comes from metadata. While it does not mention file location or overwrite behavior, the disclosed error conditions and return type provide solid transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Description, Args, Returns, Raises, Example), each earning its place. The opening one-liner states the core purpose, and the example adds practical value without redundancy. Length is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, usage, parameters, return value, error conditions, and a usage example. It includes mention that ctx is unused, which helps agent calls. Even with an output schema present, it explains the return path, making the tool fully understandable standalone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the Args section fully compensates by explaining every parameter: signal_id (origin), time_range (format and units), show_statistics (what lines are shown), and title (custom). The example further clarifies usage with a concrete time_range. This goes well beyond the schema's bare property definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb+resource: 'Generate interactive time-domain plot for a stored signal.' This clearly distinguishes it from sibling analysis tools (FFT, envelope, statistics) by focusing on time-domain visualization. The subsequent sentence about inspecting signal quality, identifying anomalies, and visualizing transients reinforces its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the prerequisite (signal must be loaded via load_signal()) and explains when the tool is useful (inspecting quality, anomalies, transients). However, it does not explicitly mention when not to use it or name alternative tools for other analysis types, stopping short of the fullest guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
predict_anomaliesA
Predict anomalies in a stored signal using a trained model.
Requires the signal loaded via load_signal() first and a model
trained via train_anomaly_model (its result echoes the model_name
to pass here). Pipeline: segment -> features -> scaler -> PCA ->
predict -> aggregate.
Output is BOUNDED: counts, anomaly ratio, score percentiles, and
up to 10 worst segments — never per-segment arrays, regardless of
signal length.
Args:
signal_id: ID of the stored signal to analyze (from load_signal)
model_name: Name of trained model (default: 'anomaly_model')
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
AnomalyPredictionResult with aggregate statistics and health
assessment.
Raises:
FileNotFoundError: If the model does not exist (the message
lists the models actually on disk).
ValueError: If the signal_id is not loaded, or no sampling rate
is available for segmentation.
| Name | Required | Description | Default |
|---|---|---|---|
| signal_id | Yes | ||
| model_name | No | anomaly_model |
Output Schema
| Name | Required | Description |
|---|---|---|
| model_name | Yes | Name of the trained model used |
| num_segments | Yes | Number of segments analyzed |
| anomaly_count | Yes | Number of anomalies detected |
| anomaly_ratio | Yes | Ratio of anomalies (0-1) |
| overall_health | Yes | Overall health status: 'Healthy', 'Suspicious', 'Faulty' (thresholded on anomaly_ratio: <0.1, <0.3, >=0.3) |
| worst_segments | No | Up to 10 most anomalous segments, each with segment_index, start_time_s, and score (when available) — enough to locate the worst regions without dumping per-segment arrays. |
| score_percentiles | No | Percentiles (p5/p25/p50/p75/p95) of the model decision scores; negative = anomalous side. None when the model exposes no decision_function. |
| segment_duration_s | Yes | Segment length in seconds (from the model's training metadata) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the transparency burden. It discloses that output is 'BOUNDED' and 'never per-segment arrays', describes the internal pipeline, notes that ctx is 'Unused', and details exact error conditions including that FileNotFoundError lists models on disk. This is rich behavioral context beyond a basic 'predict' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose, then systematically covers prerequisites, pipeline, output bounds, parameters, returns, and errors. Every sentence earns its place; the use of Args/Returns/Raises headers improves scannability without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with an output schema, the description provides a complete picture: required prerequisites, the transformation pipeline, bounded output behavior, parameter sources, and concrete failure modes. An agent can confidently select and invoke this tool correctly without needing additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. The Args section adds meaning: signal_id is identified as coming from load_signal, model_name is given a default and linked to the training result, and ctx is explicitly marked unused. This exceeds the bare schema but does not provide exact format specifiers (e.g., length constraints), which keeps it at a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Predict anomalies in a stored signal using a trained model.' This clearly distinguishes the tool from siblings such as train_anomaly_model, analyze_fft, and estimate_rul, while also naming both inputs (signal and model).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states prerequisites: 'Requires the signal loaded via load_signal() first and a model trained via train_anomaly_model', and gives the pipeline order. It also implies when not to use the tool via the ValueError for unloaded signals. However, it does not name specific alternatives or explicitly contrast with sibling tools, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_manual_excerptA
Read a text excerpt from a machine manual (PDF or TXT).
Use for consecutive-page reading; for targeted questions prefer
search_documentation. Start with max_pages=10 and increase only if
needed (pages consume tokens).
Args:
file_name: Manual filename in resources/machine_manuals/
(PDF or TXT)
max_pages: Maximum pages to extract (ignored for TXT files)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Extracted text from the manual.
Raises:
FileNotFoundError: If the manual does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| file_name | Yes | ||
| max_pages | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that max_pages is ignored for TXT files, that pages consume tokens, that ctx is unused, and that FileNotFoundError is raised. It could mention read-only behavior explicitly, but 'Read' implies it; the disclosure of token consumption is a notable behavioral trait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The docstring is well-structured with Args, Returns, and Raises sections, and the guidance is front-loaded. The reference to 'this module's docstring on logging' is a minor detour, but overall every sentence serves a purpose and the text is not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two parameters, no annotations, and an output schema (which the description doesn't need to duplicate), the description covers purpose, usage, parameters, return value, and error conditions. It is complete enough to use the tool safely and effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully compensate. It provides clear semantics for file_name (location and accepted formats), max_pages (default, ignored for TXT), and ctx (unused). This far exceeds what the schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Read a text excerpt from a machine manual (PDF or TXT).' It clearly distinguishes from siblings by adding 'Use for consecutive-page reading; for targeted questions prefer search_documentation.' This directly differentiates it from the related search tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'Use for consecutive-page reading; for targeted questions prefer search_documentation.' Additionally, it advises to start with max_pages=10 and increase only if needed due to token consumption, which is actionable and context-specific.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_bearing_catalogA
Search for bearing specifications in the local verified catalog.
Fallback for when the machine manual names a bearing but not its
geometry. The catalog is small BY DESIGN: only entries whose
geometry is traceable to a public source (mandatory `source`
citation). A miss is a legitimate negative outcome — ask the user
for the geometry; never guess it.
Args:
bearing_id: Bearing designation (e.g. "6205", "SKF 6205-2RS")
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with bearing specifications if found, or a
BearingCatalogMiss (status='not_found', suggestion,
catalog_contains) when the bearing is not in the catalog.
Raises:
Exception: If the catalog itself cannot be read (missing or
malformed common_bearings_catalog.json).
| Name | Required | Description | Default |
|---|---|---|---|
| bearing_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It reveals the catalog is small by design, mandates source citation, clarifies that a miss is a valid result, describes the return structure (specifications or BearingCatalogMiss), and documents an exception when the catalog file cannot be read. This is comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear Args, Returns, and Raises sections, and it front-loads the purpose. It is slightly verbose in referencing an internal docstring for logging, but the length is justified by the useful behavioral details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one parameter) but the description covers input semantics, output behavior, error conditions, and catalog policy. Even with an output schema, the Returns section adds value by describing the miss object's fields. Complete given the tool's scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only provides a parameter name, type, and required flag with 0% description coverage. The description compensates fully by defining 'bearing_id' as a bearing designation and providing concrete examples ('6205', 'SKF 6205-2RS'), which is essential for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for bearing specifications in a local verified catalog, using a specific verb and resource. It also distinguishes itself from sibling tools by noting it is a fallback when the machine manual names a bearing but lacks geometry, positioning it uniquely among the listed tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the scenario for use ('Fallback for when the machine manual names a bearing but not its geometry') and provides decision guidance for negative outcomes ('A miss is a legitimate negative outcome — ask the user for the geometry; never guess it'). This goes beyond general context to actionable instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_documentationA
Semantic search across all machine manuals and bearing catalogs.
Uses vector retrieval (RAG) to find the most relevant passages from
PDFs, text files, and JSON catalogs in resources/.
Backends (chosen automatically):
- FAISS + sentence-transformers (pip install predictive-maintenance-mcp[vector-search])
- TF-IDF keyword search (default, zero extra deps)
The index is built lazily on first call and cached on disk. It is
automatically rebuilt when source files change.
Args:
query: Natural-language question or keywords
(e.g. "bearing 6205 geometry", "maintenance interval pump")
top_k: Number of passages to return (default: 5)
force_reindex: Rebuild the index even if cache is fresh (default: False)
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
Dictionary with ranked results, each containing text passage, source
file, relevance score, and chunk index.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No | ||
| force_reindex | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It exceeds basic expectations by revealing lazy index building, disk caching, automatic rebuild on source changes, backend fallback (FAISS vs TF-IDF), and the return format including relevance score and chunk index. It also notes the ctx parameter is unused. It does not mention potential performance impacts or error cases, but is notably transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, backend details, indexing behavior, arguments, and return value. Every sentence adds value—backend options, caching, parameter explanations, and return fields—without fluff. The core purpose is front-loaded in the first line.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters, no annotations, and a provided output schema, this description is self-sufficient. It explains the search scope, retrieval algorithm, backend choices, caching behavior, parameter semantics, and return structure. It also mentions the optional dependency for the FAISS backend, making it complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero description coverage, but the description fully compensates with an Args section. It explains query with natural-language examples, top_k as 'Number of passages to return' with default, force_reindex as 'Rebuild the index even if cache is fresh', and ctx as unused. This provides complete semantic meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Semantic search across all machine manuals and bearing catalogs', a specific verb+resource+scope statement. It further clarifies it uses vector retrieval (RAG) to find relevant passages from PDFs, text files, and JSON catalogs, distinguishing it from sibling tools like read_manual_excerpt or search_bearing_catalog.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for usage: natural-language questions or keywords like 'bearing 6205 geometry', and explains the automated backend selection. However, it does not explicitly state when to use this tool over sibling tools such as search_bearing_catalog, nor does it mention exclusions or alternative contexts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
train_anomaly_modelA
Train ML-based anomaly detection model on healthy data (UNSUPERVISED/SEMI-SUPERVISED).
All signals are referenced by signal_id: load them first with
load_signal — its batch form accepts a list of file paths, e.g.
load_signal(filepath=["real_train/baseline_1.csv", ...]). Each
signal's sampling rate comes from its stored metadata.
Complete pipeline:
1. Extract features from healthy signals (segmentation + time-domain features)
2. Standardize features (StandardScaler - fitted on training data only)
3. Dimensionality reduction (PCA with specified variance explained)
4. Train novelty detection model (OneClassSVM or LocalOutlierFactor) on HEALTHY DATA ONLY
5. Optional hyperparameter tuning using validation data (semi-supervised)
6. Save model, scaler, and PCA transformer
**Training Mode:**
- UNSUPERVISED: Train only on healthy data with automatic hyperparameters
- SEMI-SUPERVISED: Train on healthy data, tune hyperparameters using validation set (healthy + fault)
**Note:** This is NOT supervised learning. OneClassSVM/LOF are trained ONLY on healthy data.
Fault data (if provided) is used ONLY for hyperparameter tuning after training.
**Validation Strategy:**
- If healthy_validation_ids provided: Use those explicitly (no split)
- If healthy_validation_ids NOT provided: Automatic 80/20 split of training data
- If fault_signal_ids provided: Enable semi-supervised mode (hyperparameter tuning)
Args:
healthy_signal_ids: Stored signal IDs with healthy machine data (for training)
segment_duration: Segment duration in seconds (default: 0.1)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
model_type: 'OneClassSVM' or 'LocalOutlierFactor' (default: 'OneClassSVM')
pca_variance: Cumulative variance to explain with PCA (default: 0.95)
fault_signal_ids: Optional stored signal IDs for HYPERPARAMETER TUNING (semi-supervised)
healthy_validation_ids: Optional stored healthy signal IDs for validation (specificity check).
If not provided, 20% of training data will be used.
model_name: Name for saved model files (default: 'anomaly_model')
ctx: MCP context. Unused — see this module's docstring on logging.
Returns:
AnomalyModelResult with model paths and performance metrics
Raises:
ValueError: If a signal_id is not loaded or has no sampling rate,
or model_name/model_type is invalid.
| Name | Required | Description | Default |
|---|---|---|---|
| model_name | No | anomaly_model | |
| model_type | No | OneClassSVM | |
| pca_variance | No | ||
| overlap_ratio | No | ||
| fault_signal_ids | No | ||
| segment_duration | No | ||
| healthy_signal_ids | Yes | ||
| healthy_validation_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| pca_path | Yes | Path to saved PCA file (.pkl) |
| model_name | Yes | Name under which the model was saved — pass this to predict_anomalies(model_name=...) |
| model_path | Yes | Path to saved model file (.pkl) |
| model_type | Yes | Type of model: 'OneClassSVM' or 'LocalOutlierFactor' |
| scaler_path | Yes | Path to saved scaler file (.pkl) |
| model_params | Yes | Best model hyperparameters |
| num_features_pca | Yes | Number of PCA components (features after dimensionality reduction) |
| validation_details | No | Validation details with healthy and fault metrics |
| validation_metrics | No | Detailed validation metrics (healthy/fault accuracy breakdown) |
| variance_explained | Yes | Cumulative variance explained by PCA components |
| validation_accuracy | No | Overall balanced accuracy on healthy + fault validation data |
| num_training_samples | Yes | Number of healthy samples used for training |
| num_features_original | Yes | Number of original features |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral disclosure burden. It reveals that the model is trained ONLY on healthy data, fault data is used only for tuning, standardization is fitted on training data only, and it saves model/scaler/PCA. It also discloses the validation strategy and possible ValueError conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but appropriately structured with numbered pipeline steps, bolded section headers, and labeled sections (Args, Returns, Raises). Every sentence adds value, and the key message (unsupervised training on healthy data) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the tool's complexity (8 params, pipeline steps, training modes, validation logic), the description covers all essentials. It explains the output (AnomalyModelResult with model paths and metrics), error conditions, and prerequisites, making it complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage (only titles/defaults), so the description's 'Args' section is essential. It explains each parameter in detail, including defaults and semantic roles—e.g., fault_signal_ids for hyperparameter tuning, healthy_validation_ids for explicit validation with automatic 80/20 fallback.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Train ML-based anomaly detection model on healthy data'. It clearly differentiates from siblings like predict_anomalies and check_bearing_faults by stating it trains an unsupervised/semi-supervised model, and it names the exact algorithms (OneClassSVM, LocalOutlierFactor).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a complete pipeline, explicitly states when to use unsupervised vs semi-supervised modes, explains how validation splits work, and warns 'This is NOT supervised learning'. It also instructs to load signals first with load_signal, giving a clear prerequisite and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
3 tool updates
v0.13.0- Changed
generate_test_signal1 field changed- added
Output schema / properties / raw_formatAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "EFFECTIVE raw-binary decode parameters (sample_format, byte_order, n_channels, channel_index, header_offset, scale_factor) after the explicit > companion > default merge — recorded as provenance so get_signal_info can answer 'how was this file decoded'. None for self-describing formats.", + "title": "Raw Format" +}
- Changed
get_signal_info1 field changed- added
Output schema / properties / raw_formatAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "EFFECTIVE raw-binary decode parameters (sample_format, byte_order, n_channels, channel_index, header_offset, scale_factor) after the explicit > companion > default merge — recorded as provenance so get_signal_info can answer 'how was this file decoded'. None for self-describing formats.", + "title": "Raw Format" +}
- Changed
load_signal7 fields changed- added
Input schema / properties / byte_orderAdded value: +{ + "anyOf": [ + { + "enum": [ + "little", + "big" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Byte Order" +} - added
Input schema / properties / channel_indexAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Channel Index" +} - added
Input schema / properties / header_offsetAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Header Offset" +} - added
Input schema / properties / n_channelsAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "N Channels" +} - added
Input schema / properties / sample_formatAdded value: +{ + "anyOf": [ + { + "enum": [ + "float32", + "float64", + "int16", + "int32" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sample Format" +} - added
Input schema / properties / scale_factorAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Scale Factor" +} - added
Output schema / $defs / StoredSignalInfo / properties / raw_formatAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "EFFECTIVE raw-binary decode parameters (sample_format, byte_order, n_channels, channel_index, header_offset, scale_factor) after the explicit > companion > default merge — recorded as provenance so get_signal_info can answer 'how was this file decoded'. None for self-describing formats.", + "title": "Raw Format" +}
1 tool update
v0.12.0- Added
generate_diagnostic_report
46 tool updates
v0.9.1- Changed
analyze_envelope18 fields changed- removed
Input schema / properties / filenameRemoved value: -{ - "title": "Filename", - "type": "string" -} - changed
Input schema / properties / filter_high / defaultPrevious value: -2000New value: +5000 - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - changed
Input schema / properties / segment_duration / defaultPrevious value: -nullNew value: +1 - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "filename" -]New value: +[ + "signal_id" +] - added
Output schema / $defsAdded value: +{ + "SpectralPeak": { + "description": "A single peak in the frequency spectrum.", + "properties": { + "frequency_hz": { + "description": "Peak frequency in Hz", + "title": "Frequency Hz", + "type": "number" + }, + "magnitude": { + "description": "Peak magnitude (linear)", + "title": "Magnitude", + "type": "number" + }, + "magnitude_db": { + "description": "Peak magnitude in dB (relative to max)", + "title": "Magnitude Db", + "type": "number" + }, + "note": { + "default": "", + "description": "Optional annotation (e.g. harmonic label)", + "title": "Note", + "type": "string" + } + }, + "required": [ + "frequency_hz", + "magnitude", + "magnitude_db" + ], + "title": "SpectralPeak", + "type": "object" + } +} - changed
Output schema / descriptionPrevious value: -"Envelope analysis result - optimized for chat display."New value: +"Unified envelope-spectrum analysis result (U9 merge).\n\nCompact summary: top peaks + the band ACTUALLY used — no full arrays.\nThe envelope FFT is computed after mean subtraction + Hann window\n(audit 2.8 fix), so low-frequency (FTF-zone) peaks are not buried by\nDC leakage." - changed
Output schema / properties / diagnosis / descriptionPrevious value: -"Interpretive diagnosis text with bearing frequency analysis"New value: +"Peak listing and comparison guidance. No reference bearing frequencies are assumed — compare against frequencies computed for the actual bearing and shaft speed." - changed
Output schema / properties / filter_band / descriptionPrevious value: -"Bandpass filter band (Hz)"New value: +"Bandpass filter band (Hz) actually used — echoed from the request" - changed
Output schema / properties / num_samples / descriptionPrevious value: -"Number of samples in envelope signal"New value: +"Number of samples analyzed (envelope length)" - removed
Output schema / properties / peak_frequenciesRemoved value: -{ - "description": "Top peak frequencies (Hz)", - "items": { - "type": "number" - }, - "title": "Peak Frequencies", - "type": "array" -} - removed
Output schema / properties / peak_magnitudesRemoved value: -{ - "description": "Top peak magnitudes", - "items": { - "type": "number" - }, - "title": "Peak Magnitudes", - "type": "array" -} - added
Output schema / properties / signal_idAdded value: +{ + "description": "Signal identifier used", + "title": "Signal Id", + "type": "string" +} - removed
Output schema / properties / spectrum_preview_freqRemoved value: -{ - "default": [], - "description": "First 100 freq points (Hz)", - "items": { - "type": "number" - }, - "title": "Spectrum Preview Freq", - "type": "array" -} - removed
Output schema / properties / spectrum_preview_magRemoved value: -{ - "default": [], - "description": "First 100 magnitude points", - "items": { - "type": "number" - }, - "title": "Spectrum Preview Mag", - "type": "array" -} - added
Output schema / properties / top_peaksAdded value: +{ + "description": "Top peaks in the envelope spectrum, sorted by frequency", + "items": { + "$ref": "#/$defs/SpectralPeak" + }, + "title": "Top Peaks", + "type": "array" +} - changed
Output schema / requiredPrevious value: -[ - "num_samples", - "sampling_rate", - "filter_band", - "peak_frequencies", - "peak_magnitudes", - "diagnosis" -]New value: +[ + "signal_id", + "num_samples", + "sampling_rate", + "filter_band", + "top_peaks", + "diagnosis" +]
- Changed
analyze_fft6 fields changed- removed
Input schema / properties / filenameRemoved value: -{ - "title": "Filename", - "type": "string" -} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - changed
Input schema / properties / segment_duration / defaultPrevious value: -nullNew value: +1 - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "filename" -]New value: +[ + "signal_id" +] - changed
Output schema / descriptionPrevious value: -"FFT analysis result — compact summary (top peaks + stats, no full arrays).\n\nFull-length arrays are never returned to the LLM to avoid context overflow.\nUse generate_fft_report() or plot_spectrum() for visual inspection."New value: +"FFT analysis result — compact summary (top peaks + stats, no full arrays).\n\nFull-length arrays are never returned to the LLM to avoid context overflow.\nUse generate_fft_report() for visual inspection."
- Changed
analyze_signal_trend23 fields changed- added
Input schema / properties / onset_threshold_sigmaAdded value: +{ + "default": 3, + "title": "Onset Threshold Sigma", + "type": "number" +} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +] - changed
Output schema / descriptionPrevious value: -"Signal trend analysis result."New value: +"Within-recording feature trend — screening only, NOT a prognosis.\n\nSegments a single recording (seconds of data) and fits a trend on the\nper-segment feature values. Use it to screen whether a recording is\nstationary. It cannot estimate Remaining Useful Life: for RUL, collect\nrepeated measurements over days/weeks and pass them to estimate_rul." - added
Output schema / properties / analysis_scopeAdded value: +{ + "description": "Always 'within_recording_screening': this trend spans seconds of one recording, not the machine's life", + "title": "Analysis Scope", + "type": "string" +} - added
Output schema / properties / baseline_segmentsAdded value: +{ + "description": "Number of leading segments used as the baseline window. Onset is only searched AFTER this window; degradation starting inside the baseline cannot be detected by this method.", + "title": "Baseline Segments", + "type": "integer" +} - added
Output schema / properties / feature_seriesAdded value: +{ + "description": "Per-segment feature values (evenly subsampled to at most 50 points). One recording yields ONE point for estimate_rul (e.g. the recording's overall feature value) — accumulate recordings over time to build its input series.", + "items": { + "type": "number" + }, + "title": "Feature Series", + "type": "array" +} - added
Output schema / properties / onset_detectedAdded value: +{ + "description": "Whether a degradation onset was detected after the baseline window (first value exceeding baseline mean + onset_threshold_sigma * std)", + "title": "Onset Detected", + "type": "boolean" +} - added
Output schema / properties / onset_segment_indexAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Segment index where degradation starts (always >= baseline_segments); None when no onset detected", + "title": "Onset Segment Index" +} - added
Output schema / properties / onset_threshold_sigmaAdded value: +{ + "description": "Baseline standard deviations used as the onset trigger", + "title": "Onset Threshold Sigma", + "type": "number" +} - added
Output schema / properties / onset_time_sAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Center time (s) of the onset segment within the recording", + "title": "Onset Time S" +} - added
Output schema / properties / p_value / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Output schema / properties / p_value / defaultAdded value: +null - changed
Output schema / properties / p_value / descriptionPrevious value: -"Statistical significance"New value: +"Two-sided p-value of the slope (None when not computable)" - removed
Output schema / properties / p_value / typeRemoved value: -"number" - changed
Output schema / properties / r_squared / descriptionPrevious value: -"R-squared goodness of fit"New value: +"R-squared goodness of fit of the linear trend" - added
Output schema / properties / segment_times_sAdded value: +{ + "description": "Segment center times in seconds for feature_series (same subsampling)", + "items": { + "type": "number" + }, + "title": "Segment Times S", + "type": "array" +} - added
Output schema / properties / series_truncatedAdded value: +{ + "description": "True when feature_series was subsampled to the 50-point cap", + "title": "Series Truncated", + "type": "boolean" +} - changed
Output schema / properties / slope / descriptionPrevious value: -"Trend slope per segment"New value: +"Trend slope in feature units per second (within the recording)" - changed
Output schema / properties / trend_direction / descriptionPrevious value: -"increasing, decreasing, or stable"New value: +"increasing, decreasing, or stable — based on the slope significance test (p < 0.05), not on an R-squared cutoff" - changed
Output schema / requiredPrevious value: -[ - "feature_name", - "slope", - "intercept", - "r_squared", - "trend_direction", - "p_value", - "num_segments" -]New value: +[ + "feature_name", + "slope", + "intercept", + "r_squared", + "trend_direction", + "num_segments", + "analysis_scope", + "feature_series", + "segment_times_s", + "series_truncated", + "onset_detected", + "onset_threshold_sigma", + "baseline_segments" +]
- Changed
analyze_statistics8 fields changed- removed
Input schema / properties / filenameRemoved value: -{ - "title": "Filename", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "filename" -]New value: +[ + "signal_id" +] - changed
Output schema / descriptionPrevious value: -"Statistical analysis result of the signal."New value: +"Statistical analysis result of the signal.\n\nValues are in the signal's native unit. The unit is reported only when\nDECLARED (companion ``_metadata.json`` or ``load_signal(signal_unit=...)``)\n— it is never guessed from signal amplitude." - removed
Output schema / properties / detected_unitRemoved value: -{ - "description": "Auto-detected signal unit (g acceleration or mm/s velocity)", - "title": "Detected Unit", - "type": "string" -} - added
Output schema / properties / signal_unitAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Declared signal unit ('g', 'm/s2', 'mm/s', 'm/s') from companion metadata — never guessed from amplitude. None when not declared.", + "title": "Signal Unit" +} - changed
Output schema / properties / unit_note / descriptionPrevious value: -"Important note about signal units and conversion requirements"New value: +"Unit declaration status and how to declare the unit for ISO severity assessment" - changed
Output schema / requiredPrevious value: -[ - "rms", - "peak_to_peak", - "peak", - "crest_factor", - "kurtosis", - "skewness", - "mean", - "std_dev", - "detected_unit", - "unit_note" -]New value: +[ + "rms", + "peak_to_peak", + "peak", + "crest_factor", + "kurtosis", + "skewness", + "mean", + "std_dev", + "unit_note" +]
- Added
assess_severity - Removed
assess_vibration_severity - Changed
calculate_bearing_characteristic_frequencies2 fields changed- added
Input schema / properties / rpmAdded value: +{ + "default": 1500, + "title": "Rpm", + "type": "number" +} - removed
Input schema / properties / shaft_speed_rpmRemoved value: -{ - "default": 1500, - "title": "Shaft Speed Rpm", - "type": "number" -}
- Removed
check_bearing_fault_peak_tool - Added
check_bearing_faults - Removed
check_bearing_faults_direct - Removed
check_custom_vibration_alert - Removed
check_vibration_alert - Removed
clear_all_signals - Removed
clear_signal - Added
clear_signals - Removed
compute_envelope_spectrum_tool - Removed
detect_signal_degradation_onset - Added
diagnose_vibration - Removed
diagnose_vibration_tool - Changed
estimate_rul35 fields changed- added
Input schema / properties / feature_valuesAdded value: +{ + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Feature Values" +} - added
Input schema / properties / method / enumAdded value: +[ + "linear", + "exponential", + "kalman" +] - removed
Input schema / properties / overlap_ratioRemoved value: -{ - "default": 0.5, - "title": "Overlap Ratio", - "type": "number" -} - removed
Input schema / properties / sampling_intervalRemoved value: -{ - "default": 1, - "title": "Sampling Interval", - "type": "number" -} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / segment_durationRemoved value: -{ - "default": 0.1, - "title": "Segment Duration", - "type": "number" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Signal Ids" +} - added
Input schema / properties / time_unitAdded value: +{ + "default": "hours", + "title": "Time Unit", + "type": "string" +} - added
Input schema / properties / timestampsAdded value: +{ + "items": { + "type": "number" + }, + "title": "Timestamps", + "type": "array" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file", - "failure_threshold" -]New value: +[ + "failure_threshold", + "timestamps" +] - changed
Output schema / descriptionPrevious value: -"Remaining Useful Life estimation result."New value: +"Remaining Useful Life estimate from repeated measurements over time.\n\nRUL is only physically meaningful when fitted on a degradation trend\nacross multiple measurements of the same machine (days/weeks/months).\n``fit_r_squared`` describes how well the degradation curve fits the\nobserved series; it is NOT a probability that the estimate is correct.\nExtrapolation beyond the observation horizon is inherently uncertain." - removed
Output schema / properties / confidenceRemoved value: -{ - "description": "R-squared or confidence metric (0-1)", - "title": "Confidence", - "type": "number" -} - removed
Output schema / properties / confidence_intervalRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "description": "[lower, upper] RUL bounds (Kalman only)", - "title": "Confidence Interval" -} - added
Output schema / properties / current_valueAdded value: +{ + "description": "Most recent measured indicator value", + "title": "Current Value", + "type": "number" +} - changed
Output schema / properties / estimated_rate / descriptionPrevious value: -"Estimated degradation rate (Kalman only)"New value: +"Estimated degradation rate in feature units per time_unit (linear/kalman)" - added
Output schema / properties / failure_thresholdAdded value: +{ + "description": "Indicator value considered as failure", + "title": "Failure Threshold", + "type": "number" +} - added
Output schema / properties / feature_nameAdded value: +{ + "description": "Degradation indicator tracked (e.g. 'rms')", + "title": "Feature Name", + "type": "string" +} - added
Output schema / properties / fit_r_squaredAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "R-squared of the fitted degradation curve on the observed data. Goodness of fit only — NOT a confidence or probability. None for the kalman method.", + "title": "Fit R Squared" +} - added
Output schema / properties / messageAdded value: +{ + "description": "Human-readable explanation of the outcome and its caveats", + "title": "Message", + "type": "string" +} - changed
Output schema / properties / method / descriptionPrevious value: -"Estimation method used"New value: +"Estimation method used: linear, exponential, or kalman" - added
Output schema / properties / num_measurementsAdded value: +{ + "description": "Number of measurements in the series", + "title": "Num Measurements", + "type": "integer" +} - added
Output schema / properties / observation_horizonAdded value: +{ + "description": "Time span covered by the measurement series (last minus first timestamp), in time_unit. RUL estimates far beyond this horizon are extrapolations with low reliability.", + "title": "Observation Horizon", + "type": "number" +} - added
Output schema / properties / precision_heuristicAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Heuristic in [0,1]: 1 - rul_std/rul, clipped (kalman only). This is a heuristic, NOT a statistical confidence — do not present it as a probability of correctness.", + "title": "Precision Heuristic" +} - added
Output schema / properties / rul / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - added
Output schema / properties / rul / defaultAdded value: +null - changed
Output schema / properties / rul / descriptionPrevious value: -"Estimated remaining useful life in time units"New value: +"Estimated remaining useful life in time_unit (only when status='estimated')" - removed
Output schema / properties / rul / typeRemoved value: -"number" - added
Output schema / properties / rul_interval_95Added value: +{ + "anyOf": [ + { + "items": { + "type": "number" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "[lower, upper] approximate 95% interval from the delta-method variance (kalman only). Coverage not validated — treat as an order-of-magnitude band.", + "title": "Rul Interval 95" +} - removed
Output schema / properties / scaleRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Weibull scale parameter (Weibull only)", - "title": "Scale" -} - removed
Output schema / properties / shapeRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Weibull shape parameter (Weibull only)", - "title": "Shape" -} - added
Output schema / properties / statusAdded value: +{ + "description": "'estimated' (RUL computed), 'no_degradation_trend' (no statistically significant trend toward the threshold — healthy outcome, no RUL number), or 'threshold_already_exceeded' (last measurement is at/above the failure threshold).", + "enum": [ + "estimated", + "no_degradation_trend", + "threshold_already_exceeded" + ], + "title": "Status", + "type": "string" +} - added
Output schema / properties / time_unitAdded value: +{ + "description": "Unit of timestamps, observation_horizon, and rul", + "title": "Time Unit", + "type": "string" +} - added
Output schema / properties / trend_p_valueAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Two-sided p-value of the series' linear slope (None when not computable). The trend gate requires p < 0.05.", + "title": "Trend P Value" +} - changed
Output schema / requiredPrevious value: -[ - "rul", - "confidence", - "method" -]New value: +[ + "status", + "method", + "feature_name", + "num_measurements", + "observation_horizon", + "time_unit", + "failure_threshold", + "current_value", + "message" +]
- Removed
evaluate_iso_20816 - Changed
extract_features_from_signal4 fields changed- removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +]
- Changed
extract_manual_specs3 fields changed- added
Input schema / properties / file_nameAdded value: +{ + "title": "File Name", + "type": "string" +} - removed
Input schema / properties / manual_filenameRemoved value: -{ - "title": "Manual Filename", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "manual_filename" -]New value: +[ + "file_name" +]
- Changed
generate_diagnostic_report_docx3 fields changed- removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file", - "sections" -]New value: +[ + "signal_id", + "sections" +]
- Changed
generate_envelope_report7 fields changed- added
Input schema / properties / filter_high / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - changed
Input schema / properties / filter_high / defaultPrevious value: -5000New value: +null - removed
Input schema / properties / filter_high / typeRemoved value: -"number" - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +]
- Changed
generate_feature_comparison_report1 field changed- removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -}
- Changed
generate_fft_report6 fields changed- removed
Input schema / properties / rotation_freqRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Rotation Freq" -} - added
Input schema / properties / rpmAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rpm" +} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +]
- Changed
generate_iso_report8 fields changed- added
Input schema / properties / machine_group / enumAdded value: +[ + 1, + 2 +] - removed
Input schema / properties / operating_speed_rpmRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Operating Speed Rpm" -} - added
Input schema / properties / rpmAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rpm" +} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - added
Input schema / properties / support_type / enumAdded value: +[ + "rigid", + "flexible" +] - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +]
- Changed
generate_maintenance_recommendations5 fields changed- removed
Input schema / properties / confidenceRemoved value: -{ - "default": 0, - "title": "Confidence", - "type": "number" -} - added
Input schema / properties / fault_types / anyOfAdded value: +[ + { + "items": { + "enum": [ + "ball", + "cage", + "inner_race", + "looseness", + "misalignment", + "outer_race", + "unbalance" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } +] - changed
Input schema / properties / fault_types / defaultPrevious value: -""New value: +null - removed
Input schema / properties / fault_types / typeRemoved value: -"string" - added
Input schema / properties / severity_zone / enumAdded value: +[ + "A", + "B", + "C", + "D" +]
- Changed
generate_pca_visualization_report3 fields changed- removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - removed
Input schema / properties / test_signal_filesRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Test Signal Files" -} - added
Input schema / properties / test_signal_idsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Test Signal Ids" +}
- Changed
generate_test_signal15 fields changed- added
Input schema / properties / signal_type / enumAdded value: +[ + "bearing_fault", + "gear_fault", + "imbalance", + "normal" +] - added
Output schema / descriptionAdded value: +"Metadata for a signal stored in the SignalRepository." - added
Output schema / properties / duration_sAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Duration in seconds", + "title": "Duration S" +} - added
Output schema / properties / filepathAdded value: +{ + "description": "Original file path", + "title": "Filepath", + "type": "string" +} - added
Output schema / properties / load_timestampAdded value: +{ + "description": "ISO 8601 timestamp when signal was loaded", + "title": "Load Timestamp", + "type": "string" +} - added
Output schema / properties / num_samplesAdded value: +{ + "description": "Number of samples", + "title": "Num Samples", + "type": "integer" +} - removed
Output schema / properties / resultRemoved value: -{ - "title": "Result", - "type": "string" -} - added
Output schema / properties / sampling_rateAdded value: +{ + "anyOf": [ + { + "exclusiveMinimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Sampling rate in Hz (must be positive when set)", + "title": "Sampling Rate" +} - added
Output schema / properties / shapeAdded value: +{ + "description": "Shape of the signal array", + "items": { + "type": "integer" + }, + "title": "Shape", + "type": "array" +} - added
Output schema / properties / signal_idAdded value: +{ + "description": "Unique identifier for the stored signal", + "title": "Signal Id", + "type": "string" +} - added
Output schema / properties / signal_unitAdded value: +{ + "anyOf": [ + { + "enum": [ + "g", + "m/s2", + "mm/s", + "m/s" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "DECLARED signal unit — from load_signal(signal_unit=...) or the companion _metadata.json ('signal_unit' field). Never guessed. None means undeclared: ISO severity verdicts will be refused until the unit is declared.", + "title": "Signal Unit" +} - added
Output schema / properties / size_bytesAdded value: +{ + "description": "Approximate memory size in bytes", + "title": "Size Bytes", + "type": "integer" +} - added
Output schema / properties / source_metadataAdded value: +{ + "additionalProperties": true, + "description": "Complete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata.", + "title": "Source Metadata", + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "signal_id", + "filepath", + "load_timestamp", + "shape", + "num_samples", + "size_bytes" +] - changed
Output schema / titlePrevious value: -"generate_test_signalOutput"New value: +"StoredSignalInfo"
- Removed
get_report_info - Changed
get_signal_info5 fields changed- changed
Output schema / properties / sampling_rate / anyOfPrevious value: -[ - { - "type": "number" - }, - { - "type": "null" - } -]New value: +[ + { + "exclusiveMinimum": 0, + "type": "number" + }, + { + "type": "null" + } +] - changed
Output schema / properties / sampling_rate / descriptionPrevious value: -"Sampling rate in Hz"New value: +"Sampling rate in Hz (must be positive when set)" - changed
Output schema / properties / signal_unit / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "g", + "m/s2", + "mm/s", + "m/s" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Output schema / properties / signal_unit / descriptionPrevious value: -"Signal unit (g, mm/s, m/s², etc.)"New value: +"DECLARED signal unit — from load_signal(signal_unit=...) or the companion _metadata.json ('signal_unit' field). Never guessed. None means undeclared: ISO severity verdicts will be refused until the unit is declared." - added
Output schema / properties / source_metadataAdded value: +{ + "additionalProperties": true, + "description": "Complete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata.", + "title": "Source Metadata", + "type": "object" +}
- Changed
list_html_reports4 fields changed- added
Input schema / properties / file_nameAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "File Name" +} - added
Output schema / properties / result / anyOfAdded value: +[ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "additionalProperties": true, + "type": "object" + } +] - removed
Output schema / properties / result / itemsRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - removed
Output schema / properties / result / typeRemoved value: -"array"
- Changed
list_signals5 fields changed- added
Input schema / properties / scopeAdded value: +{ + "default": "disk", + "enum": [ + "disk", + "memory" + ], + "title": "Scope", + "type": "string" +} - added
Output schema / additionalPropertiesAdded value: +true - removed
Output schema / propertiesRemoved value: -{ - "result": { - "title": "Result", - "type": "string" - } -} - removed
Output schema / requiredRemoved value: -[ - "result" -] - changed
Output schema / titlePrevious value: -"list_signalsOutput"New value: +"list_signalsDictOutput"
- Removed
list_stored_signals - Changed
load_signal18 fields changed- added
Input schema / properties / filepath / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - removed
Input schema / properties / filepath / typeRemoved value: -"string" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "title": "Overwrite", + "type": "boolean" +} - added
Input schema / properties / signal_unitAdded value: +{ + "anyOf": [ + { + "enum": [ + "g", + "m/s2", + "mm/s", + "m/s" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Signal Unit" +} - added
Output schema / $defsAdded value: +{ + "StoredSignalInfo": { + "description": "Metadata for a signal stored in the SignalRepository.", + "properties": { + "duration_s": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Duration in seconds", + "title": "Duration S" + }, + "filepath": { + "description": "Original file path", + "title": "Filepath", + "type": "string" + }, + "load_timestamp": { + "description": "ISO 8601 timestamp when signal was loaded", + "title": "Load Timestamp", + "type": "string" + }, + "num_samples": { + "description": "Number of samples", + "title": "Num Samples", + "type": "integer" + }, + "sampling_rate": { + "anyOf": [ + { + "exclusiveMinimum": 0, + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Sampling rate in Hz (must be positive when set)", + "title": "Sampling Rate" + }, + "shape": { + "description": "Shape of the signal array", + "items": { + "type": "integer" + }, + "title": "Shape", + "type": "array" + }, + "signal_id": { + "description": "Unique identifier for the stored signal", + "title": "Signal Id", + "type": "string" + }, + "signal_unit": { + "anyOf": [ + { + "enum": [ + "g", + "m/s2", + "mm/s", + "m/s" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "DECLARED signal unit — from load_signal(signal_unit=...) or the companion _metadata.json ('signal_unit' field). Never guessed. None means undeclared: ISO severity verdicts will be refused until the unit is declared.", + "title": "Signal Unit" + }, + "size_bytes": { + "description": "Approximate memory size in bytes", + "title": "Size Bytes", + "type": "integer" + }, + "source_metadata": { + "additionalProperties": true, + "description": "Complete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata.", + "title": "Source Metadata", + "type": "object" + } + }, + "required": [ + "signal_id", + "filepath", + "load_timestamp", + "shape", + "num_samples", + "size_bytes" + ], + "title": "StoredSignalInfo", + "type": "object" + } +} - removed
Output schema / descriptionRemoved value: -"Metadata for a signal stored in the SignalRepository." - removed
Output schema / properties / duration_sRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Duration in seconds", - "title": "Duration S" -} - removed
Output schema / properties / filepathRemoved value: -{ - "description": "Original file path", - "title": "Filepath", - "type": "string" -} - removed
Output schema / properties / load_timestampRemoved value: -{ - "description": "ISO 8601 timestamp when signal was loaded", - "title": "Load Timestamp", - "type": "string" -} - removed
Output schema / properties / num_samplesRemoved value: -{ - "description": "Number of samples", - "title": "Num Samples", - "type": "integer" -} - added
Output schema / properties / resultAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/StoredSignalInfo" + }, + { + "items": { + "$ref": "#/$defs/StoredSignalInfo" + }, + "type": "array" + } + ], + "title": "Result" +} - removed
Output schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Sampling rate in Hz", - "title": "Sampling Rate" -} - removed
Output schema / properties / shapeRemoved value: -{ - "description": "Shape of the signal array", - "items": { - "type": "integer" - }, - "title": "Shape", - "type": "array" -} - removed
Output schema / properties / signal_idRemoved value: -{ - "description": "Unique identifier for the stored signal", - "title": "Signal Id", - "type": "string" -} - removed
Output schema / properties / signal_unitRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Signal unit (g, mm/s, m/s², etc.)", - "title": "Signal Unit" -} - removed
Output schema / properties / size_bytesRemoved value: -{ - "description": "Approximate memory size in bytes", - "title": "Size Bytes", - "type": "integer" -} - changed
Output schema / requiredPrevious value: -[ - "signal_id", - "filepath", - "load_timestamp", - "shape", - "num_samples", - "size_bytes" -]New value: +[ + "result" +] - changed
Output schema / titlePrevious value: -"StoredSignalInfo"New value: +"load_signalOutput"
- Removed
lookup_bearing_and_compute_tool - Removed
plot_envelope - Removed
plot_iso_20816_chart - Changed
plot_signal4 fields changed- removed
Input schema / properties / sampling_rateRemoved value: -{ - "default": 10000, - "title": "Sampling Rate", - "type": "number" -} - removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +]
- Removed
plot_spectrum - Changed
predict_anomalies13 fields changed- removed
Input schema / properties / signal_fileRemoved value: -{ - "title": "Signal File", - "type": "string" -} - added
Input schema / properties / signal_idAdded value: +{ + "title": "Signal Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "signal_file" -]New value: +[ + "signal_id" +] - changed
Output schema / descriptionPrevious value: -"Result of anomaly detection prediction on new data."New value: +"Result of anomaly detection prediction on new data.\n\nBounded output by design: counts, score percentiles, and the worst\nsegments only — never per-segment arrays (a 6M-sample signal would\ndump tens of thousands of entries into the chat context)." - removed
Output schema / properties / anomaly_scoresRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "number" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Anomaly scores if available", - "title": "Anomaly Scores" -} - removed
Output schema / properties / confidenceRemoved value: -{ - "description": "Confidence level: 'High', 'Medium', 'Low'", - "title": "Confidence", - "type": "string" -} - added
Output schema / properties / model_nameAdded value: +{ + "description": "Name of the trained model used", + "title": "Model Name", + "type": "string" +} - changed
Output schema / properties / overall_health / descriptionPrevious value: -"Overall health status: 'Healthy', 'Suspicious', 'Faulty'"New value: +"Overall health status: 'Healthy', 'Suspicious', 'Faulty' (thresholded on anomaly_ratio: <0.1, <0.3, >=0.3)" - removed
Output schema / properties / predictionsRemoved value: -{ - "description": "Predictions per segment: 1=normal, -1=anomaly", - "items": { - "type": "integer" - }, - "title": "Predictions", - "type": "array" -} - added
Output schema / properties / score_percentilesAdded value: +{ + "anyOf": [ + { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Percentiles (p5/p25/p50/p75/p95) of the model decision scores; negative = anomalous side. None when the model exposes no decision_function.", + "title": "Score Percentiles" +} - added
Output schema / properties / segment_duration_sAdded value: +{ + "description": "Segment length in seconds (from the model's training metadata)", + "title": "Segment Duration S", + "type": "number" +} - added
Output schema / properties / worst_segmentsAdded value: +{ + "default": [], + "description": "Up to 10 most anomalous segments, each with segment_index, start_time_s, and score (when available) — enough to locate the worst regions without dumping per-segment arrays.", + "items": { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + "title": "Worst Segments", + "type": "array" +} - changed
Output schema / requiredPrevious value: -[ - "num_segments", - "anomaly_count", - "anomaly_ratio", - "predictions", - "overall_health", - "confidence" -]New value: +[ + "model_name", + "num_segments", + "anomaly_count", + "anomaly_ratio", + "segment_duration_s", + "overall_health" +]
- Changed
read_manual_excerpt3 fields changed- added
Input schema / properties / file_nameAdded value: +{ + "title": "File Name", + "type": "string" +} - removed
Input schema / properties / manual_filenameRemoved value: -{ - "title": "Manual Filename", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "manual_filename" -]New value: +[ + "file_name" +]
- Changed
search_bearing_catalog8 fields changed- removed
Input schema / properties / bearing_designationRemoved value: -{ - "title": "Bearing Designation", - "type": "string" -} - added
Input schema / properties / bearing_idAdded value: +{ + "title": "Bearing Id", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "bearing_designation" -]New value: +[ + "bearing_id" +] - added
Output schema / $defsAdded value: +{ + "BearingCatalogMiss": { + "description": "Typed 'not in catalog' result for a bearing catalog lookup.\n\nA missing catalog entry is a legitimate negative outcome, not a tool\nfailure — the catalog is intentionally small (verified geometry only),\nso the miss is expressed in the SCHEMA (status + suggestion) instead of\nan ad-hoc dict with an 'error' key. No geometry is ever invented.", + "properties": { + "bearing_id": { + "description": "The bearing designation that was searched for", + "title": "Bearing Id", + "type": "string" + }, + "catalog_contains": { + "description": "Designations actually present in the verified catalog", + "items": { + "type": "string" + }, + "title": "Catalog Contains", + "type": "array" + }, + "status": { + "const": "not_found", + "default": "not_found", + "description": "Always 'not_found' — discriminates from a catalog hit", + "title": "Status", + "type": "string" + }, + "suggestion": { + "description": "Concrete next step to obtain the bearing geometry", + "title": "Suggestion", + "type": "string" + } + }, + "required": [ + "bearing_id", + "suggestion", + "catalog_contains" + ], + "title": "BearingCatalogMiss", + "type": "object" + } +} - removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / propertiesAdded value: +{ + "result": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "$ref": "#/$defs/BearingCatalogMiss" + } + ], + "title": "Result" + } +} - added
Output schema / requiredAdded value: +[ + "result" +] - changed
Output schema / titlePrevious value: -"search_bearing_catalogDictOutput"New value: +"search_bearing_catalogOutput"
- Changed
train_anomaly_model10 fields changed- removed
Input schema / properties / fault_signal_filesRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Fault Signal Files" -} - added
Input schema / properties / fault_signal_idsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fault Signal Ids" +} - removed
Input schema / properties / healthy_signal_filesRemoved value: -{ - "items": { - "type": "string" - }, - "title": "Healthy Signal Files", - "type": "array" -} - added
Input schema / properties / healthy_signal_idsAdded value: +{ + "items": { + "type": "string" + }, + "title": "Healthy Signal Ids", + "type": "array" +} - removed
Input schema / properties / healthy_validation_filesRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Healthy Validation Files" -} - added
Input schema / properties / healthy_validation_idsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Healthy Validation Ids" +} - removed
Input schema / properties / sampling_rateRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sampling Rate" -} - changed
Input schema / requiredPrevious value: -[ - "healthy_signal_files" -]New value: +[ + "healthy_signal_ids" +] - added
Output schema / properties / model_nameAdded value: +{ + "description": "Name under which the model was saved — pass this to predict_anomalies(model_name=...)", + "title": "Model Name", + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "model_type", - "num_training_samples", - "num_features_original", - "num_features_pca", - "variance_explained", - "model_params", - "model_path", - "scaler_path", - "pca_path" -]New value: +[ + "model_name", + "model_type", + "num_training_samples", + "num_features_original", + "num_features_pca", + "variance_explained", + "model_params", + "model_path", + "scaler_path", + "pca_path" +]
46 tool updates
v0.8.0- First observed
analyze_envelope - First observed
analyze_fft - First observed
analyze_signal_trend - First observed
analyze_statistics - First observed
assess_vibration_severity - First observed
calculate_bearing_characteristic_frequencies - First observed
check_bearing_fault_peak_tool - First observed
check_bearing_faults_direct - First observed
check_custom_vibration_alert - First observed
check_vibration_alert - First observed
clear_all_signals - First observed
clear_signal - First observed
compute_envelope_spectrum_tool - First observed
compute_power_spectral_density - First observed
compute_spectrogram_stft - First observed
detect_signal_degradation_onset - First observed
diagnose_vibration_tool - First observed
estimate_rul - First observed
evaluate_iso_20816 - First observed
extract_features_from_signal - First observed
extract_manual_specs - First observed
generate_diagnostic_report_docx - First observed
generate_envelope_report - First observed
generate_feature_comparison_report - First observed
generate_fft_report - First observed
generate_iso_report - First observed
generate_maintenance_recommendations - First observed
generate_pca_visualization_report - First observed
generate_test_signal - First observed
get_report_info - First observed
get_signal_info - First observed
list_html_reports - First observed
list_machine_manuals - First observed
list_signals - First observed
list_stored_signals - First observed
load_signal - First observed
lookup_bearing_and_compute_tool - First observed
plot_envelope - First observed
plot_iso_20816_chart - First observed
plot_signal - First observed
plot_spectrum - First observed
predict_anomalies - First observed
read_manual_excerpt - First observed
search_bearing_catalog - First observed
search_documentation - First observed
train_anomaly_model
TDQS
Most tools have clearly distinct purposes, but a few overlapping clusters exist: assess_severity vs diagnose_vibration vs generate_diagnostic_report, analyze_fft vs compute_power_spectral_density, and analyze_statistics vs extract_features_from_signal. The detailed descriptions mitigate confusion, but agents could still misselect when a simpler tool would suffice.
All tool names follow a consistent verb_noun pattern with lowercase and underscores (e.g., list_signals, analyze_fft, generate_diagnostic_report). Minor deviations like extract_features_from_signal and compute_spectrogram_stft are still readable and predictable.
34 tools is excessive for the domain, especially with 9 report generation tools and overlapping analysis/diagnosis tools. The server would benefit from consolidating report generators and unifying the diagnosis pipeline.
The tool set covers the full predictive maintenance workflow: signal management, spectral analysis, bearing diagnostics, ISO severity, ML anomaly detection, RUL estimation, documentation search, and reporting. Minor gaps exist, such as no model management (list/delete) or raw data retrieval, but these are workable.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Sentiment, toxicity, entity extraction, PII, translation, summary, QA, fraud scoring, safety audit.
Connects AI assistants to QCDatabase.AI for everyday construction quality-control work.
Conversational access to advertising performance data, creative analysis, and campaign insights
Conversational access to advertising performance data, creative analysis, and campaign insights
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables predictive maintenance for electric motors by analyzing stator current signals to detect faults like broken rotor bars, bearing defects, and eccentricity, using spectral and envelope analysis techniques.219MIT
- AlicenseNot gradedqualityCmaintenanceEnables natural language analysis of mechanical test data files (CSV, TDMS, MDF) by providing tools for channel statistics, spectrum analysis, rainflow fatigue counting, thermal state detection, and report generation.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to analyze plant-floor data using OEE, Pareto, SPC, and yield-loss calculations, providing continuous-improvement insights from manufacturing data.1-
- FlicenseNot gradedqualityCmaintenanceEnables engineers and plant managers to interact with manufacturing systems using natural language, providing machine health analysis, KPI dashboards, predictive maintenance, and automated workflow execution via MCP.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/LGDiMaggio/predictive-maintenance-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server