Skip to main content
Glama
mosandlt

Bosch Smart Home Camera MCP Server

by mosandlt

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

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

Tools

Functions exposed to the LLM to take actions

NameDescription
bosch_camera_listA

List all configured Bosch cameras with their online status.

bosch_camera_statusB

Get the current status of one camera by name (case-insensitive).

bosch_camera_snapshotB

Capture a fresh snapshot via LAN only (HTTP Digest to camera IP). No Bosch cloud roundtrip.

Requires the MCP host to be on the same network as the camera. Saves to ~/.cache/bosch-camera-mcp/snapshots//.jpg.

bosch_camera_stream_urlA

Get the LAN RTSPS stream URL for one camera. No Bosch cloud relay.

The returned URL is consumable by ffmpeg/VLC/go2rtc. Requires that the MCP host runs on the same network as the camera and has local credentials configured for the camera (bosch_config.json → cameras[name].local_*).

bosch_camera_eventsB

Return the most recent motion / person / audio events for one camera.

Each item contains: event_id, type, timestamp_iso, has_clip.

bosch_camera_lan_pingA

Probe whether a camera is reachable on the LAN (TCP port 443, 1.5 s timeout).

Pass either camera (resolved against bosch_config.json) or a raw lan_ip. Useful when diagnosing cloud-down situations: if this returns reachable=true while the cloud API is returning 5xx, privacy/light writes via prefer_local=True will work without waiting for Bosch infrastructure.

Returns {reachable, ip, latency_ms}.

bosch_camera_privacy_setA

Turn privacy mode on or off. enabled=True hides the camera.

When prefer_local=True, attempt the RCP-LAN write path FIRST (skipping the Bosch cloud entirely). Useful when the agent already knows the cloud is down but the camera is LAN-reachable (confirmed via bosch_camera_lan_ping). Falls back to the cloud API automatically if the LAN write fails or if no local_ip is configured.

bosch_camera_light_setA

Turn the camera's spotlight on or off.

Only for cameras with featureSupport.light=true (currently: Eyes Outdoor II / HOME_Eyes_Outdoor). Raises hardware_unsupported immediately for cameras without a controllable light — no Bosch cloud call is made.

When prefer_local=True, attempt the RCP-LAN write path FIRST (skipping the Bosch cloud entirely). Maps enabled=True to brightness 100, False to 0. Falls back to the cloud API automatically if the LAN write fails or if no local_ip is configured. Wallwasher RGB is always cloud-only.

bosch_camera_panA

Pan the 360° indoor camera (Gen1 CAMERA_360 only, panLimit > 0).

Named presets (preferred, via preset parameter): home → 0° (center) left → -60° right → +60° back-left → -120° (full left limit) back-right → +120° (full right limit)

direction accepts the same preset names, legacy aliases (center), or an integer string in the range -panLimit to +panLimit.

When preset is set it takes priority over direction.

bosch_camera_siren_triggerA

Trigger (or stop) the indoor siren on a camera.

Endpoint depends on the camera model:

  • Gen1 360° indoor (model == "INDOOR") → PUT /v11/video_inputs/{id}/acoustic_alarm Body: {"enabled": <bool>}. Outdoor cameras return HTTP 442 (not supported).

  • Gen2 Indoor II (model == "HOME_Eyes_Indoor") → PUT /v11/video_inputs/{id}/panic_alarm Body: {"status": "ON"|"OFF"}. 75 dB integrated siren.

The siren plays for the camera-side configured duration (typically 30–60 s on Gen2). To change the duration, use bosch_camera_siren_duration_set (range 10–300 s) before triggering.

Raises hardware_unsupported for outdoor cameras and Gen1 outdoor models. Raises privacy_blocked when the camera is in privacy mode (Gen2 panic alarm is gated by privacyMode at the Bosch cloud level).

Args: camera: Camera name (case-insensitive). stop: If True, send the stop variant ({"enabled": False} or {"status": "OFF"}). Useful for cancelling an active Gen2 panic alarm before its duration expires.

bosch_camera_siren_duration_setA

Set the siren alarm duration for one camera (Gen2 Indoor II only).

Read-modify-write on GET/PUT /v11/video_inputs/{id}/alarm_settings (field alarmDelayInSeconds) — existing fields in that config are preserved. Does not trigger the siren itself; call bosch_camera_siren_trigger afterwards to fire it with the new duration.

Raises hardware_unsupported for non-Gen2-Indoor-II cameras (matches bosch_camera_siren_trigger's own gating). Raises invalid_argument if seconds is outside 10-300. Raises privacy_blocked when the camera is in privacy mode.

Args: camera: Camera name (case-insensitive). seconds: New siren duration, 10-300 seconds inclusive.

bosch_camera_lighting_schedule_getA

Get the LED lighting schedule for one outdoor (Eyes) camera.

API: GET /v11/video_inputs/{id}/lighting_options. Only available on outdoor cameras with LED light — raises hardware_unsupported (HTTP 442) on cameras without this feature, and api_unreachable (HTTP 444) if the camera is offline.

bosch_camera_lighting_schedule_setA

Update the LED lighting schedule for one outdoor (Eyes) camera.

Read-modify-write on GET/PUT /v11/video_inputs/{id}/lighting_options. At least one of on_time/off_time/light_on_motion/ darkness_threshold must be provided. Writing any field forces scheduleStatus to FOLLOW_SCHEDULE (matches CLI behavior).

Only available on outdoor cameras with LED light — raises hardware_unsupported (HTTP 442) otherwise, api_unreachable (HTTP 444) if the camera is offline.

Args: camera: Camera name (case-insensitive). on_time: Light-on time, "HH:MM" or "HH:MM:SS". off_time: Light-off time, "HH:MM" or "HH:MM:SS". light_on_motion: Whether motion also triggers the light. darkness_threshold: Ambient-darkness trigger threshold, 0.0-1.0.

bosch_camera_intercom_openA

Open a listen-audio session tunnel to a camera (cloud proxy).

Listen-only — returns an RTSPS URL streaming the camera's microphone audio to the caller. True two-way talk (caller mic -> camera speaker) is not exposed via the Bosch cloud API (same limitation as the Python CLI's own intercom command — it falls back to ffplay for listen-only playback). The returned URL is consumable by ffmpeg/ffplay/VLC; the MCP server does not itself play audio.

Flow: optionally sets the camera's speaker level (full-body PUT to /audio, preserving other fields), then opens a live connection via PUT /v11/video_inputs/{id}/connection (tries REMOTE then LOCAL) and builds an rtsps:// URL with enableaudio=1.

Args: camera: Camera name (case-insensitive). duration: Requested session duration in seconds (embedded in the URL as maxSessionDuration), default 60. speaker_level: Optional 0-100 speaker level to set before opening the session.

bosch_camera_notifications_setC

Toggle push notifications for one camera.

bosch_camera_maintenance_statusA

Fetch the current Bosch Smart Home cloud maintenance announcement from the official community RSS feed.

Returns title, time window, link, state (active/scheduled/past/recent/unknown/idle), and a recommended_action hint for the calling agent:

  • "check_lan" — state is "active" (outage/maintenance in progress): run bosch_camera_lan_ping to check per-camera LAN reachability, then use prefer_local=True on privacy/light writes while the cloud is down.

  • "wait" — state is "scheduled": outage is upcoming; no action needed yet.

  • null — state is past/recent/unknown/idle: normal operation expected.

Use this tool when users ask why cameras are unavailable or when the cloud returns 5xx errors.

bosch_camera_audio_getA

Get the microphone and speaker level settings for one Gen2 camera.

Only for cameras with featureSupport.sound=true (Gen2 Indoor II and Gen2 Outdoor II). Raises hardware_unsupported immediately for Gen1 cameras or Gen2 cameras without audio hardware.

Returns {microphone_level, speaker_level, intercom_enabled}. intercom_enabled is None for cameras without a two-way intercom (e.g. Outdoor II).

bosch_camera_audio_setA

Set the microphone level and/or speaker level for one Gen2 camera.

Only for cameras with featureSupport.sound=true (Gen2 Indoor II and Gen2 Outdoor II). Raises hardware_unsupported for cameras without audio hardware. At least one of mic_level or speaker_level must be provided.

Both values must be in the range 0-100. The API persists the full audio payload — unspecified fields are preserved from the current camera state.

Returns updated {microphone_level, speaker_level, intercom_enabled} after write.

bosch_camera_intrusion_getA

Get the intrusion detection configuration for one Gen2 camera.

Returns {mode, sensitivity, distance}. Only available on Gen2 cameras (has_sound=true in config is reused as the Gen2 gate; intrusion detection is a Gen2-only feature). Raises hardware_unsupported for Gen1 cameras.

mode: PERSON | STANDARD | HIGH_SENSITIVITY | ZONES | ALL_MOTIONS | ONLY_HUMANS (maps to Bosch API field detectionMode). sensitivity: 0 (low) to 7 (high) — confirmed range FW 9.40+. distance: detection range in meters, 1-8 (Bosch API limit).

bosch_camera_intrusion_setA

Update the intrusion detection configuration for one Gen2 camera.

Gen2-only feature — raises hardware_unsupported for Gen1 cameras. At least one parameter must be provided.

mode: PERSON | STANDARD | HIGH_SENSITIVITY | ZONES | ALL_MOTIONS | ONLY_HUMANS (maps to Bosch API field detectionMode). v1.6.0 incorrectly documented OFF|ACTIVE|SCHEDULED and silently sent mode instead of detectionMode — Bosch's API accepted the request but dropped the field. Fixed in v1.6.1. sensitivity: 0-7 (0 = low, 7 = high; FW 9.40+ confirmed range). distance: detection range in meters, 1-8 (Bosch API rejects 9+ with HTTP 400 "must be less than or equal to 8" — verified 2026-05-28 FW 9.40.102).

Unspecified fields are preserved from the current camera configuration. Returns the updated {mode, sensitivity, distance} after write.

bosch_camera_audio_detection_getA

Get the glass-break + smoke/fire-alarm sound detection config for one Gen2 camera.

Only available on Gen2 Audio-Plus cameras (featureSupport.sound=true). Raises hardware_unsupported for Gen1 cameras. Ported from HA integration v14.2.0 (BoschGlassBreakDetectionSwitch / BoschFireAlarmDetectionSwitch).

Returns {glass_break, fire_alarm} (Bosch API fields detectGlassBreak / detectFireAlarm).

bosch_camera_audio_detection_setA

Update glass-break and/or fire-alarm sound detection for one Gen2 camera.

Gen2 Audio-Plus-only feature — raises hardware_unsupported for Gen1 cameras. At least one of glass_break or fire_alarm must be provided.

Read-modify-write: the current config is fetched first, only the provided field(s) are merged in, and both detectGlassBreak and detectFireAlarm are always sent together on the PUT — Bosch's API silently resets whichever field is omitted (same requirement as intrusionDetectionConfig).

Returns the updated {glass_break, fire_alarm} after write.

bosch_camera_wifiA

Get the WiFi signal quality for one camera.

Queries GET /v11/video_inputs/{id}/wifiinfo and returns {rssi, ssid, signal_strength}.

rssi: raw RSSI in dBm (negative integer, e.g. -67). ssid: the connected WiFi network name. signal_strength: 0-100 % quality derived from RSSI (-50 dBm = 100 %, -100 dBm = 0 %).

Useful for diagnosing intermittent connectivity, stream drops, or deciding whether to force prefer_local=True on privacy/light writes.

bosch_camera_mjpeg_snapshotA

Direct LAN MJPEG snapshot via RTSP inst=3 (Gen2 only). Faster than snap.jpg, no cloud roundtrip.

Uses ffmpeg to pull a single frame from the camera's RTSPS stream (inst=3 = sub-stream, lower resolution but faster). Saves JPEG to ~/.cache/bosch-camera-mcp/snapshots/. Requires ffmpeg installed and MCP host on same LAN as camera. Gen2 only (HOME_Eyes_Outdoor / HOME_Eyes_Indoor).

bosch_camera_onvif_scopesA

Read ONVIF device scopes from camera via LAN RCP command 0x0a98 (Gen2 only).

Returns parsed scope fields: name, hardware model, ONVIF profiles, and the raw scope string. Requires local_ip + local credentials in bosch_config.json. Gen2 only (HOME_Eyes_Outdoor / HOME_Eyes_Indoor).

bosch_camera_rcp_versionA

Read RCP firmware version from camera via LAN (opcodes 0xff00 + 0xff04).

Returns primary and secondary RCP library versions in dotted decimal and raw hex. Useful for diagnosing protocol compatibility. Requires local_ip + local credentials.

bosch_camera_feature_flagsA

Fetch account-level Bosch cloud feature flags from GET /v11/feature_flags.

Returns the raw dict of feature flag names to boolean values, e.g. {"APP_RATING": true, "IOT_THINGS_INTEGRATION": true, ...}. No camera parameter — flags are account-level. Useful for discovering which Bosch platform features are active for this account.

bosch_camera_motion_getA

Get motion detection settings for one camera.

Returns {enabled, sensitivity} where sensitivity is one of: OFF | LOW | MEDIUM_LOW | MEDIUM_HIGH | HIGH | SUPER_HIGH.

API: GET /v11/video_inputs/{id}/motion.

bosch_camera_motion_setA

Set motion detection enabled state and/or sensitivity for one camera.

At least one of enabled or sensitivity must be provided.

sensitivity: OFF | LOW | MEDIUM_LOW | MEDIUM_HIGH | HIGH | SUPER_HIGH. Note: providing only sensitivity also implicitly enables motion detection (mirrors the CLI behavior — setting sensitivity implies you want it active).

API: PUT /v11/video_inputs/{id}/motion.

bosch_camera_recording_getB

Get cloud recording options for one camera.

Returns {sound_on} — whether audio is recorded in cloud clips.

API: GET /v11/video_inputs/{id}/recording_options.

bosch_camera_recording_setB

Enable or disable audio in cloud recordings for one camera.

sound_on=True → record audio in cloud clips. sound_on=False → no audio in cloud clips.

API: PUT /v11/video_inputs/{id}/recording_options Body: {"recordSound": bool}.

bosch_camera_autofollow_getA

Get auto-follow (360° auto-tracking) state for one camera.

Returns {enabled}. Only meaningful for 360° cameras with panLimit > 0 (Gen1 CAMERA_360 indoor). Raises hardware_unsupported for non-360° cameras.

API: GET /v11/video_inputs/{id}/autofollow.

bosch_camera_autofollow_setA

Enable or disable 360° auto-tracking for one camera.

Only available on 360° indoor cameras (panLimit > 0). Raises hardware_unsupported for non-360° cameras.

API: PUT /v11/video_inputs/{id}/autofollow Body: {"result": bool}.

bosch_camera_privacy_sound_getA

Get the privacy-sound indicator setting for one camera.

When enabled, the camera plays an audible indicator when privacy mode changes. Returns {enabled}.

API: GET /v11/video_inputs/{id}/privacy_sound_override.

bosch_camera_privacy_sound_setA

Enable or disable the audible indicator that plays when privacy mode changes.

enabled=True → camera beeps/chimes when privacy is toggled. enabled=False → silent privacy mode switching.

API: PUT /v11/video_inputs/{id}/privacy_sound_override Body: {"result": bool}.

bosch_camera_unread_getA

Get the unread event count for one camera.

Reads numberOfUnreadEvents from the /v11/video_inputs listing (the /unread_events_count endpoint returns HTTP 404 — verified in testing).

Returns {camera, count}.

bosch_camera_health_check_allA

Bulk health check for ALL configured cameras in one call.

Returns status + WiFi signal + privacy mode + last event + unread count for each camera. Replaces 4+ separate MCP calls for dashboard use.

Errors per camera are captured in the error field rather than raising, so a single failing camera does not abort the entire check.

bosch_camera_token_statusA

Return the current bearer token validity, expiry, and account email.

Parses the JWT exp and email/preferred_username claims from the stored bearer token without making a network call.

Returns {valid, expires_in_min, email}. valid=False when the token is expired or missing. expires_in_min is negative when already expired.

bosch_camera_motion_zones_getA

List the motion-detection zone rectangles configured for one camera.

Coordinates are normalized 0.0-1.0 (x/y = top-left corner, w/h = size). Returns an empty list if no zones are configured. Raises privacy_blocked if the camera is currently in privacy mode (Bosch returns HTTP 443 for this endpoint while privacy is on).

bosch_camera_motion_zones_setA

Replace ALL motion-detection zones for one camera with the given list.

This is a full replace, not a merge — pass every zone you want to keep. Each zone is {"x": ..., "y": ..., "w": ..., "h": ...}, normalized 0.0-1.0. Pass an empty list to clear all zones (equivalent to calling bosch_camera_motion_zones_clear).

bosch_camera_motion_zones_clearB

Remove all motion-detection zones for one camera. Returns the (empty) list.

bosch_camera_privacy_masks_getA

List the privacy-mask zone rectangles configured for one camera.

Coordinates are normalized 0.0-1.0 (x/y = top-left corner, w/h = size). Masked areas are permanently blacked out in both live view and recordings.

bosch_camera_privacy_masks_setA

Replace ALL privacy-mask zones for one camera with the given list.

Full replace, not a merge. Each mask is {"x": ..., "y": ..., "w": ..., "h": ...}, normalized 0.0-1.0. Pass an empty list to clear all masks.

bosch_camera_privacy_masks_clearA

Remove all privacy-mask zones for one camera. Returns the (empty) list.

bosch_camera_rules_listB

List the automation (time-schedule) rules configured for one camera.

bosch_camera_rules_addA

Create a new automation rule for one camera.

start/end are HH:MM 24h time. days are 0=Monday..6=Sunday. The new rule is created active. Returns the created rule (with its id).

bosch_camera_rules_editB

Update an existing automation rule for one camera. Only provided fields change.

bosch_camera_rules_deleteA

Delete an automation rule from one camera. Returns {deleted, rule_id}.

bosch_camera_friends_listA

List all friends/invitations this account has shared cameras with.

No camera parameter — friends are account-level, not per-camera.

bosch_camera_friends_inviteB

Invite a new friend (by email) to share cameras with. Account-level.

bosch_camera_friends_shareA

Share one camera with an existing friend.

days limits the share to a time window starting now; omit for an unlimited share. Returns {shared, friend_id, camera}.

bosch_camera_friends_unshareA

Revoke ALL camera shares from a friend (the friend entry itself remains).

Returns {unshared, friend_id}.

bosch_camera_friends_removeA

Remove a friend entirely (revokes shares and deletes the invitation/friendship).

Returns {removed, friend_id}.

bosch_camera_firmware_statusB

Get the current/latest firmware version and update-availability for one camera.

bosch_camera_firmware_installA

Install the pending firmware update for one camera right now.

Mirrors the HA integration's async_install_firmware guard: raises invalid_argument if an install is already in progress, or if there is no pending update to install (already up to date). The camera reboots for roughly 3-7 minutes after the install starts; this call returns as soon as Bosch accepts the request, it does not wait for the reboot to finish.

Prompts

Interactive templates invoked by user choice

NameDescription
daily-camera-summaryWalk through today's events on all cameras and produce a structured daily report: motion count, person count, audio events, time distribution, and anomaly highlights.
pre-leave-checkPre-departure routine: snapshot every camera, describe what is visible, flag anomalies (open windows, unexpected occupants, lights on), and recommend enabling privacy mode on indoor cameras.

Resources

Contextual data attached and managed by the client

NameDescription
cameras-listJSON list of all configured Bosch cameras with status, firmware, and MAC.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mosandlt/Bosch-Smart-Home-Camera-Tool-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server