mcp-xtream
Saves downloaded catchup programmes with Jellyfin-compatible naming (e.g. 'Show/Season 02/Show - S02E05 - Title.mkv' or air-date naming) and writes matching .nfo metadata files, so recordings drop straight into a Jellyfin library.
Downloads past programmes from an IPTV provider's catchup archive and names them for a Plex library (show/season/episode or date-based naming) so they can be picked up and indexed by Plex.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-xtreamDownload last night's Gogglebox for my Jellyfin library"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-xtream
An MCP server for Xtream Codes IPTV subscriptions. It lets an AI assistant search your provider's TV guide and download past programmes from its catchup archive, saved ready for Jellyfin or Plex.
You: Download Sunday Politics from this morning, BBC One NI.
Assistant: Found it: Sunday Politics, 10:00–10:30 on IRL: BBC ONE NORTHERN 4K (catchup available). Downloading in the background… done:
~/Movies/IPTV/Sunday Politics/Sunday Politics - 2026-10-18.mkv(1.3 GB, 29:44).
Other things to ask:
"Is there any snooker in the last three days?"
"What's on RTÉ One tonight?"
"Get last night's Gogglebox for my Jellyfin library."
"How long is left on my IPTV subscription?"
Features
Guide search across thousands of channels, past and upcoming, with every channel carrying a programme and whether it can still be downloaded.
Background catchup downloads that keep going after the chat ends, resume dropped connections from the exact byte, and convert to
.mkv(no re-encode, keeps subtitles) whenffmpegis installed.Jellyfin/Plex naming (
Show/Season 02/Show - S02E05.mkvplus an.nfofile) when the assistant has identified the episode, or date-based naming when it hasn't.Handles provider quirks: catchup times in the server's own timezone, "+1" channels that reuse the main channel's guide, duplicated or overlapping guide entries, and guides that only reach a day back (past programmes are kept for 7 days so the whole catchup window stays searchable).
Tells you when a download is done: clients that support server-push events get a
download_finished/download_failednotification instead of having to poll.Respects your connection limit: won't start a download while all of your account's connections are in use (e.g. you're watching TV).
Keeps your password private: stream URLs contain it, so no tool ever returns one, and errors never include it.
Related MCP server: XMLTV MCP Server
Quick start
You need uv.
uvx downloads and runs the server in an isolated environment, fetching
Python 3.13 if needed; nothing else to install. ffmpeg is optional (for
.mkv output).
Claude Code
claude mcp add xtream \
-e XTREAM_SERVER=http://your-provider.example:80 \
-e XTREAM_USERNAME=your-username \
-e XTREAM_PASSWORD=your-password \
-- uvx --from git+https://github.com/dmarkey/mcp-xtream mcp-xtreamClaude Desktop and other MCP clients
Add to your client's MCP configuration (for Claude Desktop,
claude_desktop_config.json):
{
"mcpServers": {
"xtream": {
"command": "uvx",
"args": ["--from", "git+https://github.com/dmarkey/mcp-xtream", "mcp-xtream"],
"env": {
"XTREAM_SERVER": "http://your-provider.example:80",
"XTREAM_USERNAME": "your-username",
"XTREAM_PASSWORD": "your-password"
}
}
}
}Try it from a terminal
XTREAM_SERVER=http://your-provider.example:80 \
XTREAM_USERNAME=your-username XTREAM_PASSWORD=your-password \
uvx --from git+https://github.com/dmarkey/mcp-xtream mcp-xtreamIt speaks MCP over stdio, so it waits silently for a client; use MCP Inspector to poke at the tools by hand.
Configuration
Everything is set with environment variables.
Variable | Required | Default |
| yes | — e.g. |
| yes | — |
| yes | — |
| no |
|
| no |
|
| no | your system timezone, e.g. |
The -e / env settings above store your password in plain text in the
client's config file. If you'd rather not, export the variables from your
shell profile instead and leave them out of the MCP config.
Tools
Tool | What it does |
| Search the guide by title (optionally descriptions or channel), past, now or upcoming. Lists every channel carrying each programme and whether catchup is available |
| Find channels by name or category, with catchup days and what's on now |
| One channel's guide for a day |
| Full description, air times and channels for one programme, for identifying the episode |
| Download a past programme in the background, optionally named for Jellyfin/Plex |
| Track and manage downloads |
| Get pushed a notification when each download finishes, fails or is cancelled |
| Subscription status, expiry, connection limit, active connections |
| Re-fetch the channel list and guide now |
Download notifications
Clients that support server-push events can call subscribe_events once after
connecting. Each download that ends is then announced as an MCP log
notification with logger="events":
{"event": "download_finished", "job_id": "c7cba935dee2", "title": "Sunday Politics",
"channel": "IRL: BBC ONE NORTHERN 4K", "output": "/media/tv/Sunday Politics/Sunday Politics - 2026-10-18.mkv",
"size_mb": 1288.6, "message": "Download finished: 'Sunday Politics' (1.3 GB) saved to …"}download_failed (with error) and download_cancelled work the same way.
Announcements are tracked per client on disk, so a download that ends while
the server is restarting is still announced when the client resubscribes.
For markeybot, set "events": true on
the server entry and it subscribes automatically.
Note: MCP's logging capability, which these notifications ride on, is marked
deprecated in the 2026-07-28 spec (SEP-2577). Clients that still deliver log
notifications (the MCP Python SDK's ClientSession with a logging_callback,
markeybot) work; others just won't see the events, and download_status still
works for everyone.
Episode numbers are best effort (and the assistant's job)
Xtream guides almost never carry season/episode numbers (one provider tested
had them for 0.1% of programmes), and repeats air long after the original
broadcast, so the server doesn't guess. Instead the assistant reads the
description with programme_details, identifies the episode itself (web
search, TheTVDB, TMDB, TVmaze or the broadcaster's site) and passes what it
found to download_programme:
Arguments | Saved as |
|
|
|
|
neither |
|
Treat the numbers as a best guess: broadcasters and databases often number the
same episode differently (e.g. "series 18" vs "season 28"), so tell the
assistant which database your media server uses. The .nfo file records the
description and air date and notes that the numbering came from the assistant.
How it works
The guide. The channel list and XMLTV guide are fetched from your
provider and cached on disk (refreshed when over 6 hours and 3 hours old
respectively, the next time a tool is used; refresh_data forces it).
Overlapping entries are resolved, mangled titles cleaned up, and past
programmes kept for 7 days. If a refresh fails, the previous copy is used and
results carry a warning.
"+1" channels. Providers often point "+1" channels at the main channel's guide. When a channel's name contains "+1" but its guide doesn't, its times are shifted an hour later everywhere, so the right hour is downloaded.
Downloads. Each download runs as a detached process, so it survives the
assistant session ending, and holds a lock that the operating system releases
however it exits, so a crashed download never blocks the next one. Catchup URLs
use the start time in the provider's timezone (many providers aren't on
UTC). Dropped connections resume with an HTTP Range request from the last byte
written. Only one download runs at a time, and cancelling also stops an
in-progress .mkv conversion and removes partial files.
Requirements and limitations
macOS or Linux (downloads use POSIX file locking; Windows isn't supported).
Python 3.13+ (
uvxfetches it automatically).Your provider must support Xtream Codes catchup (
tv_archive) for downloads; how far back depends on the channel (often 1–7 days).A download uses one of your account's connections. With a one-connection account you can't watch and download at the same time.
Development
git clone https://github.com/dmarkey/mcp-xtream
cd mcp-xtream
uv sync
uv run pytest # unit + end-to-end tests against local fake servers
uv run ruff check src testsThe tests never contact a real provider.
Disclaimer
This is an unofficial client for the Xtream Codes API. Use it only with IPTV services you are entitled to use, and respect your provider's terms and the rights of content owners. Downloads are for personal, time-shifted viewing.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Control Android TV from any AI. 38 MCP tools: playback, recap, recommend, smart-home, schedules.
Query your Twitch streams, events, supporters, raids & rankings from an AI assistant via OAuth.
- MoreLikeOAuthai.morelike
Track the TV and films you watch, and find more like them, by talking to your own AI.
YouTube transcripts, search, channel/playlist listings and upload tracking for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA comprehensive Model Context Protocol server that bridges LLMs with self-hosted media services, enabling natural language control of TV shows, movies, downloads, and notifications while maintaining traditional API access.15AGPL 3.0
- AlicenseAqualityDmaintenanceEnables querying TV programming data from Tunarr XMLTV feeds, including viewing channel listings, current and upcoming schedules, and searching for programmes by title or description.5MIT
- AlicenseNot gradedqualityDmaintenanceEnables users to manage and control their Plex media library through natural language commands in MCP-compatible AI clients. It supports searching content, managing playlists, tracking library statistics, and monitoring live viewing sessions.MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage media automation services like Sonarr, Radarr, Prowlarr, Bazarr, Overseerr, and Plex through natural language commands.7MIT