go2rtc-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,397 @@
1
+ Metadata-Version: 2.4
2
+ Name: go2rtc-mcp
3
+ Version: 0.1.0
4
+ Summary: Production-grade Model Context Protocol (MCP) server for go2rtc streaming servers
5
+ Author: Armen
6
+ Author-email: Armen <gaxkalik@gmail.com>
7
+ License-Expression: MIT
8
+ Requires-Dist: httpx>=0.28.1
9
+ Requires-Dist: mcp[cli]>=1.2.0
10
+ Requires-Dist: pydantic>=2.10.0
11
+ Requires-Dist: python-dotenv>=1.0.1
12
+ Requires-Dist: pyyaml>=6.0.2
13
+ Requires-Python: >=3.11
14
+ Project-URL: Homepage, https://github.com/gaxkalik/go2rtc-mcp
15
+ Project-URL: Repository, https://github.com/gaxkalik/go2rtc-mcp
16
+ Project-URL: Issues, https://github.com/gaxkalik/go2rtc-mcp/issues
17
+ Description-Content-Type: text/markdown
18
+
19
+ # go2rtc-mcp
20
+
21
+ A production-grade **Model Context Protocol (MCP)** server for [go2rtc](https://github.com/AlexxIT/go2rtc) (including Home Assistant's built-in `go2rtc` service). Designed primarily for **Linux** environments (Home Assistant Supervised/OS, Debian/Ubuntu, Docker, and headless media servers), `go2rtc-mcp` enables AI assistants and MCP clients to inspect camera streams, probe video/audio codecs, capture live JPEG snapshots, generate streaming playback URLs (WebRTC, MSE, HLS, MP4, MJPEG, RTSP), discover camera integrations, and manage streams dynamically—with **strict, automated credential redaction**.
22
+
23
+ ---
24
+
25
+ ## Table of Contents
26
+
27
+ - [Architecture & Security Guardrails](#architecture--security-guardrails)
28
+ - [Linux Installation & Quick Start](#linux-installation--quick-start)
29
+ - [Configuration](#configuration)
30
+ - [MCP Client Configuration (Linux, macOS, Windows)](#mcp-client-configuration-linux-macos-windows)
31
+ - [Running as a Systemd Service (Linux)](#running-as-a-systemd-service-linux)
32
+ - [Usage Guide](#usage-guide)
33
+ - [Example Natural-Language Prompts](#example-natural-language-prompts)
34
+ - [MCP Tools Reference & Examples](#mcp-tools-reference--examples)
35
+ - [MCP Resources Reference](#mcp-resources-reference)
36
+ - [MCP Prompts Reference](#mcp-prompts-reference)
37
+ - [Programmatic Python Usage](#programmatic-python-usage)
38
+ - [Project Structure](#project-structure)
39
+ - [Development & Testing](#development--testing)
40
+ - [License](#license)
41
+
42
+ ---
43
+
44
+ ## Architecture & Security Guardrails
45
+
46
+ Live `go2rtc` API endpoints (`/api/streams`, `/api/config`, `/api/hass`, `/api/log`) regularly return plaintext or URL-encoded camera credentials and authentication tokens in RTSP producer URLs. `go2rtc-mcp` enforces defense-in-depth security:
47
+
48
+ ### 1. Centralized Recursive Credential Redaction (`redact_sensitive_data`)
49
+ Every MCP tool return value, MCP resource response, client error message, and log record passes through [`redact_sensitive_data`](src/go2rtc_mcp/security.py):
50
+ - **Universal URI Credential Masking**: Masks credentials in any URI scheme (`rtsp://`, `rtsps://`, `http://`, `https://`, `rtmp://`, `onvif://`, `dvrip://`, including chained prefixes like `ffmpeg:rtsp://...`).
51
+ - **Query Parameter Token Masking**: Masks sensitive query parameters (`token`, `access_token`, `auth`, `password`, `pass`, `pwd`, `secret`, `api_key`, `jwt`).
52
+ - **Recursive Dict Key & Value Sanitization**: Sanitizes both dictionary keys and values (crucial because `go2rtc` creates dynamic stream keys named after raw RTSP URLs), lists, tuples, sets, Pydantic models, and multiline YAML text.
53
+ - **Log Stream Redaction**: Attaches `RedactingLoggingFilter` to `httpx`, `httpcore`, `mcp`, and `go2rtc_mcp` loggers so credentials never reach `stdout`/`stderr` or `journald`.
54
+
55
+ **Example Transformation:**
56
+ ```text
57
+ Raw from go2rtc:
58
+ rtsp://admin:mockpass%2A@192.0.2.10:554/Streaming/Channels/101
59
+ rtsp://stream.example.com/live?token=eyJmockToken123&tracks=v1a1
60
+
61
+ Returned by go2rtc-mcp:
62
+ rtsp://***:***@192.0.2.10:554/Streaming/Channels/101
63
+ rtsp://stream.example.com/live?token=***&tracks=v1a1
64
+ ```
65
+
66
+ ### 2. Command Execution Guardrail (`GO2RTC_ALLOW_EXEC_STREAMS`)
67
+ `go2rtc` allows stream sources starting with `exec:`, `echo:`, and `expr:` to execute host shell commands. By default (`GO2RTC_ALLOW_EXEC_STREAMS=false`), `go2rtc-mcp` rejects any `add_stream` or `update_stream` request containing `exec:`, `echo:`, or `expr:` (including chained forms like `ffmpeg:exec:...`) before any network request is issued.
68
+
69
+ ---
70
+
71
+ ## Linux Installation & Quick Start
72
+
73
+ ### Prerequisites
74
+ - **Linux** (Debian, Ubuntu, Alpine, Arch, Fedora, Raspberry Pi OS, etc.)
75
+ - **Python** `>= 3.11`
76
+ - **[uv](https://docs.astral.sh/uv/)** package manager (recommended: `curl -LsSf https://astral.sh/uv/install.sh | sh`)
77
+ - Access to your `go2rtc` instance (e.g. `http://localhost:1984` or local network IP)
78
+
79
+ ### 1. Clone the Repository
80
+ ```bash
81
+ git clone https://github.com/gaxkalik/go2rtc-mcp.git
82
+ cd go2rtc-mcp
83
+ ```
84
+
85
+ ### 2. Install Dependencies with `uv`
86
+ ```bash
87
+ uv sync
88
+ ```
89
+
90
+ ### 3. Configure Environment Variables
91
+ Copy `.env.example` to `.env`:
92
+ ```bash
93
+ cp .env.example .env
94
+ ```
95
+
96
+ Edit `.env` using your preferred editor (`nano .env` or `vim .env`):
97
+ ```env
98
+ GO2RTC_URL=http://localhost:1984
99
+ GO2RTC_USERNAME=
100
+ GO2RTC_PASSWORD=
101
+ GO2RTC_TIMEOUT=15.0
102
+ GO2RTC_ALLOW_EXEC_STREAMS=false
103
+ ```
104
+
105
+ ### 4. Run and Test the MCP Server
106
+ Run over `stdio` transport (standard for MCP clients):
107
+ ```bash
108
+ uv run go2rtc-mcp
109
+ ```
110
+
111
+ Or test interactively in your browser with the official MCP Inspector:
112
+ ```bash
113
+ npx @modelcontextprotocol/inspector uv run go2rtc-mcp
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Configuration
119
+
120
+ `go2rtc-mcp` loads settings from environment variables (and automatically reads a local `.env` file if present):
121
+
122
+ | Environment Variable | Default | Description |
123
+ | :--- | :--- | :--- |
124
+ | `GO2RTC_URL` | `http://localhost:1984` | Base HTTP/HTTPS URL of your `go2rtc` server |
125
+ | `GO2RTC_USERNAME` | *(empty)* | Optional HTTP Basic Auth username |
126
+ | `GO2RTC_PASSWORD` | *(empty)* | Optional HTTP Basic Auth password |
127
+ | `GO2RTC_TIMEOUT` | `15.0` | Request timeout in seconds |
128
+ | `GO2RTC_ALLOW_EXEC_STREAMS` | `false` | Set to `true` only if you explicitly allow `exec:` / `echo:` / `expr:` sources |
129
+
130
+ ---
131
+
132
+ ## MCP Client Configuration (Linux, macOS, Windows)
133
+
134
+ ### Linux (`~/.config/Claude/claude_desktop_config.json` or `~/.gemini/config/mcp_config.json`)
135
+ ```json
136
+ {
137
+ "mcpServers": {
138
+ "go2rtc": {
139
+ "command": "uv",
140
+ "args": [
141
+ "--directory",
142
+ "/home/user/go2rtc-mcp",
143
+ "run",
144
+ "go2rtc-mcp"
145
+ ],
146
+ "env": {
147
+ "GO2RTC_URL": "http://localhost:1984",
148
+ "GO2RTC_USERNAME": "",
149
+ "GO2RTC_PASSWORD": "",
150
+ "GO2RTC_TIMEOUT": "15.0",
151
+ "GO2RTC_ALLOW_EXEC_STREAMS": "false"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ > **Note**: Adjust `/home/user/go2rtc-mcp` (or `/config/go2rtc-mcp` on Home Assistant) to your actual installation path. Ensure `uv` is in your system `PATH` (e.g. `/home/user/.cargo/bin/uv` or `/usr/local/bin/uv`).
159
+
160
+ ### macOS (`~/Library/Application Support/Claude/claude_desktop_config.json`)
161
+ Replace the directory path with `/Users/username/go2rtc-mcp`.
162
+
163
+ ### Windows (`%APPDATA%\Claude\claude_desktop_config.json`)
164
+ Replace the directory path with `C:/Users/username/go2rtc-mcp`.
165
+
166
+ ---
167
+
168
+ ## Running as a Systemd Service (Linux)
169
+
170
+ If you wish to run `go2rtc-mcp` as a persistent background daemon or manage it through Linux `systemctl`:
171
+
172
+ Create `/etc/systemd/system/go2rtc-mcp.service`:
173
+ ```ini
174
+ [Unit]
175
+ Description=go2rtc Model Context Protocol Server
176
+ After=network.target
177
+
178
+ [Service]
179
+ Type=simple
180
+ User=user
181
+ WorkingDirectory=/home/user/go2rtc-mcp
182
+ EnvironmentFile=/home/user/go2rtc-mcp/.env
183
+ ExecStart=/home/user/.cargo/bin/uv run go2rtc-mcp
184
+ Restart=always
185
+ RestartSec=5
186
+
187
+ [Install]
188
+ WantedBy=multi-user.target
189
+ ```
190
+
191
+ Enable and start the service:
192
+ ```bash
193
+ sudo systemctl daemon-reload
194
+ sudo systemctl enable --now go2rtc-mcp
195
+ sudo systemctl status go2rtc-mcp
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Usage Guide
201
+
202
+ ### Example Natural-Language Prompts
203
+ Ask your AI assistant:
204
+ - *"List all cameras configured on my go2rtc server."*
205
+ - *"Take a snapshot of `door_camera` and describe the current scene."*
206
+ - *"Perform a security patrol across all active cameras."*
207
+ - *"Probe `garage_camera` codecs, resolution, and RTSP protocol."*
208
+ - *"Generate WebRTC viewer, HLS (.m3u8), and RTSP playback links for `outside_camera`."*
209
+ - *"Check recent go2rtc logs for connection errors or offline feeds."*
210
+
211
+ ---
212
+
213
+ ### MCP Tools Reference & Examples
214
+
215
+ #### 1. `get_server_info()`
216
+ Fetches `go2rtc` version, revision, host, and RTSP port (`GET /api`).
217
+ - **Sample Output:**
218
+ ```json
219
+ {
220
+ "config_path": "/config/go2rtc.yaml",
221
+ "host": "localhost:1984",
222
+ "revision": "b5948cf",
223
+ "rtsp": {
224
+ "default_query": "video&audio",
225
+ "listen": ":554"
226
+ },
227
+ "version": "1.9.14"
228
+ }
229
+ ```
230
+
231
+ #### 2. `list_streams()`
232
+ Lists all configured and active streams (`GET /api/streams`) with credentials automatically masked.
233
+ - **Sample Output:**
234
+ ```json
235
+ {
236
+ "door_camera": {
237
+ "producers": [
238
+ {
239
+ "url": "rtsp://***:***@192.0.2.10:554/Streaming/Channels/101"
240
+ }
241
+ ],
242
+ "consumers": []
243
+ },
244
+ "garage_camera": {
245
+ "producers": [
246
+ {
247
+ "url": "rtsp://***:***@192.0.2.11:554/Streaming/Channels/101"
248
+ }
249
+ ],
250
+ "consumers": []
251
+ }
252
+ }
253
+ ```
254
+
255
+ #### 3. `get_stream_info(stream_name: str, probe: bool = False)`
256
+ Fetches producer and consumer state for a specific camera (`GET /api/streams?src=<stream_name>`). Pass `probe=True` to query live codecs and SDP.
257
+
258
+ #### 4. `probe_stream(stream_name: str)`
259
+ Actively queries `GET /api/streams?src=<stream_name>&video=all&audio=all` to inspect active codecs (H.264, H.265, AAC, PCMA, Opus), SDP tracks, protocol (`rtsp+tcp`), and byte counters.
260
+
261
+ #### 5. `get_stream_snapshot(stream_name: str, width: int | None = None, height: int | None = None)`
262
+ Captures a live JPEG frame from `stream_name` (`GET /api/frame.jpeg?src=<stream_name>`) and returns it as a native MCP `Image` (`image/jpeg`) for multimodal vision models.
263
+
264
+ #### 6. `get_stream_urls(stream_name: str)`
265
+ Generates ready-to-use streaming URLs for web, mobile, and NVR playback:
266
+ - **Sample Output:**
267
+ ```json
268
+ {
269
+ "stream": "door_camera",
270
+ "webrtc_viewer": "http://localhost:1984/stream.html?src=door_camera&mode=webrtc",
271
+ "mse_viewer": "http://localhost:1984/stream.html?src=door_camera&mode=mse",
272
+ "websocket_url": "ws://localhost:1984/api/ws?src=door_camera",
273
+ "hls_m3u8": "http://localhost:1984/api/stream.m3u8?src=door_camera",
274
+ "mp4_stream": "http://localhost:1984/api/stream.mp4?src=door_camera",
275
+ "mjpeg_stream": "http://localhost:1984/api/stream.mjpeg?src=door_camera",
276
+ "snapshot_jpeg": "http://localhost:1984/api/frame.jpeg?src=door_camera",
277
+ "rtsp_url": "rtsp://localhost:554/door_camera"
278
+ }
279
+ ```
280
+
281
+ #### 7. `add_stream(stream_name: str, source_url: str)`
282
+ Dynamically registers or updates a stream (`PUT /api/streams?name=<name>&src=<url>`), validating against `GO2RTC_ALLOW_EXEC_STREAMS`.
283
+
284
+ #### 8. `update_stream(stream_name: str, source_url: str)`
285
+ Dynamically updates an existing stream source (`PATCH /api/streams`).
286
+
287
+ #### 9. `delete_stream(stream_name: str)`
288
+ Removes a dynamically registered stream (`DELETE /api/streams?src=<name>`).
289
+
290
+ #### 10. `get_config()`
291
+ Retrieves sanitized `go2rtc.yaml` configuration (`GET /api/config`) with all secrets masked.
292
+
293
+ #### 11. `get_server_logs(limit: int = 50)`
294
+ Fetches recent `go2rtc` log entries (`GET /api/log`) with credentials redacted.
295
+
296
+ #### 12. `discover_sources(provider: str = "hass")`
297
+ Discovers stream sources from integrations (`hass`, `onvif`, `dvrip`, `homekit`, `roborock`, `webtorrent`).
298
+
299
+ ---
300
+
301
+ ### MCP Resources Reference
302
+
303
+ | Resource URI | MIME Type | Description |
304
+ | :--- | :--- | :--- |
305
+ | `go2rtc://server/info` | `application/json` | Server version, revision, host, and RTSP listener config |
306
+ | `go2rtc://streams` | `application/json` | Complete dictionary of streams with redacted producer URLs |
307
+ | `go2rtc://streams/{stream_name}` | `application/json` | Producer and consumer details for `{stream_name}` |
308
+ | `go2rtc://config` | `text/yaml` | Sanitized `go2rtc.yaml` configuration |
309
+
310
+ ---
311
+
312
+ ### MCP Prompts Reference
313
+
314
+ - **`snapshot_all`**: Captures live frames from all cameras and generates a multi-camera visual security summary.
315
+ - **`security_patrol`**: Full security assessment combining stream health, frame capture, and log error analysis.
316
+ - **`diagnose_stream(stream_name)`**: Guided step-by-step diagnostic workflow for troubleshooting a camera.
317
+ - **`camera_urls(stream_name)`**: Formats all direct streaming integration links.
318
+ - **`stream_health_check`**: System-wide health audit of all streams, codecs, and logs.
319
+
320
+ ---
321
+
322
+ ### Programmatic Python Usage
323
+
324
+ ```python
325
+ import asyncio
326
+ from go2rtc_mcp import Go2RtcClient, Go2RtcSettings, redact_sensitive_data
327
+
328
+
329
+ async def main() -> None:
330
+ settings = Go2RtcSettings.from_env()
331
+ client = Go2RtcClient(settings=settings)
332
+
333
+ # 1. Fetch server metadata
334
+ info = await client.get_server_info()
335
+ print("Server version:", info.get("version"))
336
+
337
+ # 2. List streams (credentials automatically masked)
338
+ streams = await client.list_streams()
339
+ for name, data in streams.items():
340
+ print(f"Stream: {name} -> {data}")
341
+
342
+ # 3. Capture a live JPEG snapshot
343
+ jpeg_bytes = await client.get_snapshot("door_camera", width=1280)
344
+ with open("door_snapshot.jpg", "wb") as f:
345
+ f.write(jpeg_bytes)
346
+ print("Saved door_snapshot.jpg")
347
+
348
+
349
+ if __name__ == "__main__":
350
+ asyncio.run(main())
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Project Structure
356
+
357
+ ```text
358
+ go2rtc-mcp/
359
+ ├── .env.example # Safe template for environment variables
360
+ ├── .gitignore # Excludes .env, snapshots (*.jpg/*.png/*.mp4), and live dumps
361
+ ├── LICENSE # MIT License
362
+ ├── pyproject.toml # Package metadata, dependencies, pytest & ruff config
363
+ ├── README.md # Project documentation and Linux usage guide
364
+ ├── src/
365
+ │ └── go2rtc_mcp/
366
+ │ ├── __init__.py # Public package exports
367
+ │ ├── client.py # Async httpx Go2RtcClient with automatic redaction
368
+ │ ├── config.py # Pydantic Go2RtcSettings & dotenv loader
369
+ │ ├── models.py # Pydantic models for server & stream objects
370
+ │ ├── sanitizer.py # Alias module re-exporting security redaction utilities
371
+ │ ├── security.py # redact_sensitive_data, validate_stream_source, log filter
372
+ │ └── server.py # MCPServer tools, resources, prompts, and CLI entry point
373
+ └── tests/
374
+ ├── test_client.py # respx unit tests for Go2RtcClient endpoints & error handling
375
+ ├── test_security.py # Unit tests for URI schemes, recursive redaction & exec policy
376
+ └── test_server.py # Unit tests for MCP tools, resources, snapshots & prompts
377
+ ```
378
+
379
+ ---
380
+
381
+ ## Development & Testing
382
+
383
+ All unit tests use synthetic RFC 5737 (`192.0.2.0/24`) test fixtures and mock responses via `respx` so tests run offline and deterministically on Linux:
384
+
385
+ ```bash
386
+ # Run unit tests
387
+ uv run python -m pytest -v
388
+
389
+ # Run ruff linter
390
+ uv run ruff check src/ tests/
391
+ ```
392
+
393
+ ---
394
+
395
+ ## License
396
+
397
+ Released under the [MIT License](LICENSE).