Skip to main content
Glama
lucksmiler-A1

Predictive Maintenance MCP Server

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
UV_LINK_MODENoEnvironment variable set to "copy" in the example client configuration.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
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).
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').
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.
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.
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.
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.
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.
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.
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
    )
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').
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').
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.
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.
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.
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.
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).
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
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.
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).
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.
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.
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.
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.
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.
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
    )
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.
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}
    ... )
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.
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.
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"}
    ... )
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"]
    ...     }
    ... )
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.
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.
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).
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.
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.
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.
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.

Prompts

Interactive templates invoked by user choice

NameDescription
diagnose_bearing Guided workflow for bearing diagnostics with ISO 20816-3 compliance. Evidence-based policy: - Envelope peaks at characteristic frequencies are PRIMARY indicators (strong evidence) - Statistical indicators (CF>6, Kurtosis>6) are SECONDARY/confirmatory - If envelope shows clear peaks at BPFO/BPFI/BSF/FTF (±5% tolerance) → bearing fault is STRONGLY indicated - Additional high CF or Kurtosis reinforces the diagnosis but is not strictly required if envelope evidence is clear **ISO 20816-3 Defaults** (use if user doesn't specify): - machine_group = 2 (medium-sized machines, 15-300 kW, most common) - support_type = "rigid" (horizontal machines on foundations) Args: signal_id: ID of the stored signal (or the file to load in STEP 0) sampling_rate: Sampling frequency in Hz (if None, will check metadata or ask user) machine_group: ISO machine group (1=large >300kW, 2=medium 15-300kW) (default: 2) support_type: 'rigid' or 'flexible' (default: 'rigid' for horizontal machines) rpm: Operating speed in RPM (required for interpreting results) bpfo: Ball Pass Frequency Outer race (Hz) - if known bpfi: Ball Pass Frequency Inner race (Hz) - if known bsf: Ball Spin Frequency (Hz) - if known ftf: Fundamental Train Frequency (Hz) - if known
diagnose_gear Evidence-based guided workflow for gear diagnostics with strict anti-speculation rules. Args: signal_id: ID of the stored signal (or the file to load in STEP 0) sampling_rate: Sampling frequency in Hz (if None, will check metadata or ask user) num_teeth: Number of gear teeth (REQUIRED for GMF calculation) rpm: Shaft rotation speed in RPM (REQUIRED for GMF and sideband identification)
quick_diagnostic_report Quick, evidence-aware screening report (non-definitive). Args: signal_id: ID of the stored signal (or the file to load in STEP 0)

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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