{"ok":true,"site":{"host":"doctor-webmcp.vercel.app","url":"https://doctor-webmcp.vercel.app/","type":"live","desc":"Room OS: you talk, Brodie does. The dashboard builds itself around your request.","tools":[{"name":"show_stage","kind":"act","impl":"imperative","description":"Reconfigure the dashboard stage for the human — they should never have to click around. When the human asks to do something, call this FIRST to bring up the right surface, then fill it with the other tools. Views: 'home' (welcome screen with suggestion chips), 'watch' (video results + player), 'build' (code editor), 'files' (file browser). Example: 'find me a video about sourdough' → search_videos, show_stage('watch'), display_videos. 'Build me a landing page' → studio_write_file, preview_file. 'Show my files' → show_stage('files'). The page acknowledges every command with a receipt.","inputSchema":{"type":"object","properties":{"view":{"type":"string","description":"Which stage to show: home, watch, build, or files","enum":["home","watch","build","files"]}},"required":["view"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"search_videos","kind":"answer","impl":"imperative","description":"Search all of YouTube by keyword. When the human asks to find or watch something ('find me videos about X', 'show me lofi beats'), search here, then call show_stage('watch') and display_videos so the results pop up on the dashboard — no clicking needed. Pass channel_id to narrow the search to one channel (e.g. 'his videos'). Omit query when channel_id is given to get that channel's latest uploads.","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Search keywords, e.g. 'gut health'. Optional if channel_id is given."},"max_results":{"type":"integer","description":"Max videos to return (1-25)","default":8},"channel_id":{"type":"string","description":"Optional: a YouTube channel id (UC…) to search within"},"order":{"type":"string","description":"'relevance' (default) or 'date' for newest first"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"list_trending_videos","kind":"answer","impl":"imperative","description":"List what's popular on YouTube right now. Pair with show_stage('watch') + display_videos when the human asks what's trending.","inputSchema":{"type":"object","properties":{"max_results":{"type":"integer","description":"Max videos to return (1-25)","default":8}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_video_details","kind":"answer","impl":"imperative","description":"Get full details for one video: title, description, publish date, duration, thumbnail, and watch URL.","inputSchema":{"type":"object","properties":{"video_id":{"type":"string","description":"The YouTube video id"}},"required":["video_id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"display_videos","kind":"act","impl":"imperative","description":"Render video cards onto the dashboard's watch stage so the human can see and tap them. Call show_stage('watch') first if the dashboard isn't on the watch stage, then this — the human never has to navigate.","inputSchema":{"type":"object","properties":{"video_ids":{"type":"array","items":{"type":"string"},"description":"Video ids to display as cards"}},"required":["video_ids"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"play_video","kind":"act","impl":"imperative","description":"Play a video in the dashboard's big player (watch stage appears automatically). Use when the human picks a video or asks to play one — don't autoplay unasked.","inputSchema":{"type":"object","properties":{"video_id":{"type":"string","description":"The YouTube video id to play"}},"required":["video_id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"dock_video","kind":"act","impl":"imperative","description":"Park a video in the docked mini player so it keeps playing while the human works on the build stage. Use when they ask to keep something playing in the background ('dock some lofi while I work').","inputSchema":{"type":"object","properties":{"video_id":{"type":"string","description":"The YouTube video id to dock"}},"required":["video_id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"open_file","kind":"act","impl":"imperative","description":"Open a studio file in the dashboard's editor — the build stage pops up automatically with the file loaded. For HTML files you just wrote, prefer preview_file so the human sees the result immediately.","inputSchema":{"type":"object","properties":{"path":{"type":"string","description":"File path in the studio tree, e.g. 'index.html' or 'skills/my-skill/SKILL.md'"}},"required":["path"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"preview_file","kind":"act","impl":"imperative","description":"Open a studio file AND show its rendered preview immediately — the last click, finished for the human. Always call this (not open_file) right after studio_write_file on an .html file, so what you built appears in front of them with zero clicks.","inputSchema":{"type":"object","properties":{"path":{"type":"string","description":"HTML file path in the studio tree, e.g. 'index.html'"}},"required":["path"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"studio_list_files","kind":"act","impl":"imperative","description":"List every file in the studio: files, skills, and plugins.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"studio_read_file","kind":"act","impl":"imperative","description":"Read a file from the studio by path (e.g. 'skills/example/SKILL.md').","inputSchema":{"type":"object","properties":{"path":{"type":"string","description":"File path in the studio"}},"required":["path"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"studio_write_file","kind":"act","impl":"imperative","description":"Create or overwrite a file in the studio. This is how you build with the human: when they ask for something ('build me a landing page', 'add a notes file'), write it here, then call preview_file (for .html) or open_file so it appears in front of them with zero clicks. The Files stage picks it up instantly.","inputSchema":{"type":"object","properties":{"path":{"type":"string","description":"File path, e.g. 'notes/todo.md' or 'skills/my-skill/SKILL.md'"},"content":{"type":"string","description":"Full file content"}},"required":["path","content"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"studio_delete_file","kind":"transact","impl":"imperative","description":"Delete a file from the studio by path. Use when the human asks to remove something ('delete that draft', 'remove notes/todo.md'). The file tree refreshes instantly.","inputSchema":{"type":"object","properties":{"path":{"type":"string","description":"File path in the studio to delete"}},"required":["path"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"announce","kind":"act","impl":"imperative","description":"Show a short activity banner on the dashboard stage itself ('writing index.html…', 'pulling up trending videos…') so the human sees your hand moving the room — the stage narrates, not just the chat. Keep it under 8 words.","inputSchema":{"type":"object","properties":{"text":{"type":"string","description":"Banner text, e.g. 'pulling up trending videos…'"}},"required":["text"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"read_messages","kind":"answer","impl":"imperative","description":"Read the latest messages in the shared room chat — THIS is how you see what the human typed in the command bar. Poll it to wait for new messages, then compose the dashboard. To drive the stage from outside this browser, POST to /api/stage/command instead — you get a synchronous ack, and the page posts a kind:'action' receipt card when it executes.","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","description":"How many recent messages to return (1-50)","default":20}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"send_message","kind":"transact","impl":"imperative","description":"Post into the shared room chat as the agent. The human sees it in the agent thread (avatar pulses, toast appears if the thread is closed) — this is how you talk back while you work the dashboard. For driving the stage itself, prefer the dedicated tools or POST /api/stage/command over chat.","inputSchema":{"type":"object","properties":{"text":{"type":"string","description":"The message text"},"name":{"type":"string","description":"Display name to post as","default":"Brodie"},"kind":{"type":"string","description":"'chat' for a normal message, 'result' to attach video cards","default":"chat"},"video_ids":{"type":"array","items":{"type":"string"},"description":"Video ids to attach as watch cards (kind='result')"}},"required":["text"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"AI & Agents","apiSurface":"spec","toolCount":16}}