← Back to Documentation

MCP Integration Guide

PF-SUMP-001  |  v1.2  |  Updated: 2026-02-27  |  Transport: HTTP JSON-RPC

MCP (Model Context Protocol) allows AI assistants to directly interact with the device — reading status, changing configuration, and triggering actions through natural language.


Setup

Endpoint

POST http://<device-ip>/api/v1/mcp
Content-Type: application/json

Standard JSON-RPC 2.0 over HTTP. No authentication. LAN-only.

Compatible clients

VS Code Configuration

Add to .vscode/mcp.json:

{
  "servers": {
    "sump-pump": {
      "type": "http",
      "url": "http://<device-ip>/api/v1/mcp"
    }
  }
}

Response format

All tool responses are returned as MCP content:

{
  "content": [
    {
      "type": "text",
      "text": "<JSON string>"
    }
  ]
}

Examples below show the parsed inner JSON for clarity.


get_pump_status

Returns the current pump state, active alerts, protection mode, lockout info, learning progress, and cumulative stats. Same payload as REST GET /sump/status and MQTT sump/state.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_pump_status",
    "arguments": {}
  }
}

Response (30 fields)

{
  "pump_running": false,
  "current_run_s": 0,
  "current_power_w": 0.0,
  "alerts": [],
  "protection_mode": "active",
  "protection_auto_disabled": false,
  "lockout_active": false,
  "lockout_remaining_s": 0,
  "lockout_retries_used": 0,
  "lockout_alert": null,
  "run_count_total": 87,
  "runs_last_24h": 7,
  "total_runtime_s": 2958,
  "last_outage_s": 0,
  "last_run_end_ms": 1708300000000,
  "last_run_dur_s": 34,
  "last_run_avg_w": 762.4,
  "last_run_peak_w": 812.0,
  "idle_w": 0.0,
  "active_w": 780.0,
  "on_threshold_w": 234.0,
  "inter_run_gap_mean": 21600.0,
  "alert_enable_mask": 7,
  "relay_cut_mask": 1,
  "inactivity_alert_min": 7200,
  "anomaly_lockout_min": 10,
  "lockout_max_retries": 3,
  "rhythm_hex": "000000010001000200010000...",
  "rhythm_head": 142,
  "rhythm_last_bin_ms": 1708300200000
}

See REST API Reference — GET /sump/status for the complete field table.

💬 "Is my sump pump working?"  |  "What's the current state of my sump pump?"  |  "Are there any pump alerts?"

get_pump_history

Returns the alert event ring buffer — up to 64 most recent events, ordered oldest first.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_pump_history",
    "arguments": {}
  }
}

Response

[
  {
    "event": "alert_fired",
    "alert": "power_anomaly_low",
    "timestamp_ms": 1738886400000,
    "run_dur_s": 12,
    "power_w": 520.0,
    "relay_cut": true
  },
  {
    "event": "alert_cleared",
    "alert": "power_anomaly_low",
    "timestamp_ms": 1738886420000,
    "duration_s": 20
  },
  {
    "event": "device_boot",
    "timestamp_ms": 1739318400000,
    "reason": "power_on"
  }
]

See REST API Reference — GET /sump/history for the full event type table.

Normal pump runs do NOT appear in this ring. Only alerts, problems, and lifecycle events. Ring holds max 64 events.

💬 "Show me the recent pump alert history"  |  "Have there been any power outages?"

get_last_run

Returns detailed stats and power waveform for the last completed pump cycle.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_last_run",
    "arguments": {}
  }
}

Response

{
  "start_ms": 1708299965000,
  "end_ms": 1708300000000,
  "dur_s": 34,
  "avg_w": 762.4,
  "peak_w": 812.0,
  "std_w": 18.7,
  "sample_count": 34,
  "samples": [210.5, 810.2, 795.0, 780.1, 770.3, 762.8]
}

See REST API Reference — GET /sump/last-run for the full field table.

💬 "Show me the last pump run details"  |  "What did the power look like during the last cycle?"

get_sump_config

Read all current configuration parameters.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_sump_config",
    "arguments": {}
  }
}

Response

{
  "inactivity_alert_min": 7200,
  "anomaly_lockout_min": 10,
  "lockout_max_retries": 3,
  "alert_enable_mask": 7,
  "relay_cut_mask": 1
}

See REST API Reference — GET /sump/config for field details and ranges.

💬 "What are the sump pump settings?"  |  "Is dry run protection enabled?"

set_sump_config

Update one or more configuration parameters. Only fields present in arguments are changed. Persisted to NVS immediately.

Input schema

FieldTypeRangeDescription
inactivity_alert_mininteger1–43200Minutes without cycle before Expected Run alert
anomaly_lockout_mininteger1–480Minutes relay stays open after anomaly
lockout_max_retriesinteger1–10Max auto-release attempts
alert_enable_maskinteger0–31Bitmap of enabled alerts
relay_cut_maskinteger0–7Bitmap of alerts that cut relay

No fields are required — pass only what you want to change.

Example requests

// Enable all alerts
{ "name": "set_sump_config", "arguments": { "alert_enable_mask": 31 } }

// Enable high-power relay cut
{ "name": "set_sump_config", "arguments": { "relay_cut_mask": 3 } }

// Change lockout settings
{ "name": "set_sump_config", "arguments": {
    "anomaly_lockout_min": 15,
    "lockout_max_retries": 5
}}

Response (success)

{
  "changes_applied": 2,
  "config": {
    "inactivity_alert_min": 7200,
    "anomaly_lockout_min": 15,
    "lockout_max_retries": 5,
    "alert_enable_mask": 7,
    "relay_cut_mask": 1
  }
}
💬 "Enable blockage detection and cut power"  |  "Change the inactivity alert to 3 days"  |  "Set the lockout time to 15 minutes"

reset_lockout

Clear any active lockout, re-enable any auto-disabled protection flags, and reset the retry counter.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "reset_lockout",
    "arguments": {}
  }
}

Response

{ "status": "lockout_reset" }

Relay closes immediately. Retry counter zeroed. Safe to call even if no lockout is active.

💬 "Reset the sump pump lockout"  |  "Re-enable pump protection"

reset_stats

Reset all cumulative statistics, clear alert history, clear rhythm ring, and reset all learned baselines. Device re-enters learning mode.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "reset_stats",
    "arguments": {}
  }
}

Response

{ "status": "stats_reset" }

Device needs ~5+ cycles to rebuild baselines after reset.

💬 "Reset the pump statistics and start learning fresh"  |  "Clear all sump pump data"

get_learn_status

Returns detailed learning / baseline convergence data: Welford CV values, per-metric readiness flags, inter-run gap stats, and bimodal power baselines.

Input

None.

JSON-RPC request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_learn_status",
    "arguments": {}
  }
}

Response

{
  "mode": "learning",
  "cycle_count": 9,
  "wattage_mean": 762.4,
  "wattage_cv": 8.2,
  "wattage_ready": true,
  "runtime_mean": 34.0,
  "runtime_cv": 46.1,
  "runtime_ready": false,
  "cycle_rate_mean": 7.2,
  "cycle_rate_cv": 45.0,
  "cycle_rate_ready": false,
  "inter_run_gap_mean": 420.0,
  "inter_run_gap_cv": 32.5,
  "inter_run_gap_ready": true,
  "idle_w": 0.0,
  "active_w": 780.0
}

See REST API Reference — GET /sump/learn for the full field table and readiness thresholds.

Transitions learningactive when both wattage_ready and runtime_ready are true and ≥ 5 cycles recorded.

💬 "How close is the pump to finishing learning?"  |  "Why is the sump pump still in learning mode?"  |  "Show me the pump's CV values"

Common Notes