MCP server for the Bosch eBike Flow API with OAuth, local cache, and battery trend analysis.
Strong naming conventions (all tools start with action verbs: bosch_get_*, bosch_battery_*). Descriptions are detailed and contextual (avg ~250 chars, well above 194-char baseline), explaining WHAT, WHEN, and prerequisites. All 11 tools have input schemas with type definitions and parameter descriptions. However, output schemas are not explicitly documented in the visible code, responses are formatted via format_response() helper but the structure is not declared in tool definitions. Error handling is present but minimal (e.g., _FORBIDDEN_HINT for auth failures). No tool annotations (readOnlyHint, destructiveHint) despite all tools being READ_ONLY. Parameter descriptions are strong but some lack explicit constraints (e.g., date formats are described as 'YYYY-MM-DD, YYYY-MM, or Nd' but not formalized as regex/enum).
Analyse battery health trends for your Bosch eBike over time. Computes per-period averages and deltas for: - Charge cycle count (total, rate of accumulation) - Average battery level at time of sync - Lifetime energy delivered (total kWh ever pushed through the battery) - Remaining energy trend (indicates capacity degradation over time) A declining remaining_energy_wh at a constant charge level indicates the battery capacity is degrading. Compare early and recent snapshots for a long-term health picture.
List e-bike rides with per-ride summary metrics. Live read from the Bosch rider-activity API (no cache). Each ride includes distance, elevation gain/loss, avg/max speed, cadence, measured rider power, calories, rider-vs-motor energy share, assist-mode distance split (metres per mode), CO2 (emissions / car-equivalent / saved), and ABS/brake events. Heart rate is not recorded by the bike (it has no HR sensor) - pair with a wrist device for HR.
Get the per-point track for one ride (GPS + speed/elevation/cadence/power). Live read. Returns a downsampled track (~500 points per ride): per-point cumulative distance (m), speed (km/h), elevation (m), cadence, rider power (W), and GPS lat/lon. Get the activity_id from bosch_get_activities.
Get battery state and health for your Bosch eBike. Returns charge level, remaining energy, total capacity, charge cycles (total / on-bike / off-bike), lifetime energy delivered, and software version. Each sync captures a snapshot, building a time series of battery health. Use latest_only=False with a date range to see history.
Output schemas not documented. Tool definitions lack explicit return type declarations. Responses are formatted via format_response() helper but the structure is not visible in tool registration. LLMs cannot plan downstream calls or extract fields without knowing what fields are returned.
No tool annotations despite all tools being READ_ONLY. MCP spec supports readOnlyHint, destructiveHint, and idempotentHint annotations. All 11 tools should declare readOnlyHint=true to signal safety to agents.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | <=2025-11-25 | v2 |
Get detailed profile for a single Bosch eBike. Returns full bike details including brand, model, frame number, and the cached raw API response which may include component info.
List all Bosch eBikes registered to your Flow account. Returns bike names, brand, and frame numbers. Uses local cache (auto-syncs if stale). Run bosch_sync first if the list is empty. Returns a list of bikes with id, name, brand_name, and frame_number.
Get battery capacity tester diagnostic results. Shows battery health data from Bosch's official capacity tester tool, typically done at dealer service appointments. Includes remaining capacity percentage vs. original specification. Capacity-tester data comes only from the EU Data Act API; with a standard Bosch eBike Flow sign-in this is empty and the result explains why.
List registered components for your Bosch eBike with software versions. Shows the bike's components - drive unit, battery, ConnectModule, head unit, remote control, ABS - with part numbers, serial numbers, and firmware versions. The source depends on your sign-in: a standard Bosch eBike Flow account reads them from the bike profile (mobile app API); an EU Data Act (euda) client reads them from the Data Act registrations endpoint. Useful for tracking firmware versions and identifying components for warranty or service purposes.
Get the digital service book history for your Bosch eBike. Returns all service records logged by Bosch dealers and service centres, including dates and descriptions of work performed. Service records come only from the EU Data Act API; with a standard Bosch eBike Flow sign-in this is empty and the result explains why (register a euda client).
Get live state-of-charge from the Bosch ConnectModule. Returns real-time battery percentage, charging status, remaining energy, and reachable range per assist mode (eco/tour/sport/turbo). Requires a ConnectModule on the bike. Data is only available when the bike is powered on, charging, or recently active. Note: This calls the Bosch mobile API live - no caching.
Get software update installation history for your Bosch eBike. Returns all firmware/software update reports, showing which components were updated, from which version to which version, and when. This history comes only from the EU Data Act API; with a standard Bosch eBike Flow sign-in it is empty (current firmware is still available via components).
Date parameter formats described informally ('YYYY-MM-DD, YYYY-MM, or Nd') but not formalized as regex patterns or enums in schema. LLMs may pass invalid formats like '2024-1-5' or '30days'. Add explicit pattern constraints to schema.
Error handling minimal. Auth failures return _FORBIDDEN_HINT string but no structured error response. No guidance on recovery (e.g., 'Register a euda client' is mentioned in descriptions but not in error responses). Errors should categorize as retryable/user-fixable/fatal.
No pagination support visible in tool definitions. bosch_get_activities mentions 'limit' parameter but no offset/page/cursor. Large result sets (e.g., 500+ rides) could exhaust context window. Implement pagination with limit + offset/cursor and total count.