Skip to main content
Glama
lucksmiler-A1

Predictive Maintenance MCP Server

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: mcp-server-mcsa

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

"What changed on pump P-101 since the baseline?"

Reads the asset's recorded history, compares the latest acquisitions with the declared reference, and reports each indicator's change with the criterion it applied

The AI doesn't guess: it calls 41 specialized MCP endpoints (38 tools + 3 prompts) running locally on your machine. Every signal is referenced by a single signal_id handle from load to report. Your data never leaves your infrastructure.

Full endpoint reference, grouped by category: Tool Catalog.


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


Asset Health Ledger

A single diagnosis answers "what does this signal show". The asset health ledger answers "what changed on this machine since the reference", from measurements taken weeks apart, on terms the engineer declared.

  • Declared identity. The companion metadata file names the asset, the measurement point and the acquisition instant, plus the conditions a comparison depends on (speed, load, sensor, direction). Nothing is inferred from file names or content.

  • A history that survives restarts. Every loaded measurement with an identity is recorded in a local append-only ledger, one JSON Lines file per asset, with its derived indicators. Waveforms are never copied, events are never rewritten.

  • Qualified comparability. A measurement that contradicts its point or its reference (another unit family, another direction, a speed too far off) is excluded with the reason; one that only lacks context (no speed, no direction, a naive timestamp) stays in the trend with the qualification attached.

  • A reference that is declared, never assumed. The engineer declares which measurements are the healthy baseline, and the declaration is attributed. Without one, the first comparable acquisitions serve as a relative reference and are never called healthy.

  • Change with its criterion. Each indicator is judged against the reference band; the classification (no change, isolated episode, unconfirmed single acquisition, persistent change) states the rule it applied, and bearing evidence is counted over the last acquisitions.

Four tools carry the workflow: declare_measurement_point, declare_healthy_baseline, get_asset_history and assess_asset_change. The ledger puts the evidence over time in front of the engineer; the judgement about the machine stays with the engineer. Contract and operations: Adapter Guide · worked flow: Examples · reference adapter: STWIN.box.


Architecture

          YOU (natural language)
               │
               v
     LLM (Claude, GPT, Ollama...)
     understands intent, selects tools
               │
               v  ── Model Context Protocol ──
    ┌──────────────────────────────┐
    │    Predictive Maintenance    │
    │         MCP Server           │
    │                              │
    │  Signal Analysis    Reports  │
    │  Fault Detection    ML       │
    │  Severity Rating    RAG Docs │
    └──────────────────────────────┘
               │
               v
       YOUR DATA (stays local)
    signals · manuals · models

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

Key design choices:

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

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

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


Documentation

Guide

For

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

  • 41 MCP endpoints (38 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

  • Asset health ledger: per-asset measurement history with a declared reference and qualified comparability

  • Multi-signal trending and historical comparison

  • Real-time streaming (MQTT/Kafka)

  • Fleet dashboard for multi-asset monitoring

  • CMMS integration (SAP, Maximo, Infor)

Ideas? Open a discussion or create an issue.


Are you using this?

I'd genuinely love to know. Whether you ran it on real machinery or just tried the sample data, drop a line in Discussions — one sentence about your machine or use case is enough. Real-world feedback directly shapes what gets built next.


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

38 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_asset_changeA

Assess the change of one measurement point against its reference.

Needs nothing but the asset and the point: the measurements, their
snapshots and the declarations are read from the ledger. The reference
is the active declared baseline when one exists (health_declared True,
declarer cited), else the first reference_measurements comparable
acquisitions of the point, reported as a relative comparison whose
health is not declared. For every amplitude indicator (rms, peak, 1x,
ISO velocity, envelope amplitude at each bearing fault frequency) the
reference band is mean plus or minus max(3 sigma, 25 percent) and the
post-reference acquisitions are classified as no_change,
isolated_episode, unconfirmed_single_acquisition or persistent_change
with the criterion spelled out; bearing evidence is counted over the
last_k acquisitions; the overall verdict is the most severe. Every
comparability qualification is reported and non-comparable
acquisitions are listed, never silently dropped. The result carries at
most one suggested_verification, no list of recommendations.

Snapshots are comparable only on one processing lineage. When no
lineage covers every evaluated acquisition the status is
processing_not_homogeneous and the remedy is this call with
reprocess=True, which first recomputes the stale snapshots with the
current lineage: idempotent (a repeated call recomputes nothing that
is already current), bounded to 10 measurements per call (reference
members first, then the most recent), verified against the recorded
file hash, and the reprocess block names the exact next call while
measurements remain. Old snapshots are never deleted.

Args:
    ctx: MCP context. Unused, see this module's docstring on logging.
    asset_id: The asset (ledger id).
    measurement_point_id: The point (ledger id).
    acquired_since: ISO 8601 lower bound of the assessed post-reference
        acquisitions (the reference is always used), or None.
    acquired_until: ISO 8601 upper bound, or None.
    last_k: Acquisitions listed for drill-down and scanned for bearing
        evidence (1 to 50).
    reference_measurements: Size of the automatic reference window
        when no baseline is declared (3 to 100).
    reprocess: Recompute up to 10 stale snapshots with the current
        lineage before assessing.

Returns:
    AssetChangeAssessment with status 'assessed', 'not_found',
    'insufficient_history' or 'processing_not_homogeneous'.

Raises:
    ValueError: Invalid ids, last_k or reference_measurements outside
        their range, a bound that is not ISO 8601, or a ledger that
        cannot be read.
ParametersJSON Schema
NameRequiredDescriptionDefault
last_kNo
asset_idYes
reprocessNo
acquired_sinceNo
acquired_untilNo
measurement_point_idYes
reference_measurementsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
remedyNoConcrete action for 'insufficient_history' or 'processing_not_homogeneous' (the exact re-processing call); None otherwise
statusYesOutcome discriminator (see the class description)
derivedNoDerived comparisons: deltas per indicator against the reference mean, exceedance_runs, drift regressions, iso_change (change against 25 percent of the ISO 20816-3 B/C boundary when group and support are known) and per_indicator classifications with their criterion; None unless assessed
lineageNoProcessing lineage the assessment used: processing_id, algorithm_version, covered slots, candidates per lineage, current_processing_id, is_current, missing_for_current, stale_context; None unless assessed
messageYesOne-paragraph summary of the outcome
assessedNoThe verdict: classification ('no_change', 'isolated_episode', 'unconfirmed_single_acquisition', 'persistent_change'), direction ('increase' or 'decrease'), sudden, criterion, indicators_driving, onset_measurement_id, onset_acquired_at, onset_coincides_with (qualifications of the onset acquisition) and evidence per bearing label; None unless assessed
asset_idYesThe assessed asset (ledger id)
lineagesNoCovered evaluated slots per processing lineage ('processing_not_homogeneous')
observedNoObserved values: reference_statistics per indicator (mean, std, n, band, unit), latest values, latest_measurement_id, latest_acquired_at, evidence_presence per bearing label over the last K acquisitions, indicators_unavailable with reasons, acquisitions_assessed, slots_assessed, measurement_ids_assessed; None unless assessed
requiredNoSlots required ('insufficient_history')
availableNoUsable acquisition slots available ('insufficient_history')
referenceNoThe reference used: kind ('automatic_window' or 'declared_baseline'), health_declared (True only for a declared baseline), message (cites declared_by, declared_at and note of a baseline verbatim), measurement_ids, count, acquired_from, acquired_to, provisional, statistics_quality ('relative_only', 'provisional', 'full'), qualification_codes of the reference slots, outside_window, baseline, withdrawn_baseline, excluded_inside_span; None for a miss
reprocessNoOutcome of the re-processing run before the assessment when reprocess=True: processing_id, stale, reprocessed, not_reprocessable, up_to_date, remaining, results per attempted measurement, next_call (the exact call to continue, or None) and message; None when reprocess was False
suggestionNoConcrete next step on 'not_found'; None otherwise
known_assetsYesAsset ids the ledger directory lists (for a miss); else empty
known_pointsYesPoints of a known asset when the point is unknown; else empty
comparabilityNoComparability of the point's acquisitions: counts per grade, qualifications (code, count, detail), excluded measurements with reasons and collapsed duplicates; None for a miss
evaluated_slotsNoEvaluated slots, reference plus post-reference ('processing_not_homogeneous')
missing_for_currentNoEvaluated slots without a snapshot on the current lineage ('processing_not_homogeneous')
measurement_point_idYesThe assessed point (ledger id)
current_processing_idNoThe current processing lineage ('processing_not_homogeneous')
suggested_verificationNoAt most ONE verification sentence the evidence calls for; None when no verification is needed or the point was not assessed

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it details the reference selection logic, classification criteria, severity aggregation, comparability handling, and the exact reprocess behavior (idempotent, bounded to 10, hash-verified, next-call guidance). It also mentions return statuses and exceptions. The only minor gap is not stating whether the tool mutates state—reprocess=True does modify snapshots, but that is implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loads the core logic, but it is quite long with multiple embedded clauses and parenthetical details. The structure is logical yet verbose, and some sentences could be streamlined. It earns its place but is not tightly concise.

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 (7 parameters, 0% schema coverage, output schema present, no annotations), the description is remarkably complete. It covers reference logic, classification, comparability, reprocessing, return statuses, and exceptions. An agent has enough context to invoke it correctly without external documentation.

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 asset_id, measurement_point_id, acquired_since/until (as ISO 8601 bounds), last_k (1 to 50), reference_measurements (3 to 100), and reprocess. It adds meaning beyond the schema, such as the reference window size when no baseline is declared and the role of last_k in bearing evidence. The //ctx parameter is noted as unused but not fully described.

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?

States a specific verb+resource: 'Assess the change of one measurement point against its reference.' It distinguishes itself from siblings like declare_healthy_baseline and analyze_signal_trend by focusing on a single measurement point and a declared or automatic reference. An agent can immediately tell it evaluates change status for an asset point.

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 explains the core use case and mentions reprocess=True when processing lineage is not homogeneous, which implies when to use that flag. However, it does not explicitly compare against alternatives like assess_severity or analyze_signal_trend, nor does it state when-not to use this tool. Usage guidance is implied but lacks explicit routing.

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.

Memory only; the asset ledger on disk is untouched. A measurement
recorded at load time stays in its asset's history, and re-loading the
file later is recognized as the same measurement.

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.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and largely meets it: it discloses the memory-vs-disk boundary, that a load-time measurement persists in asset history, and the return shape (cleared_count, signal_id, status). It does not state whether the in-memory removal is irreversible for the session or note any confirmation/authorization requirements, leaving a gap for a mutating tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core behavior is well front-loaded in the first two paragraphs, but the Args/Returns docstring boilerplate is wasteful: the ctx entry references an external module docstring that an agent cannot see, and the Returns block duplicates the output schema that already exists. Roughly a third of the text does not earn its place.

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 a single-parameter tool with an output schema present, the description is nearly complete on behavior, side effects, and persistence semantics. The redundant Returns section and the phantom ctx parameter are the only meaningful blemishes, and neither blocks correct invocation.

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, and it does: signal_id is explained as the ID to remove with None (default) clearing the whole cache, which fully resolves the anyOf string/null ambiguity. It is docked slightly for documenting a 'ctx' argument that does not exist in the input schema, which adds confusion rather than 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 specific verb and resource ('Remove one signal — or all signals — from the in-memory repository') and pins the scope to the in-memory cache, which cleanly separates it from disk-oriented siblings like load_signal and the list_* tools. An agent can identify the operation without opening the schema.

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 gives clear context for when this applies ('Memory only; the asset ledger on disk is untouched') and explains the reload-recognition behavior, which helps an agent decide whether clearing is safe. It stops short of explicitly naming alternatives or when-not-to-use conditions, so it lands below the top tier.

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.

declare_healthy_baselineA

Declare which recorded measurements are the healthy reference of a point.

Until a baseline is declared, assess_asset_change compares against the
first comparable acquisitions of the point and says so
(health_declared False); a declared baseline is the only reference
reported as declared healthy, and every assessment cites declared_by,
the date and the note verbatim. The ids come from load_signal or
get_asset_history (measurement_id); every member must be a recorded
measurement of THIS point, comparable or qualified against the point's
current declaration and against the other members (a contradicting
unit, direction or speed is refused with the reason), and no two may
share an acquisition slot. At least 3 members. An empty
measurement_ids withdraws the active baseline and requires a note;
later assessments fall back to the automatic window and name the
withdrawal. Each member records the declaration versions it was
validated against, so a later re-declaration excludes it with a
qualification instead of silently changing the reference.

Args:
    ctx: MCP context. Unused, see this module's docstring on logging.
    asset_id: The asset (ledger id).
    measurement_point_id: The point (ledger id).
    measurement_ids: measurement_id values of the members (at least 3,
        at most 100), or an empty list to withdraw.
    declared_by: Who declares (required, free text, at most 200
        characters, one line); quoted verbatim in later assessments.
    note: Free-text note (at most 200 characters); required for a
        withdrawal.

Returns:
    BaselineDeclarationResult with the baseline_id, the members with
    their recorded versions, the superseded baseline and a summary.

Raises:
    ValueError: Invalid ids or free text, an empty declared_by, an
        asset without a ledger (naming the known assets), an id that is
        not a measurement of the point (naming the valid ids), fewer
        than 3 members, two members in one acquisition slot, a member
        that is not comparable (naming the reason), a withdrawal
        without a note or without an active baseline, or a ledger that
        cannot be read or written.
ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
asset_idYes
declared_byYes
measurement_idsYes
measurement_point_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoFree-text note of the declarer, as given; None when absent
membersYesOne entry per member: measurement_id, declaration_version of the measurement and point_declaration_version it was validated against (a later re-declaration excludes the member at query time with a qualification, never silently)
messageYesOne-paragraph summary of the outcome
asset_idYesAsset the point belongs to (ledger id)
event_idYesId of the appended ledger event
withdrawnYesTrue when this call withdrew the active baseline (empty list)
baseline_idYesDeterministic id of this baseline declaration (hash of the point, the sorted measurement ids and the declaration instant)
declared_atYesDeclaration instant (ISO 8601, UTC)
declared_byYesWho declared the baseline, as given by the caller; quoted verbatim in every assessment that uses it
measurement_idsYesMembers of the baseline in acquisition order; empty for a withdrawal
measurement_point_idYesThe point (ledger id)
superseded_baseline_idNoId of the baseline that was active before this call; None when the point had none

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 the full burden and does so: eligibility rules (members must be recorded measurements of THIS point, comparable or qualified against the current declaration, no two sharing an acquisition slot, 3-100 members), versioning semantics after re-declaration, withdrawal behavior, and a Raises section enumerating every rejection reason. This is far beyond what structured fields provide.

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?

Front-loads the core purpose and is organized into Args/Returns/Raises, but some material is redundant with structured fields (the Returns block restates the output schema, and the Raises list is long). The length is justified by tool complexity, though it could be trimmed slightly.

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 mutation tool with five parameters, no annotations, and a complex validation model, the description covers invocation, constraints, side effects on assess_asset_change, withdrawal semantics, and error conditions. An output schema exists, so the extra return detail is a bonus rather than a necessity.

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%, and the description fully compensates: it names each argument, gives the source of measurement_ids, the 3-100 bounds, the free-text limits (200 chars, one line) for declared_by and note, and the withdrawal-only requirement for note. Nothing is left for the agent to infer.

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?

States a specific verb and resource: 'Declare which recorded measurements are the healthy reference of a point.' It also positions the tool against its main sibling by explaining that assess_asset_change uses this baseline, so an agent can tell the two apart without opening either schema.

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?

Explicitly describes the condition under which the tool matters (until declared, assess_asset_change falls back to first comparable acquisitions), where the ids come from (load_signal, get_asset_history), and the alternative behavior of passing an empty list to withdraw, including the requirement of a note and the resulting fallback to the automatic window.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

declare_measurement_pointA

Declare the context of a measurement point in the local asset ledger.

The declaration is what the health snapshots and diagnose_vibration
default to for every measurement of the point: the bearing at the
point (bearing_id from the verified catalog, or fault_orders as
multiples of the shaft frequency: BPFO, BPFI, BSF, FTF), the design
speed nominal_rpm (distinct from the rpm a measurement declares, which
wins when present), the ISO 20816-3 machine_group and support_type
(undeclared means no ISO block, never a silent default), the rated
power, and what the point expects of its measurements: signal unit,
sensor and direction (a measurement contradicting them is excluded
from the trend, one omitting them is qualified).

Versioned per point: a re-declaration that changes nothing appends
nothing and returns the current version; one that changes a value
appends the next version and reports the changed keys. Measurements
whose snapshot was computed with a previous context are counted in
measurements_with_stale_context together with the exact
assess_asset_change(..., reprocess=True) call that recomputes them (a
note-only change makes nothing stale).

Args:
    ctx: MCP context. Unused, see this module's docstring on logging.
    asset_id: The asset (letters, digits, '_', '-', '.', starting with
        a letter or digit; case-sensitive).
    measurement_point_id: The point on the asset (same grammar).
    bearing_id: Catalog designation of the bearing at the point.
    fault_orders: {label: order} with labels BPFO, BPFI, BSF, FTF and
        orders in multiples of the shaft frequency (e.g. BPFO 3.58).
    machine_group: ISO 20816-3 group, 1 (large) or 2 (medium).
    support_type: 'rigid' or 'flexible'.
    machine_power_kw: Rated power in kW (positive).
    expected_signal_unit: Unit the point's measurements are expected in.
    expected_sensor_id: Sensor expected at the point (free text, at
        most 200 characters, one line).
    expected_direction: Expected measurement direction.
    nominal_rpm: Design speed of the point in rev/min (positive).
    declared_by: Who declares (free text, at most 200 characters).
    note: Free-text note (at most 200 characters, one line).

Returns:
    MeasurementPointDeclarationResult with the version, whether an
    event was appended, the changed keys, the stale-snapshot count and
    remedy, the recorded declaration and a summary message.

Raises:
    ValueError: Invalid ids, a value outside its vocabulary, a
        non-positive number, free text over the limit or with control
        characters (one message names every problem), or a ledger
        that cannot be read or written.
ParametersJSON Schema
NameRequiredDescriptionDefault
noteNo
asset_idYes
bearing_idNo
declared_byNo
nominal_rpmNo
fault_ordersNo
support_typeNo
machine_groupNo
machine_power_kwNo
expected_directionNo
expected_sensor_idNo
expected_signal_unitNo
measurement_point_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
remedyNoThe exact assess_asset_change(..., reprocess=True) call that recomputes the stale snapshots (bounded per call); None when nothing is stale
changedYesDeclared keys whose value differs from the previous version (every key declared with a value for version 1; empty when nothing was appended)
messageYesOne-paragraph summary of the outcome
appendedYesTrue when a new declaration version was appended to the ledger; False when the declaration equals the current version
asset_idYesAsset the point belongs to (ledger id)
event_idNoId of the appended ledger event; None when nothing was appended
declarationYesThe point declaration as recorded in the ledger: measurement_point_id, declaration_version, bearing_id, fault_orders, machine_group, support_type, machine_power_kw, expected_signal_unit, expected_sensor_id, expected_direction, nominal_rpm (the design speed of the point, distinct from the observed rpm of a measurement), declared_by, note, changed
previous_versionNoVersion this declaration supersedes; None for a first declaration
bearing_in_catalogNoWhether the declared bearing_id is in the verified bearing catalog (a bearing outside it leaves the bearing block of every snapshot missing); None when no bearing_id is declared
declaration_versionYesVersion of the point's declaration after this call (1-based, per point); unchanged when nothing was appended
measurement_point_idYesThe declared point (ledger id)
measurements_with_stale_contextYesRecorded measurements of the point that lack a health snapshot computed with the current declared context and the current processing lineage; their existing snapshots are kept

TDQS

A4.5/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 delivers: versioning semantics (a no-op re-declaration appends nothing and returns the current version; a change appends and reports changed keys), precedence rules (a measurement's rpm wins over nominal_rpm), contradiction handling (contradicting measurements are excluded, omitting ones qualified), the 'no silent default' ISO behavior, and the stale-snapshot count plus the exact reprocess remedy call.

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?

Args/Returns/Raises headers give good structure and the purpose is front-loaded, so the length is defensible for a 13-parameter, versioned tool. It loses a point for dense, parenthesis-heavy prose and for a Returns section that duplicates the existing output schema.

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 high-complexity versioned mutation with 0% schema coverage and no annotations, the description covers all parameters, the versioning/staleness model, the remedy call, and the ValueError conditions in one place. An agent has everything needed to invoke it correctly, even though the output schema already exists.

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, and it does: it documents id grammar (letters/digits/underscore/dash/dot, leading alnum, case-sensitive), fault_orders labels and shaft-multiple convention, machine_group 1/2, support_type values, positive-number constraints on nominal_rpm and machine_power_kw, and the 200-char one-line limits on free text. This meaning is not recoverable from the schema alone.

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 names a specific verb (declare) and resource (the context of a measurement point in the local asset ledger), then enumerates exactly what that context comprises. It also positions the tool relative to consumers like health snapshots and diagnose_vibration, so an agent can tell what it does without opening the schema.

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?

It explains what the declaration feeds (snapshots and diagnose_vibration defaults) and when stale context arises, which implies usage. However it never states when to prefer this over the sibling declare_healthy_baseline, nor gives an explicit when-to-use / when-not-to-use rule, leaving routing to inference.

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.

Diagnostic parameters default to the DECLARED context of the signal
(the result's parameter_sources block says where each value came
from): an explicit argument always wins; rpm then falls back to the
rpm declared in the companion's "measurement" object, then to the
nominal_rpm of the measurement point's current declaration in the
asset ledger (declare_measurement_point), and with no source anywhere
the call is refused, never defaulted; bearing_id, machine_group and
support_type fall back to the point's current declaration, and
machine_group / support_type then to the historical defaults 2 and
'rigid' (without a bearing anywhere the bearing block is skipped). A
point declared with fault_orders but no bearing_id gets no bearing
block in this stage — frequency sets are not supported here; the
result says so and names check_bearing_faults(frequencies=...). A
signal loaded without a measurement identity behaves exactly as
before: only the explicit arguments and the historical defaults apply.

Args:
    ctx: MCP context. Unused — see this module's docstring on logging.
    signal_id: ID of the stored signal.
    rpm: Machine operating speed in RPM. Optional: the measurement's
        declared rpm, then the point's nominal_rpm.
    bearing_id: Bearing designation for fault detection. Optional: the
        point's declared bearing_id.
    machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW).
        Optional: the point's declaration, then 2.
    support_type: 'rigid' or 'flexible'. Optional: the point's
        declaration, then 'rigid'.

Raises:
    ValueError: If the stored signal has no sampling rate, if no rpm
        can be resolved from the call, the measurement or the point
        (the message names the three remedies), or if the point's
        declaration carries a malformed value.
ParametersJSON Schema
NameRequiredDescriptionDefault
rpmNo
signal_idYes
bearing_idNo
support_typeNo
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
parameter_sourcesNoOrigin of each diagnostic parameter, keyed rpm, bearing_id, machine_group and support_type. Precedence: 'explicit' (passed to the call) > 'measurement' (the rpm declared in the companion's "measurement" object) > 'point' (the current declaration of the measurement point in the asset ledger: nominal_rpm, bearing_id, machine_group, support_type) > 'default' (the historical machine_group=2 / support_type='rigid'; rpm has no default and is refused instead). bearing_id only: 'none' (no bearing from any source, bearing block skipped) or 'not_supported_fault_orders' (the point declares fault_orders without a bearing_id: the bearing block was not computed because frequency sets are not supported by diagnose_vibration in this stage; use check_bearing_faults(frequencies=...)).

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 the full behavioral burden and does so richly: it discloses graceful degradation (refusal block instead of failure), the never-guess-units policy, the exact precedence chain for rpm/bearing_id/machine_group/support_type, which blocks get skipped, and the ValueError conditions. This is far beyond anything the schema or annotations convey.

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?

Front-loaded with the one-line summary, then behavior, then Args/Raises, so a reader can stop early. It is long and somewhat repetitive (the degradation/refusal theme is restated across two paragraphs with heavy capitalization), but for a multi-mode diagnostic pipeline most of it earns its place.

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?

An output schema exists, so return values need not be described; the description instead covers the things structured data cannot — degradation semantics, unit requirements, parameter resolution, and error conditions. Nothing an agent needs to invoke it correctly is missing.

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% and the schema only gives bare types/enums/defaults, so the description must compensate — and it does: each of the five parameters gets a purpose plus its full resolution fallback chain (e.g. rpm → declared measurement rpm → point nominal_rpm → refuse). This adds substantial meaning the schema 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?

Opens with a specific verb+resource and enumerates the composed analyses (FFT + PSD + STFT + bearing faults + ISO severity), which instantly distinguishes it from siblings like analyze_fft, compute_power_spectral_density, check_bearing_faults and assess_severity that each do one slice. An agent can tell this is the umbrella pipeline without opening the schema.

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?

Framing it as the 'comprehensive' pipeline that 'runs all analyses' clearly signals when to reach for it over the single-analysis siblings, and it names check_bearing_faults(frequencies=...) as the alternative when a point has fault_orders but no bearing_id. It does not explicitly state when NOT to use it (e.g. when you only need one analysis), so it stops short of full routing guidance.

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
measurementNoNormalized measurement identity declared in the companion's "measurement" object: asset_id, measurement_point_id, acquired_at (ISO 8601 normalized to UTC), timezone_declared, timestamp_suspect, rpm, load, operating_state, sensor_id, direction, declared_by, measurement_id (first 16 hex of the SHA-256 of the file bytes plus the channel index), channel_index, content_sha256 (full digest of the file bytes) and size_bytes (file size). This block is AUTHORITATIVE over the verbatim object kept in source_metadata. None when the companion declares no measurement object (the file behaves exactly as before). The value RETURNED BY load_signal carries, in addition, the outcome of the asset-ledger registration: ledger_status ('recorded' | 'already_recorded' | 'superseded' | 'not_recorded'), reason (None, or why the status or the snapshot is not nominal), changed (keys that differ from the previous declaration of the same measurement, 'location' when the file moved), reattributed_from (asset the measurement was recorded under by mistake, or None), declaration_version, snapshot_status ('complete' | 'partial' | 'failed' | 'skipped'), snapshot_id, processing_id (the snapshot lineage), comparability ({grade, qualifications} against the current declaration of the measurement point, informational, never stored) and missing ({block: {reason, remedy}} of the snapshot blocks the declared context could not support). get_signal_info and list_signals show the identity only.
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.
companion_warningNoSet when a companion _metadata.json exists but could not be used (not valid JSON, or not a JSON object): names the file and the case, and the signal was loaded exactly as if it had no companion. None when the companion was read fine or is absent.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the write path (data/signals/ with timestamped filename), a companion _metadata.json declaring sampling_rate and unit 'g', auto-registration in the repository, and the exact signal content per fault type. It omits permissions, overwrite behavior, and error handling, but overall transparency is strong.

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?

Front-loaded with the core purpose and side effects, followed by signal content and a conventional Args/Returns block; every section earns its place. There is minor redundancy between 'no manual steps' and 'auto-loaded... immediately usable,' but the structure is clean.

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?

For a 5-parameter mutation tool with no annotations, the description covers purpose, persistence side effects, fault-type content, and all parameters. An output schema exists, so the brief Returns section is sufficient; only permission and failure-mode details are absent.

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%, and 5 params are undocumented in the schema, so the description must compensate — and it does, documenting all of them via an Args block: signal_type purpose, duration with a resolution hint (10 s = 0.1 Hz), sampling_rate, noise_level, and random_seed (None = non-deterministic).

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?

States a specific verb and resource ('Generate a synthetic test signal') plus its full lifecycle ('save it, and load it into the repository'). This clearly distinguishes it from siblings like load_signal or list_signals, which operate on existing data.

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 establishes clear context: this produces synthetic fault patterns and the returned signal_id is 'immediately usable by every analysis, diagnosis, and ISO severity tool.' However, it never explicitly states when to prefer this over load_signal (e.g., when no real measurement data exists), so there are no named alternatives or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_asset_historyA

Read the asset ledger: the index of the assets, or one asset's history.

Without asset_id (the index): every asset the ledger directory lists,
at most 50, each with its points (measurement counts, first and last
acquired_at, latest processing lineage, whether a baseline is
declared, declaration version), event count, ledger size and
integrity counters; truncated says whether more assets exist. With
asset_id: that asset's history read from its ledger alone, the last
max_measurements measurements newest first (identity, acquired_at,
signal_id, file location, declaration version, lineages, a preview of
the indicators of the latest snapshot, comparability grade and codes
against the point), the point declarations and baselines with their
history, the measurements re-attributed to another asset, and the
integrity block. measurement_point_id restricts the history to one
point and needs asset_id. An unknown asset or point is a typed
'not_found' naming the known ids, not an exception.

Args:
    ctx: MCP context. Unused, see this module's docstring on logging.
    asset_id: The asset (ledger id), or None for the index.
    measurement_point_id: Restrict to one point of the asset, or None.
    max_measurements: Measurements listed at most (1 to 200), newest
        first.

Returns:
    AssetHistoryResult with status 'index', 'found' or 'not_found'.

Raises:
    ValueError: measurement_point_id without asset_id, an invalid id,
        max_measurements outside 1..200, or a ledger that cannot be
        read.
ParametersJSON Schema
NameRequiredDescriptionDefault
asset_idNo
max_measurementsNo
measurement_point_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
assetNoHistory of the asset (status 'found' only): summary, measurements newest first (measurement_id, measurement_point_id, acquired_at, signal_id, location, declaration_version, rpm, direction, sensor_id, lineages, snapshot_count, indicators preview from the latest snapshot, comparability grade and codes against the point), measurement_count, truncated, point_declarations and baselines (current plus history per point), reattributed, integrity, event_count, ledger_bytes
assetsYesIndex entries (status 'index' only, else empty): asset_id, points (measurement_point_id, measurement_count, first_acquired_at, last_acquired_at, latest_lineage, baseline_declared, declaration_version), point_count, measurement_count, first_acquired_at, last_acquired_at, reattributed_count, event_count, ledger_bytes, integrity (counters)
statusYes'index', 'found' or 'not_found' (see the class description)
messageYesOne-paragraph summary of the outcome
truncatedYesTrue when the index holds fewer assets than exist, or the history fewer measurements than max_measurements would have to cover
suggestionNoConcrete next step on a miss; None otherwise
known_assetsYesAsset ids the ledger directory lists (the listed ones for the index, every id for a miss; empty for a found asset, whose ledger is the only one read)
known_pointsYesPoints of the asset (declared or named by its measurements) when the asset is known; empty otherwise

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full load and does much of it: it describes truncation at 50 assets, the integrity block, typed not_found behavior instead of exceptions, and ValueError conditions. It stops short of stating auth/permission requirements or read-only enforcement, but the error and truncation behavior are valuable and non-obvious.

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 two-mode structure is front-loaded and the Args/Returns/Raises sections are easy to scan. The prose is dense and some sentences pack multiple clauses, which slightly hurts readability but nothing is wasted.

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 a 3-parameter tool with no annotations, an output schema that only declares status values, and a 0% schema description coverage, the description supplies the missing parameter semantics, mode selection, and error behavior. It is complete enough to invoke correctly, though it could note prerequisites such as whether the ledger must already exist.

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 coverage is 0%, so the description must compensate, and it does: asset_id is described as the ledger id or None for index, max_measurements is bounded 1–200 newest first, and measurement_point_id is a point restriction requiring asset_id. Defaults (e.g., max_measurements default 20) are not repeated, but the operational meaning of each parameter is conveyed.

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 names a specific verb (Read) and resource (the asset ledger) and then bifurcates into the two distinct modes: index (all assets) and per-asset history. The reader knows exactly what the tool returns in either mode without opening the schema.

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 clearly states the condition for each mode (without asset_id = index; with asset_id = history) and the constraint that measurement_point_id needs asset_id. It does not explicitly name alternative tools like get_signal_info, but for this tool the mode selection is the dominant decision and that is well documented.

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
measurementNoNormalized measurement identity declared in the companion's "measurement" object: asset_id, measurement_point_id, acquired_at (ISO 8601 normalized to UTC), timezone_declared, timestamp_suspect, rpm, load, operating_state, sensor_id, direction, declared_by, measurement_id (first 16 hex of the SHA-256 of the file bytes plus the channel index), channel_index, content_sha256 (full digest of the file bytes) and size_bytes (file size). This block is AUTHORITATIVE over the verbatim object kept in source_metadata. None when the companion declares no measurement object (the file behaves exactly as before). The value RETURNED BY load_signal carries, in addition, the outcome of the asset-ledger registration: ledger_status ('recorded' | 'already_recorded' | 'superseded' | 'not_recorded'), reason (None, or why the status or the snapshot is not nominal), changed (keys that differ from the previous declaration of the same measurement, 'location' when the file moved), reattributed_from (asset the measurement was recorded under by mistake, or None), declaration_version, snapshot_status ('complete' | 'partial' | 'failed' | 'skipped'), snapshot_id, processing_id (the snapshot lineage), comparability ({grade, qualifications} against the current declaration of the measurement point, informational, never stored) and missing ({block: {reason, remedy}} of the snapshot blocks the declared context could not support). get_signal_info and list_signals show the identity only.
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.
companion_warningNoSet when a companion _metadata.json exists but could not be used (not valid JSON, or not a JSON object): names the file and the case, and the signal was loaded exactly as if it had no companion. None when the companion was read fine or is absent.

TDQS

A4.3/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 and mostly succeeds: it discloses that the full array is NOT loaded, that source_metadata comes from the companion _metadata.json (empty dict when absent), and that ValueError is raised for an unknown signal_id. It omits nothing critical for a local read-only repository call, though it never explicitly says the operation is read-only/non-mutating.

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 two lead paragraphs are front-loaded and earn their place, but the docstring-style Args/Returns/Raises block partially duplicates what the schema and output schema already provide, and the ctx note ('Unused — see this module's docstring on logging') is noise for an agent.

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?

Covers the precondition, the return payload, and the error case, which is enough for an agent to call it correctly. Because an output schema exists, the Returns paragraph is partly redundant, and there is no mention of behavior when the companion metadata file is malformed.

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 coverage is 0% (the single signal_id property is a bare string), so the description must compensate, and it does by defining signal_id as an ID of a signal previously loaded via load_signal. That added constraint is meaningful, though no format or error-adjacent detail beyond existence is given.

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?

States a specific verb (Get), resource (metadata for a stored signal), and scope qualifier (without loading the full array), which implicitly contrasts with the sibling load_signal that retrieves the array itself. An agent can tell what this returns without opening the schema.

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?

Gives a clear precondition: the signal_id must be 'a signal previously loaded via load_signal', and the opening line frames the use case (metadata only, not the full array). It stops short of naming load_signal or list_signals as explicit alternatives or stating when not to use it.

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.

Asset ledger: a file whose companion declares a "measurement" object
(asset_id, measurement_point_id, acquired_at, ...) is also RECORDED in
the local append-only asset ledger after the load, and its health
snapshot is derived and appended; the returned measurement block
carries the outcome (ledger_status, snapshot_status, changed keys of a
corrected declaration, comparability against the declared point,
missing snapshot blocks with their remedy). A ledger problem never
fails the load: it is reported as ledger_status 'not_recorded' with
the reason, and re-loading the file is a safe retry. Re-loading the
same file with the same declaration appends nothing
('already_recorded'); a corrected companion supersedes the previous
declaration ('superseded') and the history keeps both.

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; loads with an asset identity carry
    the ledger outcome in the measurement block (see StoredSignalInfo).

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.7/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 does so richly: batch is fail-fast and atomic with one combined error, id collision is an explicit error unless overwrite, unit declaration discipline for ISO verdicts, raw decode contract requirements, and that ledger problems never fail the load (reported as ledger_status 'not_recorded', safe retry). These are exactly the behavioral traits an agent needs.

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?

Long but organized into clearly labeled blocks (batch, id default, unit discipline, raw files, asset ledger) and front-loaded with the core purpose. It is dense and nearly every sentence adds operative detail, though the sheer volume slightly exceeds what a minimal call needs.

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 complex 11-parameter ingest tool with no annotations and a documented return (StoredSignalInfo) plus Raises, the description covers inputs, defaults, error conditions, and side effects (ledger/snapshot). Nothing an agent needs to call it correctly is missing.

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, and the Args section documents every one of the 11 parameters with defaults, allowed values (e.g. 'g'/'m/s2'/'mm/s'/'m/s', endianness, sample formats) and interaction rules (parameter overrides metadata, raw params broadcast in batch). This fully compensates for the empty 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?

States a specific verb+resource ('Load one signal — or a batch — into the in-memory repository') and explicitly frames its role as the entry point of the load -> analyze -> diagnose -> report flow, distinguishing it from sibling analysis/report tools. An agent immediately knows this is the ingest step.

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 for single vs batch use (batch for training sets) and how downstream tools consume signal_id. It explains the signal_id handle and when overwrite is needed, but does not name alternative ingestion paths (e.g. generate_test_signal) or state when-not-to-use, so it stops short of full routing guidance.

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.

  1. 38 tool updatesv0.13.0
    • First observedanalyze_envelope
    • First observedanalyze_fft
    • First observedanalyze_signal_trend
    • First observedanalyze_statistics
    • First observedassess_asset_change
    • First observedassess_severity
    • First observedcalculate_bearing_characteristic_frequencies
    • First observedcheck_bearing_faults
    • First observedclear_signals
    • First observedcompute_power_spectral_density
    • First observedcompute_spectrogram_stft
    • First observeddeclare_healthy_baseline
    • First observeddeclare_measurement_point
    • First observeddiagnose_vibration
    • First observedestimate_rul
    • First observedextract_features_from_signal
    • First observedextract_manual_specs
    • First observedgenerate_diagnostic_report
    • 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_asset_history
    • First observedget_signal_info
    • First observedlist_html_reports
    • First observedlist_machine_manuals
    • First observedlist_signals
    • First observedload_signal
    • First observedplot_signal
    • First observedpredict_anomalies
    • First observedread_manual_excerpt
    • First observedsearch_bearing_catalog
    • First observedsearch_documentation
    • First observedtrain_anomaly_model

TDQS

A4.3/5.0

Scored across 38 tools

Disambiguation4/5

Most tools have clearly distinct purposes and the descriptions repeatedly mark 'THE unified' tool to prevent overlap (analyze_envelope, assess_severity, analyze_signal_trend, check_bearing_faults). A few pairs remain confusable: analyze_statistics vs extract_features_from_signal (both time-domain feature extraction), analyze_fft vs compute_power_spectral_density, and the large cluster of generate_*_report tools plus plot_signal where selection depends on output artifact rather than action.

Naming Consistency5/5

Consistent snake_case verb_noun pattern throughout (load_signal, analyze_fft, generate_envelope_report, declare_measurement_point, assess_asset_change). Verbs are varied but semantically appropriate and prefix-grouped by sub-domain, with no mixed conventions. The only minor deviation is the generate_diagnostic_report vs generate_diagnostic_report_docx suffix pair, which is still readable.

Tool Count2/5

38 tools is well above the heavy threshold for a single server, spanning seven-plus sub-domains (signal IO, spectral/statistical analysis, ML anomaly detection, manuals/catalog, ledger/baselines, prognosis, reporting). Several report generators (fft/envelope/iso/pca/feature-comparison/diagnostic/docx) plausibly consolidate, making the surface larger than the core scope requires.

Completeness5/5

Coverage is unusually complete: signal load/list/clear, statistical and spectral analysis, bearing fault detection, ISO severity, ML training/prediction, RUL and trend prognostics, manual/catalog search, an append-only asset ledger with baseline declarations and change assessment, plus multi-format reporting. Lifecycle and CRUD operations across the domain are well represented with no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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
    26 PyPI
    9
    MIT
  • A
    license
    Not graded
    quality
    D
    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
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides AI assistants with local Wi-Fi diagnostics including connection history analysis, live signal sampling, and connectivity diagnosis. It returns findings and verdicts rather than raw data, and runs on Windows, Linux, and macOS without sending data off the machine.
    46 npm
    1
    MIT