Skip to main content
Glama
lucksmiler-A1

Predictive Maintenance MCP Server

diagnose_vibration

Detect bearing faults and assess ISO 20816-3 severity from a stored vibration signal using FFT, PSD, and STFT analysis.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
rpmNo
signal_idYes
bearing_idNo
support_typeNo
machine_groupNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
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=...)).

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.13.0

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.