Watch Buddy
FreeNot checkedAn MCP server that gives Claude the ability to watch any desktop window, detecting changes and providing compact image bundles for Claude's vision, enabling rea
About
An MCP server that gives Claude the ability to watch any desktop window, detecting changes and providing compact image bundles for Claude's vision, enabling real-time screen-watching without API costs.
README
Give your Claude eyes. Watch Twitch, games, and code streams together — with zero API costs.
Watch Buddy is an MCP server that turns Claude Desktop (or Claude Code) into a screen-watching companion. It captures any window on your desktop, detects what actually changed, and hands Claude compact image bundles that Claude reads with its own vision — on your existing subscription. No API key. No per-token billing. Ever.
(That zero-API promise covers the eyes. The optional ears — desktop-audio transcription — are the one feature that uses an external API: a Whisper endpoint of your choosing. Skip the key and the ears simply stay off; vision is unaffected. Details below.)
"Claude Desktop is the brain. Watch Buddy is the eyes and memory."
What it feels like
You: What do I have open?
Claude: → list_windows() "I can see Discord, Chrome, VS Code..."
You: Watch my Twitch tab
Claude: → attach_to_window("Twitch") "Attached — I can see the stream."
You: What's the streamer doing?
Claude: → get_next_bundle() reads the frames with its own vision
"He's refactoring the auth module — and chat is roasting his
variable names. Someone just asked if he's coding manually in 2026."
You: (an hour later) What was he building again?
Claude: → search_memory("building") "Foodies — a .NET 8 + React recipe app."
A friend on the couch who looks up at the good parts — not a security camera invoicing you per frame.
Why it's cheap: the delta engine
Naive screen-watching ships full screenshots on a timer and melts your usage limits. Watch Buddy is built around three efficiency layers:
- Delta detection (OpenCV) — each frame is diffed against the last; only changed regions are cropped and encoded. A static page costs almost nothing; a webcam in the corner costs a postage stamp, not a page.
- Zone caching — the screen is divided into named zones (scaled
automatically to your actual window size); zones whose content hasn't
changed are marked
cachedand never re-sent. - Bundle hygiene — perceptual dedup guarantees no near-identical image ships twice in one bundle, and full-frame fallback thumbnails are capped at one per bundle.
- The Delta Atlas (v1.1) — when several regions change, their crops are
packed into ONE gutter-separated mosaic with a coordinate legend, so the
canvas area Claude pays for is roughly the sum of the changes, not one
image per change. As close to "send only the pixels that moved" as a
vision model's rectangle-shaped appetite allows. Optional content-aware
downscaling (
crop_downscale, default off) shrinks large photographic crops while never touching text zones like chat — because nobody should have to read blurry text, silicon included.
And the biggest lever of all: pull, not push. Capture runs locally at
10fps for free — Claude only sees frames when it calls get_next_bundle(),
i.e., when you're actually talking. Cost scales with how often you chat, not
how long you watch.
Ears 👂 (v1.2) — optional, and the one feature that uses an API
Watch Buddy can also hear — and pair what it hears with what it sees. Unlike vision (which runs entirely on your Claude subscription), the ears send audio to a speech-to-text API, so they need a key. They are fully optional: no key, no audio device, or no network, and the ears simply report themselves disabled — the eyes never notice.
How the hearing works, end to end:
- Capture — Windows WASAPI loopback: the stream taps what your speakers play, and the microphone is never opened. Household noise around your desk cannot enter the transcript, by construction — the same mechanism OBS uses for "Desktop Audio."
- Silence gate (local, free) — audio is chunked (~12s) and RMS-checked on your machine; silent chunks are discarded without any network call. You only pay to transcribe actual speech.
- Transcription — speech chunks go to a Whisper-style endpoint
(default: Whisper large-v3-turbo via AudioDojo on Chutes).
Put your key in a
.envnext to the module (CHUTES_API_KEY=...) or the environment. Any endpoint accepting{audio_b64, language}and returning{text}works — configurable viaconfig.json→ears.endpoint. - Rolling transcript — timestamped lines are kept in memory (default
4 hours,
ears.keep_minutes) and appended to a permanent per-day log intranscripts/(gitignored) — your own captions archive for streams that never offered CC. - Delivery cursor (exactly-once) — every
get_next_bundle()carriestranscript_since_last_look: precisely the dialogue between Claude's previous glance and this one. Frequent glances → short snippets, never duplicated; a 40-minute gap → all 40 minutes, delivered once. Sight samples; sound is continuous; nothing is missed and nothing is re-read.
get_transcript(seconds) fetches any window on demand (a peek — it never
moves the delivery cursor), and set_ears(bool) toggles the whole feature
at runtime, persisted to config. Default is on when a key is present.
The tools
| Tool | What it does |
|---|---|
list_windows() |
Enumerate every open window |
attach_to_window(title) |
Fuzzy-match a window, start the capture pipeline |
get_next_bundle() |
The main event: metadata + changed-region images for Claude's vision |
log_observation(text, tags) |
Claude records what it saw (SQLite memory) |
get_recent_observations(n) |
Recall recent context |
search_memory(query) |
Search everything ever observed |
set_persona(text) |
Change the companion's personality |
get_transcript(seconds) |
The ears: desktop-audio transcript for the last N seconds |
set_ears(enabled) |
Toggle audio transcription at runtime (persists to config) |
get_status() |
Pipeline health, bundles produced, vision-token usage, ear status |
detach() |
Stop watching (and listening), close the session |
The memory layer means your companion remembers the stream — across the whole session and across sessions (it's a SQLite file).
Install
Requirements: Windows (window enumeration uses win32), Python 3.10+.
git clone https://github.com/jpetree331/mcp-watch-buddy.git
cd mcp-watch-buddy
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install "mcp[cli]" pyautogui Pillow opencv-python pywin32 mss python-dotenv
Verify (its own test suite):
.\.venv\Scripts\python.exe test_server_v2.py
.\.venv\Scripts\python.exe test_efficiency_v3.py
Register with Claude Desktop — add to %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"watch-buddy": {
"command": "C:\\path\\to\\mcp-watch-buddy\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\mcp-watch-buddy\\main.py"]
}
}
}
Or with Claude Code — add the same entry to the mcpServers block of
~/.claude.json (user scope), with "type": "stdio".
Restart the app. Ask Claude "list your watch-buddy tools" — if it can see
list_windows, you're live.
Install tip learned the hard way: always point
commandat the venv'spython.exe, not barepython— and if you move the folder later, update the path. This project spent four months presumed dead because its folder got reorganized out from under its config. The code was fine the whole time.
Config
config.json — everything optional:
{
"persona": "curious, dry-humored, observant",
"fps": 10,
"bundle_interval_seconds": 1,
"change_threshold": 25,
"min_contour_area": 500,
"screen_zones": {
"gameplay": {"x": 0, "y": 0, "width": 1000, "height": 680},
"chat": {"x": 1000, "y": 0, "width": 280, "height": 720},
"hud": {"x": 0, "y": 680, "width": 1000, "height": 40}
}
}
Zones are authored in a design space and scaled automatically to whatever window you attach — customize them for your favorite layout (stream + chat rail, IDE + terminal, etc.) or delete them for plain full-frame diffing.
Privacy & safety
- 100% local: frames go from your screen to your Claude session — nowhere else.
- Nothing is written to disk except the SQLite observation log (text only). Images live in RAM in a rolling one-second window and are never saved.
- Capture only runs while attached;
detach()stops it completely.
Limitations
- Windows-only (win32 window finding; PRs welcome for macOS/Linux).
- Small text (e.g., IDE code on a busy stream) reads best if you fullscreen the player — vision resolution is capture resolution.
- Minimized windows produce blank frames; the pipeline pauses until restored.
Provenance
Designed by Jess (architecture, delta/batching concept) and built, debugged, resurrected, and field-tested by several generations of Claude — the original build reports live in debug_report.md and debug_report_v2.md, and the efficiency fixes in test_efficiency_v3.py came from its first real afternoon of watching Twitch. Its first-ever logged observation was a 1-viewer coding stream. Go bless a small streamer. 💜
Installing Watch Buddy
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/jpetree331/mcp-watch-buddyFAQ
Is Watch Buddy MCP free?
Yes, Watch Buddy MCP is free — one-click install via Unyly at no cost.
Does Watch Buddy need an API key?
No, Watch Buddy runs without API keys or environment variables.
Is Watch Buddy hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Watch Buddy in Claude Desktop, Claude Code or Cursor?
Open Watch Buddy on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Omni Video
An MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/
by buildwithtazaARA
Generate images, video and audio from any AI agent — one connector.
by ARAYouTube
Transcripts, channel stats, search
by YouTubeEverArt
AI image generation using various models.
by modelcontextprotocolCompare Watch Buddy with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All media MCPs
