bi-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| BI_HOST | Yes | LAN IP or hostname of your Blue Iris box | |
| BI_PASS | Yes | That user's password | |
| BI_PORT | Yes | Blue Iris web-server port | 81 |
| BI_USER | Yes | The low-privilege user you created | |
| BI_MCP_DEBUG | No | Set to '1' to log to stderr and a rotating file | |
| BI_ADMIN_PASS | No | Admin user's password | |
| BI_ADMIN_USER | No | Optional admin user for admin-gated tools | |
| BI_MCP_REG_DIR | No | Directory containing .reg camera exports | |
| BI_MCP_ALLOW_MUTATIONS | No | Set to '1' to enable the 6 control tools |
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
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| bi_get_actionsetA | Return the semantic action set (OnTrigger and/or OnReset) for a camera. Decodes the full action |
| bi_get_alert_imageA | Fetch the STORED alert image (the frame BI saved when an alert fired) for a camera, resolved by time — not a live frame (that's bi_get_camera_snapshot). Pass 'camera' (short name) and optional 'at' (the alert time: ISO-8601, unix epoch int, or relative like '-2h'); omit 'at' for the most recent alert. Returns the most-recent alert at-or-before 'at' as base64, plus its record/time/memo so you can confirm which alert came back. Optional 'markup' (bool) requests the AI-overlay variant (manual's v=2). Internally resolves via alertlist + the /alerts/@record endpoint. Use a specific camera, not 'Index'. MARKUP — when 'markup'=true draws no box, it's almost always the ALERT'S SOURCE, not a tool bug: a box exists ONLY if CodeProject.AI classified the alert (memo has a score, e.g. |
| bi_list_alertsA | Recent alerts with AI memo (object, confidence, license plate), zones triggered, and clip path. Requires 'camera' short name (or 'Index' for all). First stop for 'what fired when' / reconstructing an alert chain — per-alert timestamps and memos, no dedup. Use this before bi_list_log when investigating a specific event. Optional 'startdate'/'enddate' accept unix epoch int, ISO-8601 ('2026-05-27T14:09:02Z'), or relative shorthand ('-2h', '-1d'). 'view' (filter; see schema for full enum), 'search' (memo substring). 'limit' default 50. Crossover note: if 'view' is set to 'flagged', BI may also return clip items here; those clips lack the 'zones' field and their 'msec' is the clip length, not alert length. |
| bi_get_alert_tracksA | AI object tracks (per-frame bounding boxes) inside one alert. Pass the alert's 'path' from bi_list_alerts. KNOWN BROKEN on BI 5.9.9.71: returns 'Access denied' from both the read-user and admin-user paths. The |
| bi_get_clip_infoA | Forensic detail for one clip/alert: resolution, duration, AI/profile/schedule/zones active at trigger time. Pass clip 'path' from bi_list_alerts. |
| bi_audit_actionsA | Informational tool — surfaces cross-camera action-row outliers for user review. Walks every camera's .reg export, buckets action rows into cohorts by (type, description, type-specific key), and reports fields where one camera's value deviates from the cohort's modal value under 'outliers'. Per-camera path tokens (e.g. 'ai/SecCam_3/motion') are templated to '' before comparison so legitimate per-camera substitution doesn't false-positive. The 'enabled' field is reported separately under 'disabled_outliers' so a row left disabled by accident is easy to spot. Outliers are NOT necessarily bugs — they may be intentional per-camera customizations (e.g. one camera filtering different trigger sources, or running a narrower profile set). Present findings to the user as 'values worth confirming' and ask whether each is intentional. Pure read; no live BI connection. |
| bi_list_camerasB | List of all cameras and groups: online state, motion/trigger/alert counts, stream bitrate/FPS/resolution, last alert time, error state. |
| bi_get_camera_configA | Per-camera config + state. With admin creds, calls |
| bi_get_camera_motion_configA | Live motion + post-trigger settings for a camera, read from BI's admin |
| bi_list_clipsA | Recent recorded clips for a camera: path, duration, resolution, flags, memo. Complementary to bi_list_alerts (clips include continuous recordings; alerts are AI/motion events). Requires 'camera' short name (or 'Index' for all). Optional 'view' (filter; see schema for full enum), 'startdate'/'enddate' accept unix epoch int, ISO-8601, or relative shorthand ('-2h', '-1d'). 'search' (memo substring, server-side), 'tiles' (true=one entry per day, useful for calendar views). 'limit' default 50. Crossover note: alert-side view values (e.g. 'alerts', 'people', 'zonea') will return alert items in this response — they have an 'msec' field meaning alert length (not clip length) and lack the 'zones' field. UI3 v91 fixed a bug where this was mishandled. |
| bi_explain_alert_chainA | Use after |
| bi_list_logA | Recent Blue Iris system log entries with optional filters. Pick the right tool: for reconstructing 'what fired when' on a camera, start with Filters:
since — UTC epoch sec, ISO-8601, or '-15m'/'-2h'/'-1d' (server-side via aftertime)
camera — exact match on entry.obj (clone cameras log under their own short names)
obj — exact match on entry.obj (escape hatch: 'App', 'MQTT', 'DB', 'AI_Input', drive letters, usernames)
levels — list of accepted level ints; empirical: 0=info, 1=warn, 2=error, 3=trigger/alert aggregate (deduped — use Returns {entries, scanned, matched, warning?}. BI aggregates repeated messages: |
| bi_get_ptz_statusA | PTZ state for one camera. All fields BI returns are passed through (presets[], presetnum, brightness, contrast, irmode, powermode, talksamplerate). Adds two derived helpers: 'preset_map' = {N: description, ...} keyed by preset number (UI3 source: presets[] is 1-indexed by position; "(undefined)" and empty descriptions are dropped), and 'active_preset' = {num, description} when presetnum is set. Camera must have PTZ enabled in BI. |
| bi_get_regA | Parse a camera's .reg export and return the requested key subtree. Use this for what the BI JSON API does NOT expose: trigger zone polygons (Motion<profile>\maskbits_*), per-class AI confidence thresholds (AI<profile>\smartconf), per-preset alert-skip flags (PTZ\Presets<n>\noalerts), ONVIF event handlers (camevents<n>), and alert action definitions (Alerts\OnTrigger). Optional 'key_path' limits the response to that subtree (e.g. 'AI\3' for profile 3 AI config). Returns staleness warning if the .reg file is >7 days old. |
| bi_get_camera_snapshotA | Fetch a single current JPEG frame from a camera via |
| bi_get_statusB | Snapshot of Blue Iris system state: active profile, schedule hold/run, CPU%, RAM, disk usage, uptime, DIO outputs, warnings. |
| bi_get_sessionA | Blue Iris version/license, time zone, capabilities of the current user (admin/ptz/clips/etc), and available profile/schedule/stream names. |
| bi_get_sysconfigA | System config snapshot (admin required): FTP archive enable, global schedule on/off, manual record time limit, plus any DIO/MQTT state BI exposes inline. Use this instead of asking the user to screenshot Settings → Other. |
| bi_get_timelineA | 24-hour activity timeline (motion/trigger/alert buckets) for a camera. Requires 'camera' short name. If both 'startdate' and 'enddate' are omitted, defaults to the last 24 hours (BI returns empty spans for a rangeless query). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 19 tools
Most tools target clearly distinct resources or workflows — alerts, clips, log, timeline, snapshots, config, and PTZ status are well separated. A few could be confused at first glance, particularly bi_get_actionset vs bi_audit_actions and bi_get_session vs bi_get_status vs bi_get_sysconfig, but the descriptions draw clear boundaries.
All tools follow a consistent bi_<verb>_<object> pattern with snake_case throughout. get is used for single-item/state lookups, list is used for collections, and explain/audit are appropriately used for analytical tools, so the naming is predictable and coherent.
Nineteen tools is slightly above the ideal 3-15 range, but the count is justified by the breadth of the Blue Iris domain: system health, per-camera config, alert/clip forensics, PTZ state, logs, and .reg inspection. It feels near the upper edge rather than bloated.
The read/investigation surface is deep, but there are no write or control tools at all — no PTZ movement, profile switching, camera trigger, or clip management — which makes the server one-directional. Additionally, bi_get_alert_tracks is documented as broken, creating a dead end for AI track workflows.