go2rtc-mcp
Provides tools for interacting with Home Assistant's built-in go2rtc service, enabling inspection of camera streams, codec probing, JPEG snapshots, playback URL generation, and dynamic stream management.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@go2rtc-mcpcapture a live JPEG snapshot from the front door camera"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
go2rtc-mcp
A production-grade Model Context Protocol (MCP) server for 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.
Table of Contents
Related MCP server: WAVE MCP Server
Architecture & Security Guardrails
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:
1. Centralized Recursive Credential Redaction (redact_sensitive_data)
Every MCP tool return value, MCP resource response, client error message, and log record passes through redact_sensitive_data:
Universal URI Credential Masking: Masks credentials in any URI scheme (
rtsp://,rtsps://,http://,https://,rtmp://,onvif://,dvrip://, including chained prefixes likeffmpeg:rtsp://...).Query Parameter Token Masking: Masks sensitive query parameters (
token,access_token,auth,password,pass,pwd,secret,api_key,jwt).Recursive Dict Key & Value Sanitization: Sanitizes both dictionary keys and values (crucial because
go2rtccreates dynamic stream keys named after raw RTSP URLs), lists, tuples, sets, Pydantic models, and multiline YAML text.Log Stream Redaction: Attaches
RedactingLoggingFiltertohttpx,httpcore,mcp, andgo2rtc_mcploggers so credentials never reachstdout/stderrorjournald.
Example Transformation:
Raw from go2rtc:
rtsp://admin:mockpass%2A@192.0.2.10:554/Streaming/Channels/101
rtsp://stream.example.com/live?token=eyJmockToken123&tracks=v1a1
Returned by go2rtc-mcp:
rtsp://***:***@192.0.2.10:554/Streaming/Channels/101
rtsp://stream.example.com/live?token=***&tracks=v1a12. Command Execution Guardrail (GO2RTC_ALLOW_EXEC_STREAMS)
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.
Linux Installation & Quick Start
Prerequisites
Linux (Debian, Ubuntu, Alpine, Arch, Fedora, Raspberry Pi OS, etc.)
Python
>= 3.11uv package manager (recommended:
curl -LsSf https://astral.sh/uv/install.sh | sh)
Instant Run with uvx (No Clone Required)
Run go2rtc-mcp directly using uvx from PyPI:
# Run over stdio
GO2RTC_URL=http://localhost:1984 uvx go2rtc-mcpManual Installation from Source
1. Clone the Repository
git clone https://github.com/gaxkalik/go2rtc-mcp.git
cd go2rtc-mcp2. Install Dependencies with uv
uv sync3. Configure Environment Variables
Copy .env.example to .env:
cp .env.example .envEdit .env using your preferred editor (nano .env or vim .env):
GO2RTC_URL=http://localhost:1984
GO2RTC_USERNAME=
GO2RTC_PASSWORD=
GO2RTC_TIMEOUT=15.0
GO2RTC_ALLOW_EXEC_STREAMS=false4. Run and Test the MCP Server
Run over stdio transport (standard for MCP clients):
uv run go2rtc-mcpOr test interactively in your browser with the official MCP Inspector:
npx @modelcontextprotocol/inspector uv run go2rtc-mcpConfiguration
go2rtc-mcp loads settings from environment variables (and automatically reads a local .env file if present):
Environment Variable | Default | Description |
|
| Base HTTP/HTTPS URL of your |
| (empty) | Optional HTTP Basic Auth username |
| (empty) | Optional HTTP Basic Auth password |
|
| Request timeout in seconds |
|
| Set to |
MCP Client Configuration (Claude Desktop, Cursor, Antigravity)
Option A: Using uvx from PyPI (Recommended - No Clone Needed)
Add go2rtc to your client configuration file:
Linux:
~/.config/Claude/claude_desktop_config.jsonor~/.gemini/config/mcp_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"go2rtc": {
"command": "uvx",
"args": ["go2rtc-mcp"],
"env": {
"GO2RTC_URL": "http://localhost:1984",
"GO2RTC_ALLOW_EXEC_STREAMS": "false"
}
}
}
}Option B: From Local Source Clone
If running from a cloned local repository:
{
"mcpServers": {
"go2rtc": {
"command": "uv",
"args": [
"--directory",
"/path/to/go2rtc-mcp",
"run",
"go2rtc-mcp"
],
"env": {
"GO2RTC_URL": "http://localhost:1984",
"GO2RTC_ALLOW_EXEC_STREAMS": "false"
}
}
}
}Running as a Systemd Service (Linux)
If you wish to run go2rtc-mcp as a persistent background daemon or manage it through Linux systemctl:
Create /etc/systemd/system/go2rtc-mcp.service:
[Unit]
Description=go2rtc Model Context Protocol Server
After=network.target
[Service]
Type=simple
User=user
WorkingDirectory=/home/user/go2rtc-mcp
EnvironmentFile=/home/user/go2rtc-mcp/.env
ExecStart=/home/user/.cargo/bin/uv run go2rtc-mcp
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable --now go2rtc-mcp
sudo systemctl status go2rtc-mcpUsage Guide
Example Natural-Language Prompts
Ask your AI assistant:
"List all cameras configured on my go2rtc server."
"Take a snapshot of
door_cameraand describe the current scene.""Perform a security patrol across all active cameras."
"Probe
garage_cameracodecs, resolution, and RTSP protocol.""Generate WebRTC viewer, HLS (.m3u8), and RTSP playback links for
outside_camera.""Check recent go2rtc logs for connection errors or offline feeds."
MCP Tools Reference & Examples
1. get_server_info()
Fetches go2rtc version, revision, host, and RTSP port (GET /api).
Sample Output:
{ "config_path": "/config/go2rtc.yaml", "host": "localhost:1984", "revision": "b5948cf", "rtsp": { "default_query": "video&audio", "listen": ":554" }, "version": "1.9.14" }
2. list_streams()
Lists all configured and active streams (GET /api/streams) with credentials automatically masked.
Sample Output:
{ "door_camera": { "producers": [ { "url": "rtsp://***:***@192.0.2.10:554/Streaming/Channels/101" } ], "consumers": [] }, "garage_camera": { "producers": [ { "url": "rtsp://***:***@192.0.2.11:554/Streaming/Channels/101" } ], "consumers": [] } }
3. get_stream_info(stream_name: str, probe: bool = False)
Fetches producer and consumer state for a specific camera (GET /api/streams?src=<stream_name>). Pass probe=True to query live codecs and SDP.
4. probe_stream(stream_name: str)
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.
5. get_stream_snapshot(stream_name: str, width: int | None = None, height: int | None = None)
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.
6. get_stream_urls(stream_name: str)
Generates ready-to-use streaming URLs for web, mobile, and NVR playback:
Sample Output:
{ "stream": "door_camera", "webrtc_viewer": "http://localhost:1984/stream.html?src=door_camera&mode=webrtc", "mse_viewer": "http://localhost:1984/stream.html?src=door_camera&mode=mse", "websocket_url": "ws://localhost:1984/api/ws?src=door_camera", "hls_m3u8": "http://localhost:1984/api/stream.m3u8?src=door_camera", "mp4_stream": "http://localhost:1984/api/stream.mp4?src=door_camera", "mjpeg_stream": "http://localhost:1984/api/stream.mjpeg?src=door_camera", "snapshot_jpeg": "http://localhost:1984/api/frame.jpeg?src=door_camera", "rtsp_url": "rtsp://localhost:554/door_camera" }
7. add_stream(stream_name: str, source_url: str)
Dynamically registers or updates a stream (PUT /api/streams?name=<name>&src=<url>), validating against GO2RTC_ALLOW_EXEC_STREAMS.
8. update_stream(stream_name: str, source_url: str)
Dynamically updates an existing stream source (PATCH /api/streams).
9. delete_stream(stream_name: str)
Removes a dynamically registered stream (DELETE /api/streams?src=<name>).
10. get_config()
Retrieves sanitized go2rtc.yaml configuration (GET /api/config) with all secrets masked.
11. get_server_logs(limit: int = 50)
Fetches recent go2rtc log entries (GET /api/log) with credentials redacted.
12. discover_sources(provider: str = "hass")
Discovers stream sources from integrations (hass, onvif, dvrip, homekit, roborock, webtorrent).
MCP Resources Reference
Resource URI | MIME Type | Description |
|
| Server version, revision, host, and RTSP listener config |
|
| Complete dictionary of streams with redacted producer URLs |
|
| Producer and consumer details for |
|
| Sanitized |
MCP Prompts Reference
snapshot_all: Captures live frames from all cameras and generates a multi-camera visual security summary.security_patrol: Full security assessment combining stream health, frame capture, and log error analysis.diagnose_stream(stream_name): Guided step-by-step diagnostic workflow for troubleshooting a camera.camera_urls(stream_name): Formats all direct streaming integration links.stream_health_check: System-wide health audit of all streams, codecs, and logs.
Programmatic Python Usage
import asyncio
from go2rtc_mcp import Go2RtcClient, Go2RtcSettings, redact_sensitive_data
async def main() -> None:
settings = Go2RtcSettings.from_env()
client = Go2RtcClient(settings=settings)
# 1. Fetch server metadata
info = await client.get_server_info()
print("Server version:", info.get("version"))
# 2. List streams (credentials automatically masked)
streams = await client.list_streams()
for name, data in streams.items():
print(f"Stream: {name} -> {data}")
# 3. Capture a live JPEG snapshot
jpeg_bytes = await client.get_snapshot("door_camera", width=1280)
with open("door_snapshot.jpg", "wb") as f:
f.write(jpeg_bytes)
print("Saved door_snapshot.jpg")
if __name__ == "__main__":
asyncio.run(main())Project Structure
go2rtc-mcp/
├── .env.example # Safe template for environment variables
├── .gitignore # Excludes .env, snapshots (*.jpg/*.png/*.mp4), and live dumps
├── LICENSE # MIT License
├── pyproject.toml # Package metadata, dependencies, pytest & ruff config
├── README.md # Project documentation and Linux usage guide
├── src/
│ └── go2rtc_mcp/
│ ├── __init__.py # Public package exports
│ ├── client.py # Async httpx Go2RtcClient with automatic redaction
│ ├── config.py # Pydantic Go2RtcSettings & dotenv loader
│ ├── models.py # Pydantic models for server & stream objects
│ ├── sanitizer.py # Alias module re-exporting security redaction utilities
│ ├── security.py # redact_sensitive_data, validate_stream_source, log filter
│ └── server.py # MCPServer tools, resources, prompts, and CLI entry point
└── tests/
├── test_client.py # respx unit tests for Go2RtcClient endpoints & error handling
├── test_security.py # Unit tests for URI schemes, recursive redaction & exec policy
└── test_server.py # Unit tests for MCP tools, resources, snapshots & promptsDevelopment & Testing
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:
# Run unit tests
uv run python -m pytest -v
# Run ruff linter
uv run ruff check src/ tests/License
Released under the MIT License.
Available Tools
12 toolsadd_streamB
Dynamically add or overwrite a stream on go2rtc (PUT /api/streams).
Rejects exec:, echo:, and expr: sources unless GO2RTC_ALLOW_EXEC_STREAMS=true.
| Name | Required | Description | Default |
|---|---|---|---|
| source_url | Yes | ||
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does usefully disclose upsert semantics (existing streams can be overwritten) and the exec/echo/expr rejection gated by GO2RTC_ALLOW_EXEC_STREAMS, but omits permission/auth requirements and what happens to an existing stream's configuration when overwritten.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and endpoint before the exception rule. Nothing is padded, though the raw endpoint notation adds little for an agent that only needs the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the key upsert behavior is covered. However, for a mutation tool with zero annotations and fully undocumented parameters, more on auth, overwrite side effects, and source_url format would be needed for full completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for two required parameters, and the description never explains stream_name or source_url. Mentioning exec:/echo:/expr: sources hints at accepted URL schemes, but format expectations (single vs multiple sources, rtsp:// etc.) remain undocumented in both places.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ('add or overwrite a stream') and pins it to the concrete go2rtc endpoint (PUT /api/streams). The 'or overwrite' phrasing implicitly separates it from update_stream, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance relative to the obvious alternatives (update_stream, delete_stream) despite those siblings existing. The only conditional given is an internal rejection rule for exec:/echo:/expr: sources, which is a constraint rather than routing advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_streamC
Delete a dynamically registered stream from go2rtc (DELETE /api/streams).
| Name | Required | Description | Default |
|---|---|---|---|
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It implies a destructive mutation and names the underlying endpoint, but says nothing about irreversibility, behavior when the stream does not exist, permission requirements, or whether other streams are affected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler; the trailing endpoint reference is mildly redundant but genuinely useful for agents reasoning about the go2rtc API surface.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, but for a destructive, unannotated tool with 0% parameter coverage the description is too thin. An agent gets no safety, error, or identifier-format context before issuing a delete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description says nothing about stream_name — not whether it must exactly match a registered name, whether it is case-sensitive, or what happens on a mismatch. The single required parameter is left entirely to inference from the tool name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Delete') and resource ('a dynamically registered stream'), and the 'dynamically registered' qualifier scopes it meaningfully. It does not explicitly differentiate from siblings like update_stream or add_stream, but the verb alone makes the distinction obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, but 'dynamically registered' implies a constraint (only runtime-registered streams, not statically configured ones), which is weak implied usage guidance. No alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discover_sourcesB
Discover stream sources from a go2rtc integration (hass, onvif, dvrip, homekit).
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | hass |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does not disclose that discovery likely involves network probing, whether it is slow or blocking, auth/credential requirements per provider, or any side effects. 'Discover' hints at a scan but nothing is stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the enumerations are compact. It is appropriately sized, though the fragmented phrasing leaves little room for the context an unannotated tool needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and an undocumented parameter, the description should explain what discovery returns and how the provider affects behavior. It leaves the agent without enough to anticipate the call's cost or result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema has no enum, so the description's parenthetical listing the valid providers (`hass`, `onvif`, `dvrip`, `homekit`) supplies real value that the schema lacks. It still omits the default ('hass') and any explanation of what a provider represents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Discover') plus resource ('stream sources') and the go2rtc integration context, which distinguishes it from list_streams and get_stream_info. It is clear enough to identify the operation, though it doesn't explicitly contrast itself with the sibling stream tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance is given, and no alternative sibling (e.g. list_streams for already-configured streams) is named. The agent must infer that this is for finding new sources rather than enumerating existing ones.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_configA
Retrieve the go2rtc YAML configuration (GET /api/config) with all credentials redacted.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden, and it does add one genuinely useful fact: credentials are redacted, which tells the agent this read is safe to surface. It does not state read-only/non-mutating status, whether the output reflects live state, or any permission requirements beyond the redaction note.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero padding: verb, resource, endpoint, and the most decision-relevant caveat (redaction) all land immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-argument read tool with an output schema, the description covers what is returned at a high level and flags the redaction behavior, so return-value details can be left to the schema. It stops short of stating when this config view is preferable to get_server_info.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is nothing for the description to disambiguate and it does not mislead. No per-parameter meaning is needed or missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Retrieve') and resource ('the go2rtc YAML configuration') and even anchors it to the concrete endpoint `GET /api/config`. It is distinguishable from most siblings, though it does not explicitly contrast with the closest one, get_server_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance and no mention of alternatives such as get_server_info. The only hint of context is the endpoint path, which implies read access but does not help an agent choose between this and its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_server_infoA
Get go2rtc server metadata including version, revision, host, RTSP port, and config path.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Get' implies a safe read, and the enumerated fields give some sense of scope, but it says nothing about auth requirements, side effects, or cost. For a zero-param read tool this is adequate but thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that covers the actor, the resource, and the payload with zero filler. Nothing to trim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values — though it does partially duplicate them. For a no-param read tool this is nearly complete; the only real gap is the absence of any guidance on when to prefer this over get_config.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. The schema is trivially complete at 100% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Get go2rtc server metadata') and enumerates the exact fields returned (version, revision, host, RTSP port, config path). That field list implicitly separates it from siblings like get_config and get_server_logs, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance and no mention of alternatives such as get_config or get_server_logs. The agent is left to infer that this is the lightweight identity/version lookup, which is not stated anywhere.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_server_logsA
Retrieve the most recent limit log entries from go2rtc (GET /api/log), sanitized.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It usefully discloses that output is 'sanitized' (secrets redacted) and that entries are the most recent ones, but says nothing about permissions, retention, ordering guarantees, or volume limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with the action, scope, source, and the sanitization caveat; every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter read tool with an output schema covering return values, the description supplies the essential semantics. Only behavioral details (auth, retention, ordering) are absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter is undocumented in the schema (0% coverage), but the description compensates by explaining that `limit` controls how many of the most recent log entries are returned. It does not mention bounds or the default of 50, which is left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (retrieve) plus resource (log entries) and source endpoint (GET /api/log from go2rtc), so it is clearly distinguishable from get_server_info or get_config. It does not explicitly name siblings, but the resource noun is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this versus alternatives such as get_server_info or get_config, and no preconditions or exclusions. Usage is only inferable from the purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stream_infoA
Get producer and consumer details for a specific stream (stream_name).
Set probe=True to actively query video/audio codecs, SDP, and byte counters.
| Name | Required | Description | Default |
|---|---|---|---|
| probe | No | ||
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It usefully discloses that probe=True performs an 'active' query that fetches codecs, SDP, and byte counters, implying a heavier and possibly side-effecting call than a passive read. It says nothing about permissions, cost/latency of probing, or whether the call is safe/non-mutating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core purpose front-loaded and the optional behavior immediately after. No filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and both parameters are accounted for. The remaining gap is the unresolved relationship to probe_stream, which matters given that sibling's near-identical name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it largely does: stream_name is identified as the target stream and probe=True is explained in terms of what it actually retrieves (codecs, SDP, byte counters). The default value of probe is left to the schema, but the semantic meaning of both parameters is conveyed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get producer and consumer details for a specific stream') plus the key identifier, which cleanly separates it from get_server_info and list_streams. However it does not distinguish itself from the sibling probe_stream, which appears to cover the same probing function, leaving an ambiguity an agent must resolve by guessing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one concrete usage cue: set probe=True to actively query codecs, SDP, and byte counters. That is implied guidance for the parameter rather than when-to-use guidance for the tool. It never says when to call this instead of the sibling probe_stream, or when probe=False (the default) is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stream_snapshotC
Capture a live JPEG snapshot frame from stream_name and return it as an MCP Image.
| Name | Required | Description | Default |
|---|---|---|---|
| width | No | ||
| height | No | ||
| stream_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose the output format ('live JPEG snapshot frame ... as an MCP Image'), which is genuinely useful. However it says nothing about whether the stream must already be running, latency/freshness behavior, failure modes, or permissions, so meaningful behavioral gaps remain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the resource and return type front-loaded and no filler. It is efficient, though it is terse enough that the missing parameter and usage detail had to go somewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations, and two of three parameters are undocumented in both schema and description. The return type is covered, but the resize parameters and any prerequisites for capturing a live frame are missing, which is inadequate for a 3-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for three parameters. The description names `stream_name`, but `width` and `height` — presumably resize dimensions — are never mentioned, so an agent gets no semantic guidance on those two parameters from either source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Capture a live JPEG snapshot frame from `stream_name`') and even names the return type (MCP Image), which clearly separates it from siblings like get_stream_urls or probe_stream. It stops short of explicitly naming an alternative tool, so it is clear but not sibling-differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance, and no mention of how this differs from probe_stream or get_stream_urls for inspecting a stream. The usage is only implied by the verb 'Capture'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stream_urlsB
Generate WebRTC, MSE, HLS (.m3u8), MP4, MJPEG, JPEG snapshot, and RTSP URLs for a stream.
| Name | Required | Description | Default |
|---|---|---|---|
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does usefully disclose the breadth of output formats generated (a behavioral fact not present in the schema), but omits permission/auth requirements, behavior for an unknown stream_name, URL lifetime/expiry, and whether generation is idempotent or read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the verb first and no filler. The protocol enumeration is dense but each item is informative, and nothing is repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and this is a one-parameter read tool. Still, with zero annotations the description should cover auth needs and the failure mode for a nonexistent stream; those gaps leave an agent to guess before invoking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description only implies the parameter via 'for a stream', so it never clarifies whether stream_name is the display name from list_streams or an internal identifier. The single obvious parameter keeps the ambiguity low, but the description does not compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Generate') plus resource ('URLs for a stream') and an enumeration of the supported protocols (WebRTC, MSE, HLS, MP4, MJPEG, JPEG, RTSP) that makes the scope concrete. It is distinguishable from siblings like get_stream_snapshot or get_stream_info by virtue of returning playable URLs, though it never names an alternative to sharpen the contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states what is produced but gives no guidance on when to call it versus get_stream_snapshot (single image), get_stream_info (metadata), or probe_stream. No prerequisites, no mention of whether the stream must already exist or be added via add_stream first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_streamsA
List all configured and active streams on the go2rtc server with credentials redacted.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden, and it does contribute one genuinely useful behavioral fact: credentials are redacted in the output. However, it omits whether authentication is required, ordering/pagination behavior, and whether disabled streams are excluded from "configured and active".
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. Every clause (scope, server, redaction) carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the tool has no parameters. The description is nearly complete for a simple read-only listing, missing only auth/ordering context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline there is nothing for the description to document. Schema coverage is 100% and the description correctly implies no filtering arguments are accepted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (all configured and active streams on the go2rtc server), with the scope word "all" implicitly contrasting with the singular get_stream_info sibling. It is clear what the tool does, but it never explicitly names the sibling that handles the single-stream case.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or alternative-tool guidance. An agent must infer from the name alone that this is the bulk-listing counterpart to get_stream_info; the description never says so.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
probe_streamB
Actively probe a camera stream to inspect its video/audio codecs, SDP, and track stats.
| Name | Required | Description | Default |
|---|---|---|---|
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Actively probe' usefully signals live network activity (and implicitly latency or side effects on the source) rather than a cached read, but it says nothing about authentication needs, timeouts, or rate limits for what is presumably a network-touching operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the verb and target come first and the inspected artifacts follow. The artifact list mildly overlaps with the output schema but is short enough not to waste space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description adequately covers the action. The gaps are the missing routing guidance against get_stream_info and any parameter or auth context for a network-probing operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is exactly one required parameter with 0% schema description coverage, and the description never mentions it. The name 'stream_name' is fairly self-explanatory, but the definition adds no meaning about its format, accepted identifiers, or how it maps to list_streams output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('probe') and resource ('camera stream'), plus the artifacts it inspects (codecs, SDP, track stats), so the agent knows what it gets. It does not explicitly differentiate itself from the close sibling get_stream_info, which is the one ambiguity an agent could stumble on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'Actively' implies an on-demand live inspection as opposed to passively reading cached metadata, which hints at when to prefer it over get_stream_info. However, there is no explicit when-to-use statement, no exclusion, and no named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_streamA
Dynamically update an existing stream on go2rtc (PATCH /api/streams).
Rejects exec:, echo:, and expr: sources unless GO2RTC_ALLOW_EXEC_STREAMS=true.
| Name | Required | Description | Default |
|---|---|---|---|
| source_url | Yes | ||
| stream_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full disclosure burden. It does add one real behavioral fact: exec:/echo:/expr: sources are rejected unless GO2RTC_ALLOW_EXEC_STREAMS=true. However, it omits any mention of auth/permissions and does not clarify whether the update replaces the stream's full source set or merges into it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, purpose front-loaded, constraint second. No filler and nothing wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. Still, for a mutation tool with zero annotations, the description leaves gaps: no auth requirements, no statement of whether unspecified fields are cleared, and only partial coverage of what source_url accepts.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the schema alone explains nothing about the two params. The description partially compensates by constraining valid source_url values (no exec:/echo:/expr:), but stream_name and the replace-vs-merge semantics of source_url remain unaddressed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('update an existing stream') plus the underlying endpoint (PATCH /api/streams), which lets an agent distinguish it from add_stream and delete_stream. It stops short of explicitly naming the sibling boundary (e.g., 'use add_stream to create'), so it is clear but not maximally differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'an existing stream' implies a precondition (the stream must already exist), but there is no explicit when-to-use/when-not guidance or routing to add_stream/delete_stream. The usage context is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.1.1- First observed
add_stream - First observed
delete_stream - First observed
discover_sources - First observed
get_config - First observed
get_server_info - First observed
get_server_logs - First observed
get_stream_info - First observed
get_stream_snapshot - First observed
get_stream_urls - First observed
list_streams - First observed
probe_stream - First observed
update_stream
TDQS
Scored across 12 tools
Most tools have clearly distinct purposes, but get_stream_info (with probe=True) and probe_stream overlap significantly in actively inspecting stream codecs, SDP, and track stats. This one pair could cause occasional misselection, though descriptions help clarify the intended use.
All tool names use snake_case with a consistent verb_noun pattern (e.g., get_server_info, list_streams, add_stream, delete_stream). The convention is predictable and readable throughout, with only minor natural variation like probe_stream vs. get_stream_info.
With 12 tools, the set is well-scoped for managing a go2rtc server: CRUD for streams, inspection, discovery, snapshots, URLs, config, and logs. Each tool earns its place without obvious redundancy or bloat.
The surface covers core stream lifecycle operations, server info, logs, config, discovery, snapshots, and URL generation. Minor gaps exist, such as a server restart or health-check operation, but agents can work around these for most workflows.
Maintenance
Related MCP Connectors
Manage 24/7 live streams, media, playback queues, schedules, and multistreaming from AI assistants.
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Manage SRG+ hubs, channels, content, assets, users, and workspaces from any MCP-aware AI agent.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables interaction with local camera devices to capture and process images. It allows LLMs to access video devices with configurable settings such as resolution, orientation, and image format.1MIT

WAVE MCP Serverofficial
AlicenseAqualityBmaintenanceExposes WAVE streaming APIs as tools for AI assistants to manage live streams, studio productions, and real-time analytics. It enables users to control stream lifecycles, monitor health metrics, and access billing usage through the Model Context Protocol.2411 npm1Apache 2.0- AlicenseNot gradedqualityBmaintenanceEnables AI agents to query and interact with Extra Low Voltage security hardware such as Hikvision and Dahua cameras and NVRs through typed, read-only-by-default MCP tools for device info, channel enumeration, and JPEG snapshot capture. Translates proprietary ISAPI and CGI protocols into safe, auditable calls that any MCP client can use over stdio.MIT
- AlicenseBqualityBmaintenanceEnables AI agents to access an allowlisted set of local Eufy cameras through MediaMTX, providing camera status, single JPEG snapshots, and motion clip listing with frame extraction, without PTZ or cloud APIs.6MIT