sf-mm-mcp
Enables searching movies and TV shows, finding magnet links, and starting downloads on put.io via natural language from MCP clients like Claude.
README
<img src="https://raw.githubusercontent.com/githendrik/sf-mm-mcp/main/assets/logo-256.png" alt="" width="96" align="left">
sf-mm-mcp
An MCP server that exposes moviemagnet.site (movies) and showfeed.site (TV shows) to LLM clients, with put.io as the download backend.
Search a title, find magnet links ranked by seeders, and start the download on put.io — all from inside Claude Desktop, Claude Code, opencode, or any other MCP client.
npx sf-mm-mcp login # one-time put.io sign-in
npx sf-mm-mcp # start the server on stdio
Setup
1. Add the server to your MCP client
The put.io app id (9525) is built in, so there is nothing to configure for a default
install.
Claude Desktop (claude_desktop_config.json), Claude Code (.mcp.json), and opencode
(opencode.json) all use the same shape:
{
"mcpServers": {
"sf-mm": {
"command": "npx",
"args": ["-y", "sf-mm-mcp"]
}
}
}
opencode
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"sfmm": {
"type": "local",
"command": ["npx", "-y", "sf-mm-mcp"],
"enabled": true
}
}
}
opencode prefixes tool names with the server name, so the tools appear as
sfmm_movies_search, sfmm_putio_login, and so on. Verify the connection with
opencode mcp list.
Note that opencode mcp auth does not apply here. That command drives OAuth for
remote MCP servers via dynamic client registration; this is a local stdio server that
manages its own put.io credential. Use the sign-in below instead.
See docs/clients.md for Cursor, VS Code, Windsurf, Zed,
Cline and others.
2. Sign in
Either run npx sf-mm-mcp login in a terminal, or ask your assistant to call the
putio_login tool and follow the instructions it returns.
putio_login is non-blocking by design, so the in-chat flow works: the tool returns a
code immediately, you enter it at put.io/link, and putio_auth_status confirms. The token
is stored per-machine, so signing in once covers every MCP client on that machine.
Authentication
The default is put.io's OOB (out-of-band) device flow: the server requests a short code, you enter it at https://put.io/link, and the server polls until it is linked.
This is the default rather than the more familiar redirect flow for a specific reason: an npx-distributed package cannot hold a client secret. Anything baked into the tarball is readable by everyone who installs it. The OOB flow needs no secret and no loopback listener, so it also works over SSH and inside containers.
If you control the environment and prefer the redirect flow, set:
SF_MM_AUTH_FLOW=loopback
PUTIO_CLIENT_SECRET=... # supply it yourself; never commit it
PUTIO_REDIRECT_URI=http://127.0.0.1:41830/callback
The redirect URI must match one registered on your put.io app. state is generated per
handshake and verified on the callback.
Where the token is stored
In order of preference:
PUTIO_TOKENenvironment variable, if set (nothing is persisted).- OS keychain — macOS Keychain via
security, Linux viasecret-tool. - A
0600file at~/.config/sf-mm-mcp/token.json.
npx sf-mm-mcp status reports which backend is in use. npx sf-mm-mcp logout clears it.
Tools
Discovery — no sign-in required
| Tool | Purpose |
|---|---|
movies_search |
Find movies by title, returns IMDb ids |
movies_get |
Full details for one movie |
movies_popular |
Most-viewed movies on moviemagnet.site |
shows_search |
Find TV shows by title |
shows_get |
Show details plus episode list, optionally one season |
shows_popular |
Most-viewed shows on showfeed.site |
Torrents — sign-in required
| Tool | Purpose |
|---|---|
movies_find_torrents |
Magnets for a movie, filterable by resolution and seeders |
shows_find_torrents |
Magnets for a show, filterable by season, episode, resolution |
Results are normalised to {title, magnet, sizeHuman, seeders, resolution, season, episode, ageDays}
and sorted by seeder count.
put.io — sign-in required
| Tool | Purpose |
|---|---|
putio_add_transfer |
Start a download from a magnet or URL |
putio_list_transfers |
List transfers with progress |
putio_get_transfer |
Poll a single transfer |
putio_cancel_transfers |
Cancel or remove transfers |
putio_clean_transfers |
Clear completed transfer entries |
putio_account |
Username and disk usage |
putio_list_files |
Browse files and folders |
favorites_list / favorites_update |
Read and edit the favorites list |
Favorites are stored in the put.io account config under the same favorites key the two
websites use, so the list stays in sync across all three.
Auth
putio_login, putio_auth_status, putio_logout.
putio_login returns instructions immediately rather than blocking — waiting for a human
to finish a browser flow would hold the tool call open for minutes and most clients time
out first. Poll putio_auth_status to confirm.
Configuration
All optional.
| Variable | Default | Purpose |
|---|---|---|
PUTIO_CLIENT_ID |
9525 |
put.io OAuth app id (public); override to use your own app |
PUTIO_TOKEN |
— | Use a token directly, skipping sign-in |
SF_MM_AUTH_FLOW |
oob |
oob or loopback |
PUTIO_CLIENT_SECRET |
— | Only for loopback |
PUTIO_REDIRECT_URI |
http://127.0.0.1:41830/callback |
Only for loopback |
MOVIEMAGNET_BASE_URL |
https://moviemagnet.site |
Point at a dev instance |
SHOWFEED_BASE_URL |
https://showfeed.site |
Point at a dev instance |
PUTIO_API_BASE_URL |
https://api.put.io/v2 |
|
SF_MM_CONFIRM_TRANSFERS |
false |
Require confirm=true on putio_add_transfer |
SF_MM_TORRENT_CACHE_TTL |
900 |
Torrent result cache, seconds |
SF_MM_METADATA_CACHE_TTL |
3600 |
Metadata cache, seconds |
SF_MM_TOKEN_STORE |
auto |
auto/keychain/file/none; none disables persistence |
SF_MM_LOG_LEVEL |
info |
debug/info/warn/error/silent |
Caching and rate limits
Both websites validate the put.io token on every /api/torrent request, and that endpoint
fans out to torrent indexers. An LLM will call these far more eagerly than a human
clicking through a web page, so this server:
- caches torrent results (15 min) and metadata (1 hour) in process,
- de-duplicates concurrent identical requests,
- caches token-validation results for 10 minutes rather than revalidating per call,
- honours put.io's
429plusX-RateLimit-Resetheaders with backoff, - never retries a write, so a transfer cannot be silently created twice.
Development
npm install
npm run build
npm run typecheck
npm test # boots the server, asserts tool surface; no network
npm run smoke # exercises the live public endpoints over MCP stdio
npm test is network-free on purpose, so CI does not go red because a torrent
indexer is having a bad day. It runs with SF_MM_TOKEN_STORE=none so it cannot
accidentally pick up a developer's real token and skip the auth-gating checks.
Releasing
npm version patch && git push --follow-tags
Publishing runs from GitHub Actions on a version tag. There is no npm token anywhere: the workflow authenticates with npm via OIDC trusted publishing, which also generates a provenance attestation automatically.
npm version patch # or minor / major - commits and tags
git push --follow-tags
.github/workflows/publish.yml then refuses to continue unless:
- the tag matches
package.jsonversion exactly, - that version is not already on npm,
- typecheck, build and the tool-surface test all pass,
- no
.envfile made it into the tarball.
To rehearse without publishing, run the workflow manually from the Actions tab
with dry-run left checked. Full detail in
docs/releasing.md.
Documentation
docs/architecture.md |
Design decisions and why the alternatives lost |
docs/auth.md |
Credential model; why there is no client secret |
docs/upstream-apis.md |
The two sites' API surface and its quirks |
docs/clients.md |
Configuration for every common MCP client |
docs/releasing.md |
Release procedure and CI guards |
Agents should start at AGENTS.md.
Point at local dev servers with MOVIEMAGNET_BASE_URL=http://localhost:5173.
Notes on the upstream APIs
Neither site publishes a schema, so the shapes in src/schemas.ts were derived by reading
the SvelteKit route handlers and probing the live endpoints. Two things worth knowing:
- Both sites expect the put.io token in a bare
Authorizationheader with noBearerprefix. This client matches that. - Neither site has a "create transfer" endpoint — the web apps do it client-side. So
transfers, account info, and favorites go directly to
api.put.io.
Validation failures are logged rather than swallowed, so upstream schema drift shows up as a warning on stderr instead of a silent "no results found".
A bug this client used to work around
Both sites once returned 500 on the first request for any given title, because
torrentService.js destructured the Jackett response as const { instance, data: results }
— declaring a new block-scoped results that shadowed the outer one, leaving it undefined
on every cache miss. It hid well: the shadowed value was still written to Redis, so a retry
hit the cache and succeeded. Titles with zero indexer results were never cached and so
failed permanently.
Fixed and deployed in both apps (showfeed-app@6640310, moviemagnet-app@77b22fe),
along with queryMultipleServices, which only ever called resolve and therefore hung
forever if every indexer failed.
The 5xx retry in this client predates those fixes. It is kept because indexers still fail
transiently, but it is no longer masking a deterministic upstream failure. Full write-up in
docs/upstream-apis.md.
Credits
Logo icons from pepicons by CyCraft, licensed CC BY 4.0.
See assets/README.md.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。