Streamfog MCP
# Streamfog MCP
<p align="center">
<a href="https://github.com/casey/just"><img src="https://img.shields.io/badge/just-ready_to_go-7c5cfc?style=flat-square&logo=just&logoColor=white" alt="Just"></a>
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff"></a>
<a href="https://python.org"><img src="https://img.shields.io/badge/Python-3.12+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python"></a>
<a href="https://biomejs.dev"><img src="https://img.shields.io/badge/Linted_with-Biome-60a5fa?style=flat-square&logo=biome&logoColor=white" alt="Biome"></a>
<a href="https://github.com/PrefectHQ/fastmcp"><img src="https://img.shields.io/badge/FastMCP-3.4-7c5cfc?style=flat-square" alt="FastMCP"></a>
</p>
> π **[Installation Guide](INSTALL.md)** β quick start, manual setup, and troubleshooting
> π **[Docs](docs/)** β [Configuration](docs/CONFIGURATION.md) Β· [Tools](docs/TOOLS.md) Β· [Troubleshooting](docs/TROUBLESHOOTING.md) Β· [Development](docs/DEVELOPMENT.md)
> π€ **[llms-full.txt](llms-full.txt)** β full LLM-readable documentation
**AI-driven AR lens orchestrator for live OBS streams.** Control Streamfog face filters, AR effects, and Vtuber avatars through MCP tools via the local Streamer.bot WebSocket bridge. Your AI assistant becomes a stream producer.
## What is Streamfog?
**Streamfog** is a Windows desktop app (https://streamfog.com) that streamers
use to put AR effects on their face during live broadcasts β face filters
("beauty smooth", "cyber helmet"), animated lenses, background effects, and
Vtuber-style avatars. It takes your webcam feed, applies the effect in real
time, and renders the result into OBS Studio through a browser source.
Two things matter for automation:
1. **Streamfog has no public API, CLI, or plugin SDK.** You cannot script it
directly, and it cannot tell you which lens is active. It is effectively
a black box that only listens to Streamer.bot.
2. **Streamer.bot is the remote control.** [Streamer.bot](https://streamer.bot)
is a free automation tool for streamers. Streamfog registers itself with
Streamer.bot as an integration, and Streamer.bot exposes a local
WebSocket server that accepts `DoAction` commands by name (e.g. fire the
action `SetLens_BeautySmooth`).
**This project is the bridge between the two**: it gives an AI assistant (or
the dashboard, or any script) a clean tool interface β `streamfog_set_lens`,
`streamfog_clear_effects`, `streamfog_toggle_avatar`, `streamfog_status`,
`streamfog_list_lenses` β and translates each call into a Streamer.bot
`DoAction` dispatch. Without this server you would have to open Streamer.bot
and click actions manually; with it, your agent becomes a stream producer.
> β οΈ **Fire-and-forget**: Streamer.bot does not report whether an action
> succeeded, and Streamfog cannot be queried. A tool returning "success"
> means *dispatched*, not *applied* β confirm visually on the stream.
| | |
|--:|--|
| **You might use this ifβ¦** | You want your AI to switch AR lenses, toggle Vtuber avatars, or clear effects during live OBS broadcasts β controlled by Twitch chat events, channel points, or agentic automation. |
| **What it connects to** | [Streamfog](https://streamfog.com) desktop app β [Streamer.bot](https://streamer.bot) WebSocket β this MCP server |
| **Ports** | Backend **10994**, Dashboard **10995** |
| **Start** | `just bootstrap` then `start.ps1` |
## How to use this server (3 steps)
1. **Install the two external apps** (one-time): Streamfog + Streamer.bot,
enable Streamfog's integration inside Streamer.bot, and enable
Streamer.bot's WebSocket server on port 8080. Full walkthrough:
[docs/ONBOARDING.md](docs/ONBOARDING.md).
2. **Map your lenses**: create `lenses.json` linking human-readable lens
names to the exact Streamer.bot action names that apply them (see
[Lens Map](#lens-map-lensesjson)).
3. **Start and drive it**: `start.ps1` boots the backend + dashboard; then
either connect your MCP client (Claude Desktop / Cursor / opencode) over
stdio or `http://127.0.0.1:10994/mcp`, click lenses on the dashboard, or
call the REST API from scripts. All three surface the same bridge.
## Architecture
Plain English: **your AI talks to this server, this server talks to
Streamer.bot, Streamer.bot tells Streamfog what to render, and OBS shows the
result.** Every hop is local.
```
βββββββββββββββ MCP ββββββββββββββββββββ WebSocket ββββββββββββββββ
β LLM Agent β ββββββββββββββββ β streamfog-mcp β βββββββββββββββββ β Streamer.bot β
β (Claude, β ββββββββββββββββ β :10994 (FastMCP) β βββββββββββββββββ β :8080 β
β Gemini) β stdio / /mcp β :10995 (React) β DoAction JSON β β
βββββββββββββββ ββββββββββββββββββββ ββββββββ¬βββββββββ
β Native Hook
ββββββββΌβββββββββ
β Streamfog β
β Desktop App β
ββββββββ¬βββββββββ
β Browser Source
ββββββββΌβββββββββ
β OBS Studio β
βββββββββββββββββ
```
- **MCP tools** (for AI agents): served over stdio or the streamable HTTP
endpoint at `http://127.0.0.1:10994/mcp`.
- **REST API** (for scripts + dashboard): `/api/*` on the same port, backed
by the same bridge instance.
- **Dashboard** (for humans): React SPA at `:10995` β lens grid, status
KPIs, chat, logs.
The MCP endpoint is served at `http://127.0.0.1:10994/mcp` (streamable HTTP)
in dual mode, alongside the REST API and dashboard.
## Quick Start
```powershell
uv sync
# Edit lenses.json with your Streamer.bot action names
# Set STREAMFOG_MCP_STREAMERBOT_TOKEN in .env if using auth
.\start.ps1
```
MCP-only via stdio (for Cursor, Claude Desktop):
```powershell
uv run -m streamfog_mcp --stdio
```
## Prerequisites
1. [Streamfog](https://streamfog.com) installed and running
2. [Streamer.bot](https://streamer.bot) installed and running
3. Streamfog β Streamer.bot integration enabled in Streamfog's Integrations panel
4. Streamer.bot WebSocket server enabled (Settings β WebSocket Server)
5. Actions created in Streamer.bot (e.g. `SetLens_BeautySmooth`, `ClearEffects`, `ToggleAvatar`)
6. `lenses.json` populated with your actionβlens mappings
See [docs/ONBOARDING.md](docs/ONBOARDING.md) for the step-by-step walkthrough.
## Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `STREAMFOG_MCP_STREAMERBOT_HOST` | `127.0.0.1` | Streamer.bot WebSocket host |
| `STREAMFOG_MCP_STREAMERBOT_PORT` | `8080` | Streamer.bot WebSocket port |
| `STREAMFOG_MCP_STREAMERBOT_TOKEN` | β | Streamer.bot auth token |
| `STREAMFOG_MCP_LENS_MAP_PATH` | `lenses.json` | Path to lensβaction mapping file |
| `STREAMFOG_MCP_PORT` | `10994` | Backend port |
| `STREAMFOG_MCP_LOG_LEVEL` | `INFO` | Logging level |
## Lens Map (`lenses.json`)
```json
{
"beauty_smooth": "SetLens_BeautySmooth",
"cyber_helmet": "SetLens_CyberHelmet",
"vtuber_avatar": "SetLens_VTuberAvatar"
}
```
Keys are human-readable lens identifiers used in MCP tool calls. Values are the corresponding Streamer.bot action names. Keys starting with `_` are ignored; unknown identifiers fall back to the action `SetLens_{identifier}`.
## MCP Tools (5)
### Lens Control
| Tool | Description |
|------|-------------|
| `streamfog_set_lens` | Activate a specific AR lens or face filter |
| `streamfog_clear_effects` | Strip all effects, return camera to baseline |
| `streamfog_toggle_avatar` | Toggle Vtuber-style avatar on/off |
### Discovery β READ_ONLY
| Tool | Description |
|------|-------------|
| `streamfog_list_lenses` | List all configured lenses from lenses.json |
| `streamfog_status` | Bridge connection health + lens count |
## REST API
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/health` | GET | Liveness probe (status, version, uptime, tool count, bridge) |
| `/api/v1/status` | GET | Server + bridge health |
| `/api/v1/lenses` | GET | List all lenses |
| `/api/v1/lenses/set` | POST | Activate a lens (`{"lens_identifier": "beauty_smooth"}`) |
| `/api/v1/lenses/reload` | POST | Reload lens map from disk |
| `/api/v1/effects/clear` | POST | Clear all effects |
| `/api/v1/avatar/toggle` | POST | Toggle avatar |
| `/api/tools` | GET | Dynamic MCP tool list with schemas |
| `/api/capabilities` | GET | Capability discovery |
| `/api/skills` | GET | Skill list |
| `/api/skills/{name}` | GET | Skill content (markdown) |
| `/api/llm/discover` | GET | Local LLM provider probe (Ollama/LM Studio/vLLM) + GPU |
| `/api/logs` | GET | Ring-buffer log window |
| `/api/v1/diagnostics` | GET | Tool list, system info, errors |
## Web Dashboard
Dark SOTA dashboard at `:10995` (React + Vite + Tailwind + Zustand):
- **Dashboard** β hero + KPI cards (server, tools, bridge, uptime), lens grid, quick actions, exponential-backoff health
- **Tools** β dynamic tool list with schemas from `/api/tools`
- **Chat** β skill-first local LLM chat (Ollama/LM Studio/vLLM), 4 personalities, localStorage history, export
- **Settings** β backend health + LLM provider detection
- **Help** β architecture, env reference, troubleshooting
- **Logs** β live ring-buffer modal (Ctrl+L)
Keyboard: Ctrl+Scroll zoom, Ctrl+0 reset, Ctrl+L logs.
## Project Structure
```
streamfog-mcp/
βββ src/streamfog_mcp/
β βββ _mcp.py FastMCP singleton + resources
β βββ server.py FastAPI gateway (REST + /mcp mount)
β βββ __main__.py CLI entry (--stdio / --serve)
β βββ config.py Pydantic settings (STREAMFOG_MCP_ prefix)
β βββ errors.py _error_response() with logger.exception
β βββ logging_ring.py Ring buffer for /api/logs
β βββ skills/streamfog/ SKILL.md (chat preprompt)
β βββ tools/core_tools.py 5 @mcp.tool() decorators
β βββ services/streamerbot.py Streamer.bot WebSocket client
βββ webapp/ Vite + React 19 + Tailwind + Zustand
βββ native/ Tauri 2.0 desktop wrapper
βββ lenses.json Lens β action mapping
βββ pyproject.toml / uv.lock
βββ start.ps1 / start.bat
βββ justfile
βββ tests/ 13 tests (units + endpoint + e2e)
```
## Verification
```powershell
just lint # ruff
just test # pytest (coverage-gated)
uv run pyright src/ # types
cd webapp && bun run check && bun run biome:ci
cd webapp && bunx playwright test # e2e
```
## Known Limitations
- Streamfog does not expose a native CLI or local API β all control goes through Streamer.bot
- Lens activation is fire-and-forget (Streamer.bot does not report success/failure for actions)
- No lens preview or thumbnail retrieval (Streamfog desktop is a black box)
- Lumia/Crowd Control bridge path is documented but not yet implemented as an alternative transport
TDQS
Scored across 5 tools
Each tool targets a distinct operation: status checks connectivity, set_lens activates a specific lens, clear_effects removes all effects, toggle_avatar toggles the avatar overlay, and list_lenses enumerates available lenses. There is no functional overlap.
All tool names follow a consistent streamfog_verb_noun pattern using snake_case. Verbs are descriptive and uniform, making it easy to predict tool behavior from the name.
Five tools is well-scoped for an AR lens management server. Each tool serves a core function: status, set lens, clear effects, toggle avatar, and list lenses, without unnecessary duplication.
The tool set covers essential operations for managing AR lenses, including status checking, activation, clearing, avatar toggling, and listing. A minor gap is the lack of a tool to get the currently active lens or avatar state, though status provides bridge health.