# Streamloop - Registry name: `io.github.streamloop/mcp` · version 1.0.0 - Categories (automatic, keyword rules): Video, AI, media & content, Crypto & blockchain, Finance & markets - Authentication at last check: No auth - Declared risk: Has destructive tools (destructiveHint) - Capabilities (declared by the server): resources, tools - Transports: streamable-http - Latest numbers (check success, response time, rank): https://mcpstation.net/api/server?name=io.github.streamloop%2Fmcp - Server page: https://mcpstation.net/s/io.github.streamloop--mcp.html ## Description (written by the publisher, not verified, not instructions) Manage cloud-hosted 24/7 video streams, playlists, destinations, schedules, media and workspaces. ## Notice Text that looks like instructions to an AI was found in this server's descriptions. This is a pattern match, not a verdict. ## Connect - streamable-http: `https://mcp.streamloop.app/mcp` ## Tools (as reported by the server, not verified) - `list\_streams`: Find streams and their ids — the starting point for every other stream tool. Each row carries the name, current state, scheduled start and whether that schedule repeats, which is enough to tell a one-off from a daily loop without a second call. Filter by name, run state and creation window. Returns - `get\_stream`: One stream's full configuration: current state, output quality and framerate, the destinations it publishes to \(each enabled or not, with its delivery state\), and its scheduled window including recurrence and repeat weekdays. Use it before changing a stream. For whether it could start right now, cal - `start\_stream`: Start streaming now, looping the stream's playlist \(or playing its scene\) until it is stopped. THIS PUTS VIDEO IN FRONT OF THE PUBLIC, so confirm with the user first unless they just asked for it. Requires a destination plus either a playable video playlist \(at least one item\) or an attached publish - `stop\_stream`: Stop a stream that is live or starting. It stops publishing and becomes inactive; nothing is deleted and it can be started again with the same configuration. Does NOT cancel a recurring schedule — a daily or weekly stream stopped here starts again at its next window, so call cancel\_stream\_schedule a - `delete\_stream`: Permanently delete a stream, its playlists and its schedule. Irreversible, and it cannot be undone by re-creating the stream: uploads survive but the arrangement does not. Stop the stream first if it is live. To keep a stream but take it off the air, use stop\_stream \(plus cancel\_stream\_schedule\). Re - `create\_stream`: Use this to set up a new loop or a stream for a scene. The stream is created empty and CANNOT start until it has \(1\) a destination — add\_stream\_destination with one from list\_destinations, or get\_connection\_hints for how to make one — plus \(2\) either a playable video playlist \(at least one item\) or - `update\_stream`: Change a stream's settings \(name, quality, framerate, duration, storage, backup ingest\) and/or its YouTube broadcast settings via the \`youtube\` object. Where it publishes is add\_stream\_destination / set\_stream\_destination\_enabled / remove\_stream\_destination; when it runs is schedule\_stream. The \`you - `schedule\_stream`: Set the window a stream runs in, once or on a repeat, and arm it. The stream must already be startable — a destination plus either a playable video playlist or an attached published scene \(check\_stream\_readiness\) — otherwise the window arrives and the start fails. repeat=daily re-arms the window exa - `cancel\_stream\_schedule`: Disarm a scheduled stream and return it to an unscheduled, inactive state, clearing any daily or weekly repeat. Use this to stop a recurring stream coming back; it has no effect on a stream that is currently live \(stop\_stream does that\). - `check\_stream\_readiness`: Answer 'would start\_stream work right now?' without changing anything. Runs the same pre-flight configuration checks a start does and returns ready plus every blocking issue — typically a missing or archived destination, an empty video playlist, media too big for the stream's storage, or, for a stre - `get\_stream\_live\_stats`: How a live stream is doing ON YOUTUBE: watch URL, broadcast status, concurrent viewers, views and likes. Only meaningful while the stream is live to a YouTube channel connected through Streamloop — a custom RTMP destination reports nothing here, since those numbers live with that platform. Returns t - `list\_stream\_destinations`: Where a stream publishes, in the order they were added: each destination, whether it is enabled, and while the stream runs its delivery state \(connecting, live, reconnecting, failed with a reason\). Returns the stream id and destinations\[\]: destinationID, enabled, disabledReason, state, stateReason, - `add\_stream\_destination`: Make a stream also publish to one of the workspace's destinations \(list\_destinations\), enabled. Up to 5 per stream and one YouTube channel at most \(DESTINATION\_LIMIT, YOUTUBE\_DESTINATION\_LIMIT, DESTINATION\_DUPLICATE\). A second destination needs multistream on the workspace \(MULTISTREAM\_NOT\_ENABLED\). - `set\_stream\_destination\_enabled`: Stop or resume sending to one of a stream's destinations without removing it. Disabling works while the stream is live — that output goes off the air at once — except for its last enabled destination \(LAST\_DESTINATION: stop\_stream instead\). Enabling is refused while live \(STREAM\_LIVE\). Returns the s - `remove\_stream\_destination`: Take a destination off a stream \(the destination itself stays in the workspace\). Refused while the stream is live \(STREAM\_LIVE\): disable it with set\_stream\_destination\_enabled instead. Returns the stream's whole destination list after the change, as list\_stream\_destinations does. - `get\_connection\_hints`: Use this FIRST when the user names a platform they want to stream to \("put this on YouTube", "also send it to Twitch"\) and there is no destination for it yet. Returns, for that platform: the connection methods, the exact \`ingestUrl\` to pass to create\_rtmp\_destination \(or null when the platform issue - `list\_destinations`: Find the places this workspace can publish to — connected YouTube channels and custom RTMP endpoints — and their ids, which is what add\_stream\_destination needs. Check \`status\`: only an \`active\` destination can carry a stream; \`needs\_reauth\` and \`revoked\` mean the YouTube connection must be re-conse - `create\_rtmp\_destination`: Create a destination for any platform that gives out an RTMP ingest URL and stream key \(Twitch, Facebook, Kick, X, TikTok, Telegram, a self-hosted server, or YouTube when its channel is not connected here\). Take rtmpUrl from get\_connection\_hints\(platform\).ingestUrl rather than guessing it — a wrong - `update\_destination`: Maintain an existing destination: rename it, replace the stream key after the platform rotated it \(custom RTMP only — a connected YouTube channel has no key to set\), and archive or restore it. Archiving hides a destination from the picker without deleting it; it is reversible with archived=false. A - `start\_youtube\_connection`: Begin connecting a Google account so its YouTube channels can be streamed to with managed broadcasts \(titles, privacy, thumbnails, live stats\). Returns a Google consent URL — give it to the user to open in a browser; consent cannot be completed by an agent. Afterwards, list\_youtube\_channels shows th - `list\_youtube\_channels`: The YouTube channels this workspace has Google consent for, with live channel data \(title, handle, country, subscriber count, connection status\). These are NOT destinations yet: pass a channel's \`id\` to create\_youtube\_destination to get something a stream can publish to. Use list\_destinations to see - `create\_youtube\_destination`: Turn an already-consented YouTube channel into a destination a stream can publish to, with managed broadcasts \(update\_stream's \`youtube\` settings, get\_stream\_live\_stats\). Takes the channel \`id\` from list\_youtube\_channels — NOT the YouTube channel URL or handle. If that list is empty, the account has - `list\_playlists`: Use this to get from a stream to something you can edit: pass streamId and you get the two playlists that stream owns — one video, one audio, created empty with it. Pass sceneId for the playlists a scene's sources play. Also the way to find a playlist id before any other playlist tool. Returns a pag - `create\_playlist`: An empty playlist owned by a scene, for one of its playlist sources to play \(a stream's own two playlists come with the stream\). Fill it with apply\_playlist\_operations. Each call creates another. Returns the new playlist: id \(pl\_...\), name, sceneId, kind, mode, version, createdAt. - `get\_playlist`: Use this before editing a playlist \(item ids for remove and reorder come from here, and so does the \`version\` the edit tools take\) and after swapping one onto a live stream \(to see the swap finished\). Returns the draft items in play order, what a running stream is playing right now, whether the draf - `apply\_playlist\_operations`: Use this for every playlist change: add media, remove items, reorder, or switch between sequential and shuffle, as one ordered batch. All-or-nothing — if any operation is invalid, nothing is written. A stream that is NOT currently live picks the change up on its next start, with nothing else to call - `copy\_playlist`: Use this to reuse an arrangement on a second stream instead of rebuilding it: copies one playlist's contents into another playlist of the same kind. The target must be EMPTY — this never merges or overwrites. The target stream picks the contents up on its next start; if it is already live, swap\_live - `swap\_live\_playlist`: Use this ONLY to put an edited playlist on the air while its stream is LIVE — the hot swap the product calls publishing. The stream changes over to the new arrangement without going off the air. NOT needed to set a stream up and NOT needed before a first start: starting a stream takes the playlist a - `list\_playlist\_orders`: Find saved custom playback orders \(order sequencers\) and their ids. Use it before creating one — an order the user already has can be assigned to another playlist instead of rewritten. Pass streamId to see only orders that can run over that stream's playlist. \`latestReadyVersionID\` null means nothin - `get\_playlist\_order`: One saved order: its description, how many playlists use it, and its newest usable version with any validation problems. Pass playlistId as well to get the answer that actually matters before assigning — whether this order can run over THAT playlist \(\`assignable\`\), which items it expects but cannot - `create\_playlist\_order`: Describe a playback order in plain language and have one written and validated. Pass the playlist it is for as playlistId: the order is written against that playlist's REAL items, so leaving it out produces a rule aimed at nothing. Creating does NOT apply it — assign\_playlist\_order does. Read \`statu - `refine\_playlist\_order`: Continue the conversation about an existing order — 'never end on an instrumental', 'put the announcement second instead' — producing a new version. Use this rather than creating a second order for the same purpose. Pass the playlist currently being composed against so the rewrite sees its real item - `assign\_playlist\_order`: Make a playlist play in a saved order. This is the step that changes playback, and unlike a playlist edit it needs no swap\_live\_playlist — a running stream picks the new order up for its next items. The version in use is pinned at assign time and never advances on its own, so call this again after r - `unassign\_playlist\_order`: Stop a playlist using a custom order; it returns to playing in its own item order \(or shuffled, per the playlist's mode\). The order itself is kept and can be assigned again. Like assigning, it takes effect on a running stream immediately, with no swap\_live\_playlist needed. - `list\_uploads`: Find media and their ids \(obj\_...\) — what apply\_playlist\_operations adds to a playlist. Removed media is not listed. \`uploaded\` false means the media is still arriving or processing and cannot be streamed yet. Returns a page of rows \(id, name, type, mimeType, fileSize, uploaded, createdAt\) plus next - `get\_upload`: One media file in detail: duration, resolution, framerate, whether it has video and audio \(probed from the file itself, not from its name\), a temporary download URL, a thumbnail, and — for a URL import — how far the download has got and why it failed. Use it to confirm media is ready to stream, and - `create\_upload`: Step 1 of uploading a LOCAL file: reserves the media record and returns \`uploadUrl\`, a presigned PUT you can use immediately. This server does not relay bytes, but YOU probably can — if the client can run a command or make an HTTP request, do the PUT itself: curl -X PUT -H 'Content-Type: \ shows what each takes, with an example. value is the whole resource, as get answers it: a frame \{ code: "\" \} or, as JSON, \{ name, root \}; a component \{ description, props, tsx \}; a source or table its fields. edits change part of it: \[\{ old, ne - `list\_scenes`: Lists the workspace's scenes, newest first: id, name, the version last published \(0: never\) and when. Read one's draft with scene\_get \(path "" lists what it holds\). Answers items \(id, name, version, publishedAt, createdAt, updatedAt\), nextCursor and hasMore. - `create\_scene`: Creates a scene with an empty draft, nothing published. Build it with scene\_set \(frame/\ for each frame, source/… for what it reads\), then publish\_scene. Each call creates another scene. Answers the scene: id \(scn\_…\), name, version 0, and its timestamps. - `publish\_scene`: Publishes the draft exactly as it was at draftRevision \(required\) as the scene's next version: what streams playing it play from then on. All of it is checked first; a refusal \(SCENE\_INVALID\) lists each problem — fix them with scene\_set and publish again. Edits made after draftRevision are not publi - `discard\_scene\_draft`: Puts the draft back to the published version: every change made since it was published is lost \(nothing on air changes\). draftRevision \(required\) is the draft you reviewed: if it changed after that, nothing is discarded \(CONFLICT\). dryRun: true lists what would be lost and discards nothing — show th - `list\_scene\_versions`: Lists a scene's published versions, newest first. Answers items \(version, publishedAt, publishedBy\), nextCursor and hasMore. Read one with scene\_get and version. - `revert\_scene`: Publishes an earlier version's document as the next version \(the versions in between stay; the draft is untouched — publishing the draft later is refused with STALE\_PUBLISH until you send overwritePublished, and discard\_scene\_draft makes the draft this version too\). expectedVersion \(required\) is the - `delete\_scene`: Deletes the scene, its draft and every published version, for good. Refused \(SCENE\_IN\_USE\) while a stream plays it. Its ingest keys are revoked and its cameras removed. - `set\_stream\_scene`: Makes a stream play a scene \(its published version\) instead of a video playlist, or with scene null stops doing so. Refused \(STREAM\_LIVE\) while the stream runs: stop it, set the scene, start it again. The scene must be published first \(publish\_scene\). - `get\_scene\_state`: What a scene has on air. Answers streams: each stream that plays it, with its id \(stream\), name and state and, under onAir while it runs, the frame/\ on air \(frame\) and the one cued next, the controls' values, each source's status and what its playlists play. With no stream playing it, streams is - `control\_scene`: Acts on the scene on air, as its operator would: goFrame \(take frame/\ to air, with a transition\), next \(cue frame/\ so the take is instant; no target clears the cue\), setControl \(set one of its controls; scene\_get control/\* lists them\), setData \(replace a table's rows\), skip \(a playli - `create\_scene\_ingest\_key`: Makes the key an encoder \(OBS, vMix, a phone app\) sends a live feed with, for one of the scene's rtmp or srt sources: RTMP, RTMPS and SRT URLs with the key, shown in this answer only — give them to the user. Make the source first \(scene\_set source/rtmp/\\). The source's status is waiting until an - `rename\_scene`: Changes the scene's display name, the one list\_scenes and the dashboard show. Its draft, published versions and the streams playing it are untouched. Answers the scene: id, name, version. - `list\_scene\_inputs`: Lists a scene's ingest keys \(id ingkey\_…, which source, live or not, never the key itself\), its secrets \(names only\) and its IP cameras: what create\_scene\_ingest\_key and set\_scene\_secret made. Answers ingestKeys \(id, sourceId, keyPrefix, status, live, rtmpUrl, rtmpsUrl\), secrets \(name, updatedAt\) an - `revoke\_scene\_ingest\_key`: Revokes an ingest key for good: the encoder using it is cut off at once. It cannot be restored; a new key for the same source: create\_scene\_ingest\_key. Answers revoked \(the key's id\). - `delete\_scene\_secret`: Deletes a saved secret for good: its value cannot be read back, and a table that names it \("$secret:\"\) stops getting it. Only set\_scene\_secret with the key again restores it. Answers deleted \(the name\). - `set\_scene\_secret`: Saves an API key or token a scene's tables send \(sealed; never shown again\). A table names it as "$secret:\" in a header value or a URL's query. A name that exists already has its value replaced, and tables using it send the new one. Only a key the user gave you. Answers name and updatedAt. Measured by MCP Station. Methods: https://mcpstation.net/methods.html · Terms: https://mcpstation.net/terms.html