Skip to main content
Glama
README.md
<!-- mcp-name: io.github.phil-bryant/spot-ai-mcp -->

# spot-ai-mcp

**Unofficial community MCP server for the [Spot AI](https://developers.spot.ai)
camera / video-intelligence REST API. Not affiliated with or endorsed by Spot AI.**

Single-file, stdio transport, no dependencies beyond Python 3.9+.
Read-only by design: it can browse cameras and intelligence data but can never modify
anything in your Spot AI org. Every tool wraps a GET endpoint except
`get_live_stream_urls`, which wraps `POST /v1/cameras/live` — a read-like POST that
only generates a viewing URL. All tools declare the `readOnlyHint: true` MCP annotation.

## Install

```bash
uvx spot-ai-mcp
```

or `pip install spot-ai-mcp`, or run straight from a checkout with
`python3 -m spot_ai_mcp` (no dependencies to install).

Register with Claude Code:

```bash
claude mcp add spot-ai -s user -e SPOT_AI_API_KEY=YOUR_KEY -- uvx spot-ai-mcp
```

## API key

Create a key in the Spot AI dashboard's API settings, then **add an authorization**
(a role, e.g. Owner, optionally scoped) on the key's settings page. A key without a
role returns empty lists from every resource endpoint while `get_camera_count` still
works — that's the tell.

The server resolves the key lazily on the first API call:

1. `SPOT_AI_API_KEY` environment variable — the normal path.
2. Optionally, a secret-helper command, so the key never sits in an env var or config:
   the server runs `$SPOT_AI_OP_BIN -f $SPOT_AI_OP_ITEM $SPOT_AI_OP_FIELD`
   (defaults `1psa -f spot.ai api_key`, per [1psa](https://github.com/phil-bryant/1psa),
   a vault-scoped 1Password service-account CLI). Point these at any command with the
   same flag convention.

The key is never written to disk or config by this server.

## Tools

| Tool | What it does |
|------|--------------|
| `list_locations` | Locations the key can see (paginated) |
| `list_cameras` | Cameras with status, location, IP, MAC (paginated) |
| `get_camera` | One camera by id |
| `get_camera_count` | Number of enabled cameras in the org |
| `list_appliances` | Intelligent Video Recorders (paginated) |
| `get_zones` | Zones defined on a camera |
| `get_intelligence` | Counting / idle / presence events for people, vehicles, or forklifts over a date range |
| `get_lpr_report` | License-plate-recognition report for an LPR camera |
| `get_live_stream_urls` | Live-stream viewing URL for up to 4 cameras |
| `spot_api_get` | Escape hatch: GET any documented `/v1/` or `/v2/` path |

## Notes

- Dual-era MCP server: speaks both the modern per-request protocol
  (`server/discover`, spec 2026-07-28) and the legacy `initialize` handshake
  (2024-11-05 through 2025-06-18), so old and new clients both work.
- Base URL is `https://dev-api.spot.ai`, auth is `Authorization: Bearer <key>`.
- Cloudflare in front of the API rejects Python's default user agent with error 1010;
  the server sends `User-Agent: spot-ai-mcp/<version>`.
- Endpoint index: <https://developers.spot.ai/llms.txt> (append `.md` to any docs URL
  for markdown, including the OpenAPI definition per endpoint).

## License

MIT

TDQS

A3.6/5.0

Scored across 10 tools

Disambiguation4/5

Most tools target clearly distinct resources and actions (locations, cameras, appliances, zones, intelligence, LPR). The main overlaps are get_camera_count versus list_cameras (count is derivable) and spot_api_get, which by design overlaps with everything as an escape hatch, but it is explicitly framed as a generic fallback.

Naming Consistency4/5

Nine of ten tools follow a clean verb_noun pattern (list_locations, get_camera, get_zones, etc.) using get_/list_ prefixes. The single outlier is spot_api_get, which uses a noun_verb ordering, a minor deviation.

Tool Count5/5

Ten tools is well within the ideal range and each one covers a distinct read operation. No redundant or filler tools; the set is tightly scoped to a read-only camera/security API.

Completeness4/5

The surface covers the core domain: locations, cameras, appliances, zones, intelligence events, LPR, and live streams. Minor gaps exist (no get_location or get_appliance detail), but the spot_api_get escape hatch lets agents reach any documented endpoint, mitigating dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues