# unwatched-mcp **Video URL in → validated runbook out.** MCP server + CLI for [UNWATCHED](https://unwatched.cloud). Any AI agent (Claude Code, Cursor, any MCP client) can decode a video into a validated, structured runbook by calling the UNWATCHED API. Requires Node.js ≥ 18 and an API key from **https://unwatched.cloud/app/settings → API Keys**. ## 60-second quickstart ```bash # 1. Install npm i -g unwatched-mcp # or use npx below without installing # 2. Set your key export UNWATCHED_API_KEY=uk_live_... # or: ~/.config/unwatched/config # 3. Decode a video (starts the job, waits, writes the runbook) unwatched decode "https://www.youtube.com/watch?v=VIDEO_ID" --format yaml -o runbook.yaml ``` That's it: `runbook.yaml` now holds the validated runbook. ## CLI ``` unwatched decode [--profile agent] [--format md|yaml|json] [-o file] [--timeout 600] unwatched library [query] [--json] unwatched status [--wait] [--timeout 600] ``` - `decode` starts a job, polls until it completes, fetches the runbook and writes it to `-o ` (or stdout). - `library` lists your tenant's previous decodes; `query` filters client-side. - `status` shows job status + artifact list. ### API key resolution 1. `UNWATCHED_API_KEY` environment variable 2. `~/.config/unwatched/config` — a file containing either `UNWATCHED_API_KEY=uk_live_...` or the bare key on one line `UNWATCHED_BASE_URL` overrides the API base URL (default `https://unwatched.cloud/api/v1`). ## MCP server The package ships an MCP server (stdio transport) with these tools: | Tool | What it does | |---|---| | `decode_video(url, profiles?)` | start a decode job → returns `job_id` | | `get_job(job_id)` | status + artifact list | | `get_runbook(job_id, video_id, format: md\|yaml\|json)` | runbook content | | `list_library(query?)` | previous decodes of your tenant | | `wait_for_job(job_id, timeout_s=600)` | poll until completed/partial/failed | Typical agent flow: `decode_video` → `wait_for_job` → `get_job` (find the `video_id`) → `get_runbook`. Errors are mapped to actionable messages: `401` → check your API key, `402` → quota exhausted, upgrade at https://unwatched.cloud/app/settings, `429` → rate limited (respects `Retry-After`). ### Claude Code ```bash claude mcp add unwatched --env UNWATCHED_API_KEY=uk_live_... -- npx -y unwatched-mcp ``` ### Claude Desktop Add to `claude_desktop_config.json`: ```json { "mcpServers": { "unwatched": { "command": "npx", "args": ["-y", "unwatched-mcp"], "env": { "UNWATCHED_API_KEY": "uk_live_..." } } } } ``` ### Cursor Add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global): ```json { "mcpServers": { "unwatched": { "command": "npx", "args": ["-y", "unwatched-mcp"], "env": { "UNWATCHED_API_KEY": "uk_live_..." } } } } ``` ### Any other MCP client Run the server directly over stdio: ```bash UNWATCHED_API_KEY=uk_live_... npx -y unwatched-mcp # or, when installed globally: unwatched-mcp ``` ## Development ```bash npm install npm run build npm test # smoke tests of the API client with mocked HTTP ``` Layout: `src/api-client.ts` (REST wrapper + error mapping), `src/cli.ts` (commander CLI), `src/mcp-server.ts` (stdio MCP server), `src/config.ts` (key/base-URL resolution). ## License MIT