Skip to main content
Glama
LGDiMaggio

Predictive Maintenance MCP Server

by LGDiMaggio

Predictive Maintenance MCP Server

Python 3.11+ DOI Tests codecov License: MIT LGDiMaggio/predictive-maintenance-mcp 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

Engineer's Quickstart

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.ps1

Restart Claude Desktop, then try:

"Load real_train/OuterRaceFault_1.csv and check if the bearing is healthy."

Install the package:

pip install predictive-maintenance-mcp

Find 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 PATH that often omits user-local tool directories (e.g. ~/.local/bin). Using the full path to uvx avoids a silent "command not found" failure. On Windows the typical path is C:\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 all

What Can It Do?

Point the AI at a vibration signal → get the evidence behind the fault — detected frequencies, matched fault patterns, ISO-cited severity — to support your call.

You say

The AI does

"Is this bearing healthy?"

Loads the signal, runs spectral analysis, surfaces matching fault-frequency evidence, cites the ISO 20816-3 severity zone

"Generate a full diagnostic report"

Produces an interactive HTML report with charts, fault markers, and server-authored severity wording

"Extract specs from test_pump_manual.pdf and diagnose the signal"

Reads the equipment manual, looks up the bearing model, calculates expected fault frequencies, flags which ones the signal actually shows

"Train an anomaly detector on my healthy baselines, then flag anomalies"

Trains a model on your normal data, scores new signals, flags outliers for your review

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-marketplace

The plugin adds 8 skills that activate automatically based on context (bearing-diagnosis, gear-diagnosis, quick-screening, report-generation, anomaly-detection, signal-management, documentation-search, prognostics), 2 agents that run multi-step diagnostic workflows end-to-end and hand you the evidence (diagnostic-pipeline, signal-explorer), and 3 commands for quick entry points (/pm-diagnose, /pm-screen, /pm-report).

Full skill, agent, and command reference: Plugin README.


Reports

All analysis tools generate interactive HTML reports you can open in any browser — pan, zoom, hover for details. Also supports structured Word (.docx) exports.

Envelope Analysis Report

ISO Severity Assessment

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 · models

The codebase follows a modular architecture organized around the ISO 13374 Six-Block Diagnostic standard — signal acquisition, processing, diagnostics, prognostics, and decision support as separate sub-packages. Standards implemented: ISO 13374, ISO 20816-3, MIMOSA OSA-CBM. Module-level detail: Architecture guide.

Key design choices:

  • Privacy-first — raw vibration data never leaves your machine; only computed results flow to the LLM

  • LLM-agnostic — works with Claude, ChatGPT, Microsoft Copilot Studio, or any MCP-compatible client. Use Ollama for fully air-gapped deployments

  • Modular — use only the tools you need, extend with your own


Documentation

Guide

For

Quickstart for Engineers

Get results fast, no coding required

Quickstart for Developers

Understand MCP, extend the server

Tool Catalog

Every MCP endpoint, grouped by category

Adapter Guide

Bring vendor/DAQ raw data in via explicit declarations

Plugin README

Claude Code plugin installation and usage

HTTPS Deployment

Docker + HTTPS for enterprise environments

Ollama Guide

Use with local LLMs (fully air-gapped)

Architecture

ISO 13374 block mapping and module design

Benchmark Methodology

How the CWRU diagnostic benchmark is measured

Examples

Complete diagnostic workflows

Installation

Detailed setup and troubleshooting

Contributing

How to contribute (all skill levels welcome)

Changelog

Version history


Testing

85%+ test coverage, enforced as a CI minimum, across Windows, macOS, and Linux (Python 3.11 & 3.12) — the current measured figure is on the codecov badge above.

pytest                                  # run all tests
pytest --cov=src --cov-report=html      # with coverage report

20+ test files covering signal analysis, fault detection, severity assessment, ML models, report generation, RAG search, and real bearing fault data validation.


Roadmap

  • 37 MCP endpoints (34 tools, 3 prompts) with modular architecture and a single signal_id handle

  • Claude Code plugin (8 skills, 2 agents, 3 commands)

  • 85%+ test coverage enforced in CI, CI/CD on 3 platforms

  • Docker + SSE/HTTP transport for enterprise deployment

  • Semantic document search (FAISS + TF-IDF)

  • Blind, reproducible diagnostic benchmark on the CWRU dataset (extensible to Paderborn)

  • Customizable severity thresholds

  • Remaining useful life (RUL) estimation from repeated measurements (linear, exponential, Kalman)

  • Trend analysis and degradation onset detection

  • 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.


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 tools
analyze_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.
ParametersJSON Schema
NameRequiredDescriptionDefault
num_peaksNo
signal_idYes
filter_lowNo
filter_highNo
random_seedNo
segment_durationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
diagnosisYesPeak listing and comparison guidance. No reference bearing frequencies are assumed — compare against frequencies computed for the actual bearing and shaft speed.
signal_idYesSignal identifier used
top_peaksYesTop peaks in the envelope spectrum, sorted by frequency
filter_bandYesBandpass filter band (Hz) actually used — echoed from the request
num_samplesYesNumber of samples analyzed (envelope length)
sampling_rateYesSampling rate (Hz)

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes
random_seedNo
max_frequencyNo
segment_durationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
top_peaksYesTop spectral peaks sorted by magnitude
total_binsYesTotal number of FFT bins computed
num_samplesYesNumber of analyzed samples
rms_spectralYesRMS of the magnitude spectrum
freq_range_hzYes[min_freq, max_freq] of the spectrum
sampling_rateYesSampling frequency (Hz)
peak_frequencyYesDominant peak frequency (Hz)
peak_magnitudeYesDominant peak magnitude
frequency_resolutionYesFrequency resolution (Hz)

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes
feature_nameNorms
overlap_ratioNo
segment_durationNo
onset_threshold_sigmaNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
slopeYesTrend slope in feature units per second (within the recording)
p_valueNoTwo-sided p-value of the slope (None when not computable)
interceptYesTrend intercept
r_squaredYesR-squared goodness of fit of the linear trend
feature_nameYesFeature analyzed
num_segmentsYesNumber of segments analyzed
onset_time_sNoCenter time (s) of the onset segment within the recording
analysis_scopeYesAlways 'within_recording_screening': this trend spans seconds of one recording, not the machine's life
feature_seriesYesPer-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_detectedYesWhether a degradation onset was detected after the baseline window (first value exceeding baseline mean + onset_threshold_sigma * std)
segment_times_sYesSegment center times in seconds for feature_series (same subsampling)
trend_directionYesincreasing, decreasing, or stable — based on the slope significance test (p < 0.05), not on an R-squared cutoff
series_truncatedYesTrue when feature_series was subsampled to the 50-point cap
baseline_segmentsYesNumber 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_indexNoSegment index where degradation starts (always >= baseline_segments); None when no onset detected
onset_threshold_sigmaYesBaseline standard deviations used as the onset trigger

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
rmsYesRoot Mean Square (effective value)
meanYesMean value
peakYesPeak value
std_devYesStandard deviation
kurtosisYesKurtosis (measure of impulsiveness)
skewnessYesSkewness (asymmetry)
unit_noteYesUnit declaration status and how to declare the unit for ISO severity assessment
signal_unitNoDeclared signal unit ('g', 'm/s2', 'mm/s', 'm/s') from companion metadata — never guessed from amplitude. None when not declared.
crest_factorYesCrest Factor (Peak/RMS)
peak_to_peakYesPeak-to-peak value

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmNo
signal_idNo
thresholdsNo
support_typeNorigid
machine_groupNo
machine_power_kwNo
rms_velocity_mm_sNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
axisNoMeasurement axis (informational)
zoneYesISO zone: A, B, C, or D
statusNoAlways 'assessed' — discriminates from a refused result
signal_idNoSignal identifier used (None for a direct rms_velocity_mm_s reading)
boundariesYesZone boundaries {AB, BC, CD} in mm/s (ISO or custom)
color_codeYesgreen, yellow, orange, or red
alert_levelNoAlert level derived from the zone: A=none, B=warning, C=alarm, D=danger (filled automatically)
support_typeYesSupport type: 'rigid' or 'flexible'
machine_groupYesISO 20816-3 machine group: 1 (large, >300 kW) or 2 (medium, 15-300 kW)
original_unitNoOriginal signal unit before conversion
severity_levelYesGood, Acceptable, Unsatisfactory, or Unacceptable
frequency_rangeYesActual 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_kwNoDeclared rated machine power in kW, when provided. Values below 15 kW are refused as out of ISO 20816-3 scope.
zone_descriptionYesZone description
rms_velocity_mm_sYesRMS velocity in mm/s
exceeded_thresholdNoThe boundary (mm/s) exceeded by the reading (None in zone A; filled automatically from zone + boundaries)
operating_speed_rpmNoOperating speed in RPM, when provided (selects the band's lower edge)
threshold_provenanceYesProvenance of the zone boundary values (ISO edition note, or custom-threshold note)
unit_conversion_performedYesWhether acceleration-to-velocity conversion was done

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmNo
num_ballsYes
ball_diameter_mmYes
contact_angle_degNo
pitch_diameter_mmYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmYes
num_ballsNo
signal_idYes
bearing_idNo
frequenciesNo
tolerance_pctNo
ball_diameter_mmNo
contact_angle_degNo
pitch_diameter_mmNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
rpmYesShaft speed (RPM)
sourceNoProvenance of the expected frequencies: the catalog entry's source citation (bearing_id route), or a note for user-provided geometry/frequencies
signal_idYesSignal identifier used
bearing_idNoBearing designation (catalog route); None for the explicit-frequencies and explicit-geometry routes
fault_checksYesResults for each checked frequency
most_likely_faultNoMost likely fault label if any
overall_assessmentYesSummary assessment text
shaft_frequency_hzYesShaft frequency (Hz)
bearing_frequenciesYesExpected frequencies checked (Hz), plus shaft_freq_hz
most_likely_fault_canonicalNoCanonical form of most_likely_fault (None for arbitrary labels)

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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').
ParametersJSON Schema
NameRequiredDescriptionDefault
windowNohann
npersegNo
noverlapNo
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
windowYesWindow function used
npersegYesSamples per segment
noverlapYesOverlap between segments
signal_idYesSignal identifier used
top_peaksYesTop spectral peaks by power
num_samplesYesNumber of samples analyzed
total_powerYesTotal integrated power
freq_range_hzYes[min_freq, max_freq]
sampling_rateYesSampling rate (Hz)
frequency_resolutionYesFrequency resolution (Hz)

TDQS

A4.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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').
ParametersJSON Schema
NameRequiredDescriptionDefault
windowNohann
npersegNo
noverlapNo
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
windowYesWindow function used
npersegYesSamples per segment
noverlapYesOverlap between segments
signal_idYesSignal identifier used
num_samplesYesNumber of samples analyzed
time_range_sYes[start_time, end_time]
freq_range_hzYes[min_freq, max_freq]
num_freq_binsYesNumber of frequency bins
num_time_binsYesNumber of time bins
sampling_rateYesSampling rate (Hz)
energy_per_bandYesEnergy in predefined frequency bands
max_power_time_sYesTime of maximum power
max_power_freq_hzYesFrequency with maximum power

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmYes
signal_idYes
bearing_idNo
support_typeNorigid
machine_groupNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
rpmYesMachine speed (RPM)
signal_idYesSignal identifier used
bearing_idNoBearing used (if any)
fft_summaryYesFFT key findings
psd_summaryYesPSD key findings
iso_severityYesISO 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_summaryYesSTFT key findings
support_typeYesSupport type used for severity: 'rigid' or 'flexible'
machine_groupYesISO 20816-3 machine group used for severity: 1 (large) or 2 (medium)
bearing_faultsNoBearing fault results
recommendationsYesRecommended actions
anomaly_detectionNoAnomaly detection results (health, ratio, score)
evidence_strengthYesStrength 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_diagnosisYesCombined diagnostic text

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
methodNolinear
time_unitNohours
signal_idsNo
timestampsYes
feature_nameNorms
feature_valuesNo
failure_thresholdYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
rulNoEstimated remaining useful life in time_unit (only when status='estimated')
methodYesEstimation method used: linear, exponential, or kalman
statusYes'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).
messageYesHuman-readable explanation of the outcome and its caveats
time_unitYesUnit of timestamps, observation_horizon, and rul
feature_nameYesDegradation indicator tracked (e.g. 'rms')
current_valueYesMost recent measured indicator value
fit_r_squaredNoR-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_valueNoTwo-sided p-value of the series' linear slope (None when not computable). The trend gate requires p < 0.05.
estimated_rateNoEstimated degradation rate in feature units per time_unit (linear/kalman)
rul_interval_95No[lower, upper] approximate 95% interval from the delta-method variance (kalman only). Coverage not validated — treat as an order-of-magnitude band.
num_measurementsYesNumber of measurements in the series
failure_thresholdYesIndicator value considered as failure
observation_horizonYesTime 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_heuristicNoHeuristic 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

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes
overlap_ratioNo
segment_durationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
num_segmentsYesNumber of segments extracted
feature_namesYesNames of extracted features
overlap_ratioYesOverlap ratio between segments
features_shapeYesShape of feature matrix [num_segments, num_features]
features_previewYesFirst 5 segments features (preview)
segment_duration_sYesDuration of each segment in seconds
segment_length_samplesYesSamples per segment

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).
ParametersJSON Schema
NameRequiredDescriptionDefault
file_nameYes
use_cacheNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmYes
formatsNo
signal_idYes
bearing_idNo
support_typeNorigid
machine_groupNo
baseline_signal_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
sectionsYes
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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}
    ... )
ParametersJSON Schema
NameRequiredDescriptionDefault
max_freqNo
num_peaksNo
signal_idYes
filter_lowNo
filter_highNo
bearing_freqsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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"]
    ...     }
    ... )
ParametersJSON Schema
NameRequiredDescriptionDefault
overlap_ratioNo
signal_groupsYes
features_to_plotNo
segment_durationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmNo
max_freqNo
num_peaksNo
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmNo
signal_idYes
support_typeNorigid
machine_groupNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).
ParametersJSON Schema
NameRequiredDescriptionDefault
fault_typesNo
severity_zoneYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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"}
    ... )
ParametersJSON Schema
NameRequiredDescriptionDefault
model_nameYes
true_labelsNo
overlap_ratioNo
test_signal_idsNo
segment_durationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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').
ParametersJSON Schema
NameRequiredDescriptionDefault
durationNo
noise_levelNo
random_seedNo
signal_typeNobearing_fault
sampling_rateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
shapeYesShape of the signal array
filepathYesOriginal file path
signal_idYesUnique identifier for the stored signal
duration_sNoDuration in seconds
raw_formatNoEFFECTIVE 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_bytesYesApproximate memory size in bytes
num_samplesYesNumber of samples
signal_unitNoDECLARED 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_rateNoSampling rate in Hz (must be positive when set)
load_timestampYesISO 8601 timestamp when signal was loaded
source_metadataNoComplete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata.

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
shapeYesShape of the signal array
filepathYesOriginal file path
signal_idYesUnique identifier for the stored signal
duration_sNoDuration in seconds
raw_formatNoEFFECTIVE 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_bytesYesApproximate memory size in bytes
num_samplesYesNumber of samples
signal_unitNoDECLARED 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_rateNoSampling rate in Hz (must be positive when set)
load_timestampYesISO 8601 timestamp when signal was loaded
source_metadataNoComplete companion _metadata.json of the source file (rpm/shaft_speed, reference frequencies, ...). Empty when the file has no companion metadata.

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
file_nameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).
ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNodisk

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
filepathYes
overwriteNo
signal_idNo
byte_orderNo
n_channelsNo
signal_unitNo
scale_factorNo
channel_indexNo
header_offsetNo
sample_formatNo
sampling_rateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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
    )
ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
signal_idYes
time_rangeNo
show_statisticsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
signal_idYes
model_nameNoanomaly_model

Output Schema

ParametersJSON Schema
NameRequiredDescription
model_nameYesName of the trained model used
num_segmentsYesNumber of segments analyzed
anomaly_countYesNumber of anomalies detected
anomaly_ratioYesRatio of anomalies (0-1)
overall_healthYesOverall health status: 'Healthy', 'Suspicious', 'Faulty' (thresholded on anomaly_ratio: <0.1, <0.3, >=0.3)
worst_segmentsNoUp 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_percentilesNoPercentiles (p5/p25/p50/p75/p95) of the model decision scores; negative = anomalous side. None when the model exposes no decision_function.
segment_duration_sYesSegment length in seconds (from the model's training metadata)

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
file_nameYes
max_pagesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).
ParametersJSON Schema
NameRequiredDescriptionDefault
bearing_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
top_kNo
force_reindexNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.
ParametersJSON Schema
NameRequiredDescriptionDefault
model_nameNoanomaly_model
model_typeNoOneClassSVM
pca_varianceNo
overlap_ratioNo
fault_signal_idsNo
segment_durationNo
healthy_signal_idsYes
healthy_validation_idsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
pca_pathYesPath to saved PCA file (.pkl)
model_nameYesName under which the model was saved — pass this to predict_anomalies(model_name=...)
model_pathYesPath to saved model file (.pkl)
model_typeYesType of model: 'OneClassSVM' or 'LocalOutlierFactor'
scaler_pathYesPath to saved scaler file (.pkl)
model_paramsYesBest model hyperparameters
num_features_pcaYesNumber of PCA components (features after dimensionality reduction)
validation_detailsNoValidation details with healthy and fault metrics
validation_metricsNoDetailed validation metrics (healthy/fault accuracy breakdown)
variance_explainedYesCumulative variance explained by PCA components
validation_accuracyNoOverall balanced accuracy on healthy + fault validation data
num_training_samplesYesNumber of healthy samples used for training
num_features_originalYesNumber of original features

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 3 tool updatesv0.13.0
    • Changedgenerate_test_signal1 field changed
      • addedOutput schema / properties / raw_format
        Added 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"
        +}
    • Changedget_signal_info1 field changed
      • addedOutput schema / properties / raw_format
        Added 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"
        +}
    • Changedload_signal7 fields changed
      • addedInput schema / properties / byte_order
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "little",
        +        "big"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Byte Order"
        +}
      • addedInput schema / properties / channel_index
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Channel Index"
        +}
      • addedInput schema / properties / header_offset
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Header Offset"
        +}
      • addedInput schema / properties / n_channels
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "N Channels"
        +}
      • addedInput schema / properties / sample_format
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "float32",
        +        "float64",
        +        "int16",
        +        "int32"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Sample Format"
        +}
      • addedInput schema / properties / scale_factor
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Scale Factor"
        +}
      • addedOutput schema / $defs / StoredSignalInfo / properties / raw_format
        Added 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"
        +}
  2. 1 tool updatev0.12.0
    • Addedgenerate_diagnostic_report
  3. 46 tool updatesv0.9.1
    • Changedanalyze_envelope18 fields changed
      • removedInput schema / properties / filename
        Removed value: -{
        -  "title": "Filename",
        -  "type": "string"
        -}
      • changedInput schema / properties / filter_high / default
        Previous value: -2000New value: +5000
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • changedInput schema / properties / segment_duration / default
        Previous value: -nullNew value: +1
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "filename"
        -]New value: +[
        +  "signal_id"
        +]
      • addedOutput schema / $defs
        Added 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"
        +  }
        +}
      • changedOutput schema / description
        Previous 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."
      • changedOutput schema / properties / diagnosis / description
        Previous 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."
      • changedOutput schema / properties / filter_band / description
        Previous value: -"Bandpass filter band (Hz)"New value: +"Bandpass filter band (Hz) actually used — echoed from the request"
      • changedOutput schema / properties / num_samples / description
        Previous value: -"Number of samples in envelope signal"New value: +"Number of samples analyzed (envelope length)"
      • removedOutput schema / properties / peak_frequencies
        Removed value: -{
        -  "description": "Top peak frequencies (Hz)",
        -  "items": {
        -    "type": "number"
        -  },
        -  "title": "Peak Frequencies",
        -  "type": "array"
        -}
      • removedOutput schema / properties / peak_magnitudes
        Removed value: -{
        -  "description": "Top peak magnitudes",
        -  "items": {
        -    "type": "number"
        -  },
        -  "title": "Peak Magnitudes",
        -  "type": "array"
        -}
      • addedOutput schema / properties / signal_id
        Added value: +{
        +  "description": "Signal identifier used",
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • removedOutput schema / properties / spectrum_preview_freq
        Removed value: -{
        -  "default": [],
        -  "description": "First 100 freq points (Hz)",
        -  "items": {
        -    "type": "number"
        -  },
        -  "title": "Spectrum Preview Freq",
        -  "type": "array"
        -}
      • removedOutput schema / properties / spectrum_preview_mag
        Removed value: -{
        -  "default": [],
        -  "description": "First 100 magnitude points",
        -  "items": {
        -    "type": "number"
        -  },
        -  "title": "Spectrum Preview Mag",
        -  "type": "array"
        -}
      • addedOutput schema / properties / top_peaks
        Added value: +{
        +  "description": "Top peaks in the envelope spectrum, sorted by frequency",
        +  "items": {
        +    "$ref": "#/$defs/SpectralPeak"
        +  },
        +  "title": "Top Peaks",
        +  "type": "array"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
    • Changedanalyze_fft6 fields changed
      • removedInput schema / properties / filename
        Removed value: -{
        -  "title": "Filename",
        -  "type": "string"
        -}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • changedInput schema / properties / segment_duration / default
        Previous value: -nullNew value: +1
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "filename"
        -]New value: +[
        +  "signal_id"
        +]
      • changedOutput schema / description
        Previous 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."
    • Changedanalyze_signal_trend23 fields changed
      • addedInput schema / properties / onset_threshold_sigma
        Added value: +{
        +  "default": 3,
        +  "title": "Onset Threshold Sigma",
        +  "type": "number"
        +}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
      • changedOutput schema / description
        Previous 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."
      • addedOutput schema / properties / analysis_scope
        Added value: +{
        +  "description": "Always 'within_recording_screening': this trend spans seconds of one recording, not the machine's life",
        +  "title": "Analysis Scope",
        +  "type": "string"
        +}
      • addedOutput schema / properties / baseline_segments
        Added 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"
        +}
      • addedOutput schema / properties / feature_series
        Added 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"
        +}
      • addedOutput schema / properties / onset_detected
        Added 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"
        +}
      • addedOutput schema / properties / onset_segment_index
        Added 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"
        +}
      • addedOutput schema / properties / onset_threshold_sigma
        Added value: +{
        +  "description": "Baseline standard deviations used as the onset trigger",
        +  "title": "Onset Threshold Sigma",
        +  "type": "number"
        +}
      • addedOutput schema / properties / onset_time_s
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Center time (s) of the onset segment within the recording",
        +  "title": "Onset Time S"
        +}
      • addedOutput schema / properties / p_value / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / p_value / default
        Added value: +null
      • changedOutput schema / properties / p_value / description
        Previous value: -"Statistical significance"New value: +"Two-sided p-value of the slope (None when not computable)"
      • removedOutput schema / properties / p_value / type
        Removed value: -"number"
      • changedOutput schema / properties / r_squared / description
        Previous value: -"R-squared goodness of fit"New value: +"R-squared goodness of fit of the linear trend"
      • addedOutput schema / properties / segment_times_s
        Added value: +{
        +  "description": "Segment center times in seconds for feature_series (same subsampling)",
        +  "items": {
        +    "type": "number"
        +  },
        +  "title": "Segment Times S",
        +  "type": "array"
        +}
      • addedOutput schema / properties / series_truncated
        Added value: +{
        +  "description": "True when feature_series was subsampled to the 50-point cap",
        +  "title": "Series Truncated",
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / slope / description
        Previous value: -"Trend slope per segment"New value: +"Trend slope in feature units per second (within the recording)"
      • changedOutput schema / properties / trend_direction / description
        Previous 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"
      • changedOutput schema / required
        Previous 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"
        +]
    • Changedanalyze_statistics8 fields changed
      • removedInput schema / properties / filename
        Removed value: -{
        -  "title": "Filename",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "filename"
        -]New value: +[
        +  "signal_id"
        +]
      • changedOutput schema / description
        Previous 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."
      • removedOutput schema / properties / detected_unit
        Removed value: -{
        -  "description": "Auto-detected signal unit (g acceleration or mm/s velocity)",
        -  "title": "Detected Unit",
        -  "type": "string"
        -}
      • addedOutput schema / properties / signal_unit
        Added 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"
        +}
      • changedOutput schema / properties / unit_note / description
        Previous value: -"Important note about signal units and conversion requirements"New value: +"Unit declaration status and how to declare the unit for ISO severity assessment"
      • changedOutput schema / required
        Previous 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"
        +]
    • Addedassess_severity
    • Removedassess_vibration_severity
    • Changedcalculate_bearing_characteristic_frequencies2 fields changed
      • addedInput schema / properties / rpm
        Added value: +{
        +  "default": 1500,
        +  "title": "Rpm",
        +  "type": "number"
        +}
      • removedInput schema / properties / shaft_speed_rpm
        Removed value: -{
        -  "default": 1500,
        -  "title": "Shaft Speed Rpm",
        -  "type": "number"
        -}
    • Removedcheck_bearing_fault_peak_tool
    • Addedcheck_bearing_faults
    • Removedcheck_bearing_faults_direct
    • Removedcheck_custom_vibration_alert
    • Removedcheck_vibration_alert
    • Removedclear_all_signals
    • Removedclear_signal
    • Addedclear_signals
    • Removedcompute_envelope_spectrum_tool
    • Removeddetect_signal_degradation_onset
    • Addeddiagnose_vibration
    • Removeddiagnose_vibration_tool
    • Changedestimate_rul35 fields changed
      • addedInput schema / properties / feature_values
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "number"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Feature Values"
        +}
      • addedInput schema / properties / method / enum
        Added value: +[
        +  "linear",
        +  "exponential",
        +  "kalman"
        +]
      • removedInput schema / properties / overlap_ratio
        Removed value: -{
        -  "default": 0.5,
        -  "title": "Overlap Ratio",
        -  "type": "number"
        -}
      • removedInput schema / properties / sampling_interval
        Removed value: -{
        -  "default": 1,
        -  "title": "Sampling Interval",
        -  "type": "number"
        -}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / segment_duration
        Removed value: -{
        -  "default": 0.1,
        -  "title": "Segment Duration",
        -  "type": "number"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Signal Ids"
        +}
      • addedInput schema / properties / time_unit
        Added value: +{
        +  "default": "hours",
        +  "title": "Time Unit",
        +  "type": "string"
        +}
      • addedInput schema / properties / timestamps
        Added value: +{
        +  "items": {
        +    "type": "number"
        +  },
        +  "title": "Timestamps",
        +  "type": "array"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file",
        -  "failure_threshold"
        -]New value: +[
        +  "failure_threshold",
        +  "timestamps"
        +]
      • changedOutput schema / description
        Previous 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."
      • removedOutput schema / properties / confidence
        Removed value: -{
        -  "description": "R-squared or confidence metric (0-1)",
        -  "title": "Confidence",
        -  "type": "number"
        -}
      • removedOutput schema / properties / confidence_interval
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "items": {
        -        "type": "number"
        -      },
        -      "type": "array"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "[lower, upper] RUL bounds (Kalman only)",
        -  "title": "Confidence Interval"
        -}
      • addedOutput schema / properties / current_value
        Added value: +{
        +  "description": "Most recent measured indicator value",
        +  "title": "Current Value",
        +  "type": "number"
        +}
      • changedOutput schema / properties / estimated_rate / description
        Previous value: -"Estimated degradation rate (Kalman only)"New value: +"Estimated degradation rate in feature units per time_unit (linear/kalman)"
      • addedOutput schema / properties / failure_threshold
        Added value: +{
        +  "description": "Indicator value considered as failure",
        +  "title": "Failure Threshold",
        +  "type": "number"
        +}
      • addedOutput schema / properties / feature_name
        Added value: +{
        +  "description": "Degradation indicator tracked (e.g. 'rms')",
        +  "title": "Feature Name",
        +  "type": "string"
        +}
      • addedOutput schema / properties / fit_r_squared
        Added 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"
        +}
      • addedOutput schema / properties / message
        Added value: +{
        +  "description": "Human-readable explanation of the outcome and its caveats",
        +  "title": "Message",
        +  "type": "string"
        +}
      • changedOutput schema / properties / method / description
        Previous value: -"Estimation method used"New value: +"Estimation method used: linear, exponential, or kalman"
      • addedOutput schema / properties / num_measurements
        Added value: +{
        +  "description": "Number of measurements in the series",
        +  "title": "Num Measurements",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / observation_horizon
        Added 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"
        +}
      • addedOutput schema / properties / precision_heuristic
        Added 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"
        +}
      • addedOutput schema / properties / rul / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / rul / default
        Added value: +null
      • changedOutput schema / properties / rul / description
        Previous value: -"Estimated remaining useful life in time units"New value: +"Estimated remaining useful life in time_unit (only when status='estimated')"
      • removedOutput schema / properties / rul / type
        Removed value: -"number"
      • addedOutput schema / properties / rul_interval_95
        Added 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"
        +}
      • removedOutput schema / properties / scale
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Weibull scale parameter (Weibull only)",
        -  "title": "Scale"
        -}
      • removedOutput schema / properties / shape
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Weibull shape parameter (Weibull only)",
        -  "title": "Shape"
        -}
      • addedOutput schema / properties / status
        Added 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"
        +}
      • addedOutput schema / properties / time_unit
        Added value: +{
        +  "description": "Unit of timestamps, observation_horizon, and rul",
        +  "title": "Time Unit",
        +  "type": "string"
        +}
      • addedOutput schema / properties / trend_p_value
        Added 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"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "rul",
        -  "confidence",
        -  "method"
        -]New value: +[
        +  "status",
        +  "method",
        +  "feature_name",
        +  "num_measurements",
        +  "observation_horizon",
        +  "time_unit",
        +  "failure_threshold",
        +  "current_value",
        +  "message"
        +]
    • Removedevaluate_iso_20816
    • Changedextract_features_from_signal4 fields changed
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
    • Changedextract_manual_specs3 fields changed
      • addedInput schema / properties / file_name
        Added value: +{
        +  "title": "File Name",
        +  "type": "string"
        +}
      • removedInput schema / properties / manual_filename
        Removed value: -{
        -  "title": "Manual Filename",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "manual_filename"
        -]New value: +[
        +  "file_name"
        +]
    • Changedgenerate_diagnostic_report_docx3 fields changed
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file",
        -  "sections"
        -]New value: +[
        +  "signal_id",
        +  "sections"
        +]
    • Changedgenerate_envelope_report7 fields changed
      • addedInput schema / properties / filter_high / anyOf
        Added value: +[
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / filter_high / default
        Previous value: -5000New value: +null
      • removedInput schema / properties / filter_high / type
        Removed value: -"number"
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
    • Changedgenerate_feature_comparison_report1 field changed
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
    • Changedgenerate_fft_report6 fields changed
      • removedInput schema / properties / rotation_freq
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Rotation Freq"
        -}
      • addedInput schema / properties / rpm
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Rpm"
        +}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
    • Changedgenerate_iso_report8 fields changed
      • addedInput schema / properties / machine_group / enum
        Added value: +[
        +  1,
        +  2
        +]
      • removedInput schema / properties / operating_speed_rpm
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Operating Speed Rpm"
        -}
      • addedInput schema / properties / rpm
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Rpm"
        +}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • addedInput schema / properties / support_type / enum
        Added value: +[
        +  "rigid",
        +  "flexible"
        +]
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
    • Changedgenerate_maintenance_recommendations5 fields changed
      • removedInput schema / properties / confidence
        Removed value: -{
        -  "default": 0,
        -  "title": "Confidence",
        -  "type": "number"
        -}
      • addedInput schema / properties / fault_types / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "enum": [
        +        "ball",
        +        "cage",
        +        "inner_race",
        +        "looseness",
        +        "misalignment",
        +        "outer_race",
        +        "unbalance"
        +      ],
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / fault_types / default
        Previous value: -""New value: +null
      • removedInput schema / properties / fault_types / type
        Removed value: -"string"
      • addedInput schema / properties / severity_zone / enum
        Added value: +[
        +  "A",
        +  "B",
        +  "C",
        +  "D"
        +]
    • Changedgenerate_pca_visualization_report3 fields changed
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • removedInput schema / properties / test_signal_files
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Test Signal Files"
        -}
      • addedInput schema / properties / test_signal_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Test Signal Ids"
        +}
    • Changedgenerate_test_signal15 fields changed
      • addedInput schema / properties / signal_type / enum
        Added value: +[
        +  "bearing_fault",
        +  "gear_fault",
        +  "imbalance",
        +  "normal"
        +]
      • addedOutput schema / description
        Added value: +"Metadata for a signal stored in the SignalRepository."
      • addedOutput schema / properties / duration_s
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Duration in seconds",
        +  "title": "Duration S"
        +}
      • addedOutput schema / properties / filepath
        Added value: +{
        +  "description": "Original file path",
        +  "title": "Filepath",
        +  "type": "string"
        +}
      • addedOutput schema / properties / load_timestamp
        Added value: +{
        +  "description": "ISO 8601 timestamp when signal was loaded",
        +  "title": "Load Timestamp",
        +  "type": "string"
        +}
      • addedOutput schema / properties / num_samples
        Added value: +{
        +  "description": "Number of samples",
        +  "title": "Num Samples",
        +  "type": "integer"
        +}
      • removedOutput schema / properties / result
        Removed value: -{
        -  "title": "Result",
        -  "type": "string"
        -}
      • addedOutput schema / properties / sampling_rate
        Added value: +{
        +  "anyOf": [
        +    {
        +      "exclusiveMinimum": 0,
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Sampling rate in Hz (must be positive when set)",
        +  "title": "Sampling Rate"
        +}
      • addedOutput schema / properties / shape
        Added value: +{
        +  "description": "Shape of the signal array",
        +  "items": {
        +    "type": "integer"
        +  },
        +  "title": "Shape",
        +  "type": "array"
        +}
      • addedOutput schema / properties / signal_id
        Added value: +{
        +  "description": "Unique identifier for the stored signal",
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • addedOutput schema / properties / signal_unit
        Added 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"
        +}
      • addedOutput schema / properties / size_bytes
        Added value: +{
        +  "description": "Approximate memory size in bytes",
        +  "title": "Size Bytes",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / source_metadata
        Added 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"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "result"
        -]New value: +[
        +  "signal_id",
        +  "filepath",
        +  "load_timestamp",
        +  "shape",
        +  "num_samples",
        +  "size_bytes"
        +]
      • changedOutput schema / title
        Previous value: -"generate_test_signalOutput"New value: +"StoredSignalInfo"
    • Removedget_report_info
    • Changedget_signal_info5 fields changed
      • changedOutput schema / properties / sampling_rate / anyOf
        Previous value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "exclusiveMinimum": 0,
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / sampling_rate / description
        Previous value: -"Sampling rate in Hz"New value: +"Sampling rate in Hz (must be positive when set)"
      • changedOutput schema / properties / signal_unit / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "g",
        +      "m/s2",
        +      "mm/s",
        +      "m/s"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / signal_unit / description
        Previous 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."
      • addedOutput schema / properties / source_metadata
        Added 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"
        +}
    • Changedlist_html_reports4 fields changed
      • addedInput schema / properties / file_name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "File Name"
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "additionalProperties": true,
        +    "type": "object"
        +  }
        +]
      • removedOutput schema / properties / result / items
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • removedOutput schema / properties / result / type
        Removed value: -"array"
    • Changedlist_signals5 fields changed
      • addedInput schema / properties / scope
        Added value: +{
        +  "default": "disk",
        +  "enum": [
        +    "disk",
        +    "memory"
        +  ],
        +  "title": "Scope",
        +  "type": "string"
        +}
      • addedOutput schema / additionalProperties
        Added value: +true
      • removedOutput schema / properties
        Removed value: -{
        -  "result": {
        -    "title": "Result",
        -    "type": "string"
        -  }
        -}
      • removedOutput schema / required
        Removed value: -[
        -  "result"
        -]
      • changedOutput schema / title
        Previous value: -"list_signalsOutput"New value: +"list_signalsDictOutput"
    • Removedlist_stored_signals
    • Changedload_signal18 fields changed
      • addedInput schema / properties / filepath / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  }
        +]
      • removedInput schema / properties / filepath / type
        Removed value: -"string"
      • addedInput schema / properties / overwrite
        Added value: +{
        +  "default": false,
        +  "title": "Overwrite",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / signal_unit
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "g",
        +        "m/s2",
        +        "mm/s",
        +        "m/s"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Signal Unit"
        +}
      • addedOutput schema / $defs
        Added 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"
        +  }
        +}
      • removedOutput schema / description
        Removed value: -"Metadata for a signal stored in the SignalRepository."
      • removedOutput schema / properties / duration_s
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Duration in seconds",
        -  "title": "Duration S"
        -}
      • removedOutput schema / properties / filepath
        Removed value: -{
        -  "description": "Original file path",
        -  "title": "Filepath",
        -  "type": "string"
        -}
      • removedOutput schema / properties / load_timestamp
        Removed value: -{
        -  "description": "ISO 8601 timestamp when signal was loaded",
        -  "title": "Load Timestamp",
        -  "type": "string"
        -}
      • removedOutput schema / properties / num_samples
        Removed value: -{
        -  "description": "Number of samples",
        -  "title": "Num Samples",
        -  "type": "integer"
        -}
      • addedOutput schema / properties / result
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/StoredSignalInfo"
        +    },
        +    {
        +      "items": {
        +        "$ref": "#/$defs/StoredSignalInfo"
        +      },
        +      "type": "array"
        +    }
        +  ],
        +  "title": "Result"
        +}
      • removedOutput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Sampling rate in Hz",
        -  "title": "Sampling Rate"
        -}
      • removedOutput schema / properties / shape
        Removed value: -{
        -  "description": "Shape of the signal array",
        -  "items": {
        -    "type": "integer"
        -  },
        -  "title": "Shape",
        -  "type": "array"
        -}
      • removedOutput schema / properties / signal_id
        Removed value: -{
        -  "description": "Unique identifier for the stored signal",
        -  "title": "Signal Id",
        -  "type": "string"
        -}
      • removedOutput schema / properties / signal_unit
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Signal unit (g, mm/s, m/s², etc.)",
        -  "title": "Signal Unit"
        -}
      • removedOutput schema / properties / size_bytes
        Removed value: -{
        -  "description": "Approximate memory size in bytes",
        -  "title": "Size Bytes",
        -  "type": "integer"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "signal_id",
        -  "filepath",
        -  "load_timestamp",
        -  "shape",
        -  "num_samples",
        -  "size_bytes"
        -]New value: +[
        +  "result"
        +]
      • changedOutput schema / title
        Previous value: -"StoredSignalInfo"New value: +"load_signalOutput"
    • Removedlookup_bearing_and_compute_tool
    • Removedplot_envelope
    • Removedplot_iso_20816_chart
    • Changedplot_signal4 fields changed
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "default": 10000,
        -  "title": "Sampling Rate",
        -  "type": "number"
        -}
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
    • Removedplot_spectrum
    • Changedpredict_anomalies13 fields changed
      • removedInput schema / properties / signal_file
        Removed value: -{
        -  "title": "Signal File",
        -  "type": "string"
        -}
      • addedInput schema / properties / signal_id
        Added value: +{
        +  "title": "Signal Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "signal_file"
        -]New value: +[
        +  "signal_id"
        +]
      • changedOutput schema / description
        Previous 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)."
      • removedOutput schema / properties / anomaly_scores
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "items": {
        -        "type": "number"
        -      },
        -      "type": "array"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "description": "Anomaly scores if available",
        -  "title": "Anomaly Scores"
        -}
      • removedOutput schema / properties / confidence
        Removed value: -{
        -  "description": "Confidence level: 'High', 'Medium', 'Low'",
        -  "title": "Confidence",
        -  "type": "string"
        -}
      • addedOutput schema / properties / model_name
        Added value: +{
        +  "description": "Name of the trained model used",
        +  "title": "Model Name",
        +  "type": "string"
        +}
      • changedOutput schema / properties / overall_health / description
        Previous 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)"
      • removedOutput schema / properties / predictions
        Removed value: -{
        -  "description": "Predictions per segment: 1=normal, -1=anomaly",
        -  "items": {
        -    "type": "integer"
        -  },
        -  "title": "Predictions",
        -  "type": "array"
        -}
      • addedOutput schema / properties / score_percentiles
        Added 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"
        +}
      • addedOutput schema / properties / segment_duration_s
        Added value: +{
        +  "description": "Segment length in seconds (from the model's training metadata)",
        +  "title": "Segment Duration S",
        +  "type": "number"
        +}
      • addedOutput schema / properties / worst_segments
        Added 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"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
    • Changedread_manual_excerpt3 fields changed
      • addedInput schema / properties / file_name
        Added value: +{
        +  "title": "File Name",
        +  "type": "string"
        +}
      • removedInput schema / properties / manual_filename
        Removed value: -{
        -  "title": "Manual Filename",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "manual_filename"
        -]New value: +[
        +  "file_name"
        +]
    • Changedsearch_bearing_catalog8 fields changed
      • removedInput schema / properties / bearing_designation
        Removed value: -{
        -  "title": "Bearing Designation",
        -  "type": "string"
        -}
      • addedInput schema / properties / bearing_id
        Added value: +{
        +  "title": "Bearing Id",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "bearing_designation"
        -]New value: +[
        +  "bearing_id"
        +]
      • addedOutput schema / $defs
        Added 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"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "result": {
        +    "anyOf": [
        +      {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      {
        +        "$ref": "#/$defs/BearingCatalogMiss"
        +      }
        +    ],
        +    "title": "Result"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "result"
        +]
      • changedOutput schema / title
        Previous value: -"search_bearing_catalogDictOutput"New value: +"search_bearing_catalogOutput"
    • Changedtrain_anomaly_model10 fields changed
      • removedInput schema / properties / fault_signal_files
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Fault Signal Files"
        -}
      • addedInput schema / properties / fault_signal_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Fault Signal Ids"
        +}
      • removedInput schema / properties / healthy_signal_files
        Removed value: -{
        -  "items": {
        -    "type": "string"
        -  },
        -  "title": "Healthy Signal Files",
        -  "type": "array"
        -}
      • addedInput schema / properties / healthy_signal_ids
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Healthy Signal Ids",
        +  "type": "array"
        +}
      • removedInput schema / properties / healthy_validation_files
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Healthy Validation Files"
        -}
      • addedInput schema / properties / healthy_validation_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Healthy Validation Ids"
        +}
      • removedInput schema / properties / sampling_rate
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "number"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Sampling Rate"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "healthy_signal_files"
        -]New value: +[
        +  "healthy_signal_ids"
        +]
      • addedOutput schema / properties / model_name
        Added value: +{
        +  "description": "Name under which the model was saved — pass this to predict_anomalies(model_name=...)",
        +  "title": "Model Name",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
  4. 46 tool updatesv0.8.0
    • First observedanalyze_envelope
    • First observedanalyze_fft
    • First observedanalyze_signal_trend
    • First observedanalyze_statistics
    • First observedassess_vibration_severity
    • First observedcalculate_bearing_characteristic_frequencies
    • First observedcheck_bearing_fault_peak_tool
    • First observedcheck_bearing_faults_direct
    • First observedcheck_custom_vibration_alert
    • First observedcheck_vibration_alert
    • First observedclear_all_signals
    • First observedclear_signal
    • First observedcompute_envelope_spectrum_tool
    • First observedcompute_power_spectral_density
    • First observedcompute_spectrogram_stft
    • First observeddetect_signal_degradation_onset
    • First observeddiagnose_vibration_tool
    • First observedestimate_rul
    • First observedevaluate_iso_20816
    • First observedextract_features_from_signal
    • First observedextract_manual_specs
    • First observedgenerate_diagnostic_report_docx
    • First observedgenerate_envelope_report
    • First observedgenerate_feature_comparison_report
    • First observedgenerate_fft_report
    • First observedgenerate_iso_report
    • First observedgenerate_maintenance_recommendations
    • First observedgenerate_pca_visualization_report
    • First observedgenerate_test_signal
    • First observedget_report_info
    • First observedget_signal_info
    • First observedlist_html_reports
    • First observedlist_machine_manuals
    • First observedlist_signals
    • First observedlist_stored_signals
    • First observedload_signal
    • First observedlookup_bearing_and_compute_tool
    • First observedplot_envelope
    • First observedplot_iso_20816_chart
    • First observedplot_signal
    • First observedplot_spectrum
    • First observedpredict_anomalies
    • First observedread_manual_excerpt
    • First observedsearch_bearing_catalog
    • First observedsearch_documentation
    • First observedtrain_anomaly_model

TDQS

A4.3/5.0
Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count2/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessWithin a week

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

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    21
    9
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to analyze plant-floor data using OEE, Pareto, SPC, and yield-loss calculations, providing continuous-improvement insights from manufacturing data.
    1
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables 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

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