~ $ msm
Set up a Twitch stream and a YouTube broadcast from one form, then press Start Streaming in OBS.
msm is a terminal interface that configures a Twitch stream and a YouTube live broadcast from a single form, then shows the live figures for both platforms side by side. It never touches OBS, and your YouTube stream key stays exactly where it is.
the problem
If you stream to both platforms at once — for example through OBS with the Aitum multistream plugin — the routine before every session is the same:
- Open YouTube Studio. Create a live broadcast. Type the title and description, pick a category, set the visibility, tick “not made for kids”.
- Open the Twitch dashboard. Type the same title again, search for the category, retype the same tags, set the language.
- Find a stream key and get it into OBS or Aitum.
- Finally, press Start Streaming in OBS.
msm collapses steps 1 to 3 into one form. You type the title, description, tags, category and language once, press Ctrl+G, and both platforms are configured in parallel. Step 4 does not change: this tool never controls OBS.
install
The one-liner downloads the latest release binary and puts it on your PATH:
curl -fsSL https://raw.githubusercontent.com/worxbend/multistream-manager/main/install.sh | sh
Prebuilt binaries are Linux x86_64 and aarch64. On macOS and Windows, build from source with cargo install --path . — that needs Rust 1.88 or newer. Either way you end up with a binary called msm; run msm --help to check it.
what you get
-
One form, both platforms
Title, description, tags, category and language are typed once and pushed to Twitch and YouTube at the same time.
-
Your YouTube key stays put
Each new broadcast binds to a stream that already exists on your channel, so OBS and Aitum keep the key you gave them.
-
Both dashboards in one window
Viewers, uptime and subscribers for both platforms; followers on Twitch, likes on YouTube, refreshed while you stream. Neither website needs to be open.
-
Partial success is normal
If one platform fails, the other still goes ahead. The panels say which worked, which did not, and why.
-
Twitch categories, resolved
The category field autocompletes as you type and turns the name into the numeric game id Twitch's API requires.
-
Scriptable when you want it
Your config file doubles as an editable preset.
msm goapplies it without opening the interface;msm go --jsonprints one object per platform.
how it works
-
Choose the platforms
Tick Twitch, YouTube or both. Anything you do not tick is left alone, and each platform is logged in separately over a loopback OAuth flow with PKCE.
-
Fill in one form
Title, description, tags, category and language, plus the two settings only YouTube has: visibility, and whether it should go live by itself once it sees the feed.
-
Press Ctrl+G
Twitch has no separate “create broadcast” step, so its channel is updated in place. On YouTube a broadcast is created and bound to your existing stream, then tags, category and language are applied to the underlying video.
-
Press Start Streaming in OBS
Exactly as you always did, with Aitum sending the second copy to YouTube. msm reads statistics from both platforms from then on.
the stream key
Why your YouTube stream key never changes
This is the part that makes the whole thing work, so it is worth spelling out. YouTube's API keeps two separate objects: a broadcast is the event, with a title and a watch page; a stream is the RTMP pipe that carries the video, and it is the thing that holds the key.
Creating a new stream object mints a brand new key. A tool that created one per session would hand you a different key every time, and you would be pasting it into Aitum before every stream — the exact chore this is meant to remove.
So msm reuses a stream that is already on your channel and binds the new broadcast to that one. YouTube's list endpoint does not report whether a given stream can be reused, so msm binds the candidate and only falls back to creating a fresh stream if the bind is refused. When that happens it says so plainly, because a new key is the one thing you have to act on.
If your channel has several keys, msm streams lists them and stream_id in the config pins the one you want.
commands
Running msm with no arguments opens the interface, which is how it is meant to be used. The subcommands cover the things a terminal interface is bad at: one-off logins, scripted go-lives, and printing a key.
- msm
- Open the terminal interface. This is the default.
- msm tui
- The same thing, spelled out.
- msm login <twitch|youtube|all>
- Authorise a platform in your browser.
- msm logout <twitch|youtube|all>
- Forget a platform's saved login.
- msm status
- Show which platforms are logged in and where the config lives.
- msm go [--platforms <LIST>] [-y|--yes] [--json]
- Apply the preset from your config file without opening the interface.
--jsonimplies--yesand never prints the stream key. - msm key <twitch|youtube>
- Print a platform's stream key, for pasting into OBS or Aitum.
- msm categories <QUERY>
- Search Twitch's category list from the command line.
- msm streams [--show-keys]
- List the stream keys on your YouTube channel, and which one is pinned.
- msm cleanup [-y|--yes]
- Find YouTube broadcasts that were created but never went live. Anything that ever received a feed is never listed and never deleted.
- msm init
- Write a commented starter config file.
- msm paths
- Show where the config, token and log files live.
-c, --config <FILE> works on every subcommand, so you can keep one preset per kind of stream.