Skip to main content
Glama

tmdb-media

TypeScript/Node implementation of the TMDB local media metadata tool described in docs/spec-tmdb-media.md.

Current status: iteration 1 (read-only pipeline) in progress, building on the parser benchmark spike. It does not write media metadata, rename files, move files, delete files, or touch a media library.

The iteration provides these read-only commands:

  • scan — discover media files under a configured library root.

  • search — query TMDB for candidate matches.

  • match — score and rank candidates against a parsed file.

  • details — fetch canonical metadata for a chosen candidate.

  • scrape --dry-run — run the full pipeline and report what would be written, without writing anything to the media library.

Run

corepack pnpm install
corepack pnpm benchmark:parser
corepack pnpm test
corepack pnpm typecheck

Parse one filename or path:

corepack pnpm exec tsx src/cli.ts parse "/Volumes/Media/TV/庆余年/Season 1/第01集.mkv" --json

Related MCP server: ChromaDB Local MCP Server

Parser Spike Result

The fixture at tests/fixtures/parser-samples.json currently shows:

  • PTT + normalization baseline: 9/14 required cases.

  • Enhanced parser: 14/14 required cases.

The enhanced parser layers Chinese season/episode handling and parent-directory title inference on top of parse-torrent-title. Known-hard cases are also tracked in the fixture but do not gate the command.

如何使用 (Usage)

本项目有两种用法:CLI(你在终端手动跑)和 MCP(AI 客户端如 Claude Code / Codex 通过对话调用)。两者底层是同一套管线。

刮削分两种模式,区别在「动不动真实视频文件」:

模式

做什么

动视频吗

CLI

MCP 工具

① 轻量 sidecar

在视频旁边写 metadata.json / metadata.md

不动,只新增旁车文件

scrape

plan_scrapewrite_artifacts

② 完整 organize

tinyMediaManager / Jellyfin 式整理:重命名文件夹、把分集移进 Season N/、写 tvshow.nfo + 分集 NFO、下载 poster/fanart/剧照

会重命名/移动真实视频

organize(+ undo

plan_organizeapply_organize(+ undo_organize

两种模式都很保守:默认 dry-run、默认不覆盖、执行前需二次确认;organize 还可整次回滚。

CLI 用法

CLI 既能用源码跑(corepack pnpm exec tsx src/cli.ts <cmd>),也能 build 后用 node dist/cli.js <cmd>。下面用配置示例里的库名 movies / tv 举例。

# 列出某库(或子目录)的视频文件(只读)
node dist/cli.js scan -l tv -s "庆余年"

# 搜 TMDB 候选
node dist/cli.js search "庆余年" -t tv
node dist/cli.js search "盗梦空间" -t movie -y 2010

# 取某 TMDB id 的规范元数据
node dist/cli.js details tv 272432
node dist/cli.js details movie 27205 --language zh-CN

# 发现/挑片(只读):趋势、推荐、相似
node dist/cli.js trending movie                       # 本周热门电影(默认 week)
node dist/cli.js trending tv -w day                   # 当日热门剧集
node dist/cli.js recommend movie 27205                # 与某电影相关的推荐
node dist/cli.js similar tv 272432 --language zh-CN   # 与某剧集相似的作品

# 扫描 + 解析 + 匹配,看会命中什么(只读,不写)
node dist/cli.js match -l tv -s "庆余年"
node dist/cli.js match -l tv -s "某改名文件夹" --tmdb-id tv:272432   # 强制锁定作品

# 模式①:sidecar 刮削。默认 DRY-RUN,加 --yes 才真正写
node dist/cli.js scrape -l tv -s "庆余年"                 # dry-run,看会写什么
node dist/cli.js scrape -l tv -s "庆余年" --yes           # 真正写出 metadata.json/.md
node dist/cli.js scrape -l tv -s "某文件夹" --tmdb-id tv:272432 --yes   # 强制作品后写
node dist/cli.js scrape -l tv -s "庆余年" --yes --overwrite             # 覆盖已有 sidecar(先备份 .bak.<ts>)

# 模式②:organize(Jellyfin 式整理,会重命名/移动真实视频)。默认 DRY-RUN
# 同时支持电影和剧集:--tmdb-id 接受 movie:603 / tv:272432 / 裸 id(默认 tv)
node dist/cli.js organize -l tv -s "低智商犯罪" --tmdb-id 272432         # 剧集 dry-run:打印改名 + 每集移动
node dist/cli.js organize -l tv -s "低智商犯罪" --tmdb-id 272432 --yes   # 剧集真正执行,打印 run-id
node dist/cli.js organize -l tv -s "低智商犯罪" --tmdb-id 272432 --yes --no-images   # 不下图片
node dist/cli.js organize -l tv -s "低智商犯罪" --tmdb-id 272432 --yes --overwrite   # 覆盖已有 NFO/图片
node dist/cli.js organize -l movies -s "某电影文件夹" --tmdb-id movie:603         # 电影 dry-run
node dist/cli.js organize -l movies -s "某电影文件夹" --tmdb-id movie:603 --yes   # 电影真正执行

# 回滚一次 organize(用 organize --yes 打印的 run-id)
node dist/cli.js undo <run-id>

关键点:

  • scrape / organize 默认都是 dry-run,必须显式 --yes 才动磁盘。

  • organize 同时支持电影和剧集--tmdb-id 必填,接受 movie:603 / tv:272432 / 裸 272432(裸 id 默认按 tv 处理)。

    • 剧集布局:文件夹改名为 片名 (年份),每集移进 Season N/片名 - SxxExx - 标题,写 tvshow.nfo + 分集 NFO,下 poster/fanart/剧照。

    • 电影布局:把文件夹与主视频都重命名为 片名 (年份)(如 片名 (年份).mkv),写 movie.nfo,下 poster/fanart——没有 Season 文件夹、没有分集

  • 每次 organize --yes 都会落一个 run-id,可用 undo <run-id> 整次回滚(移回视频、删除新建的 Season 目录与 NFO/图片、把文件夹名改回去)。

  • 任何命令都不传绝对路径,只用 -l/--library 库名 + -s/--subpath 相对子路径。

MCP 用法

MCP server 跑的是编译后的 dist/cli.js mcp,共暴露 12 个工具

工具

作用

破坏性

get_capabilities

列出库、默认/回退语言、支持格式、minConfidence、视频扩展名、TMDB 署名

否(只读)

scan_media_files

分页列出某库的视频文件(含 existingArtifacts

否(只读)

search_tmdb

按标题(可带年份)搜 TMDB 候选

否(只读)

get_tmdb_metadata

取某 TMDB id 的规范元数据

否(只读)

get_trending

取趋势:{ type, window?(day/week,默认 week), language? },挑片/发现用

否(只读)

get_recommendations

取某 TMDB id 的推荐:{ type, tmdb_id, language? }

否(只读)

get_similar

取某 TMDB id 的相似作品:{ type, tmdb_id, language? }

否(只读)

plan_scrape

模式① 规划 sidecar 写入(不写),返回 plan_id + expected_plan_hash

否(只读)

write_artifacts

模式① 按计划写出 sidecar,需 plan_id + expected_plan_hash

是(destructive)

plan_organize

模式② 规划 Jellyfin 式整理(电影 / 剧集均可,tmdb_id 接受 movie:603 / tv:272432 / 裸 id),不动文件,返回 plan_id + expected_plan_hash

否(只读)

apply_organize

模式② 执行整理:重命名/移动视频 + 写 NFO + 下图片,需 plan_id + expected_plan_hash,落 run_id

是(destructive,动真实视频!)

undo_organize

run_id 整次回滚一次 apply_organize

是(destructive)

工作流 A:sidecar 刮削(模式①,不动视频)

  1. planplan_scrape({ library, subpath?, tmdb_id?, ... }) 规划,返回 plan_idexpected_plan_hashtargets(将写哪些文件、命中哪部作品、置信度)。不写任何文件。

  2. 确认 — 把 targets 念给用户看,等用户核对。

  3. write — 用户确认后 write_artifacts({ plan_id, expected_plan_hash }) 原子写出(hash 不符会报 PLAN_STALE,重新 plan 即可)。

工作流 B:organize 整理(模式②,会动真实视频)

  1. planplan_organize({ library, subpath, tmdb_id, images?, overwrite? }) 规划,返回 plan_idexpected_plan_hashshow_folder_rename(文件夹改名)、seasonsmoves(每集要移到哪)、NFO/图片数量、unmatched不动任何文件tmdb_id 同时支持电影和剧集,接受 movie:603 / tv:272432 / 裸 272432(裸 id 默认 tv);电影布局只把文件夹+主视频重命名为「片名 (年份)」并写 movie.nfo + poster/fanart(无 Season 文件夹、无分集)。

  2. 确认(重点) — organize 会重命名文件夹、移动真实视频,所以必须把文件夹改名和每集移动一条条念给用户,明确告知这会改动真实文件,等用户确认。

  3. apply — 用户确认后 apply_organize({ plan_id, expected_plan_hash }) 执行,返回一个 run_id

  4. undo(必要时) — 出问题或用户反悔,用 undo_organize({ run_id }) 整次回滚。

安全红线:root 由配置固定,只传 library + subpath绝不传绝对路径;organize 因为动真实文件,必须 plan → 给用户看 → 确认 → apply,必要时 undo;纯数字集号 / 被改名的文件夹用 tmdb_id(如 "tv:272432")强制锁定作品。

如何集成 (Integration)

前置准备

# 1. 安装依赖并构建(MCP / dist 用法都需要先 build)
corepack pnpm install
corepack pnpm build

# 2. 配置 config.toml(参考 config.example.toml,填好每个库的 root 与 type)
cp config.example.toml config.toml

# 3. 设置 TMDB 凭据(环境变量,不要写进配置文件)
export TMDB_ACCESS_TOKEN="<your-tmdb-v4-read-access-token>"

库根目录在配置里固定,AI / MCP 调用方只传库名 + 相对子路径,绝不传绝对路径。

在 Claude Code 注册

方式 A:项目级 .mcp.json(已提供示例,把占位 token 换成你自己的):

{
  "mcpServers": {
    "tmdb-media": {
      "command": "node",
      "args": ["dist/cli.js", "mcp"],
      "env": {
        "TMDB_ACCESS_TOKEN": "<your-tmdb-v4-read-access-token>",
        "TMDB_MEDIA_CONFIG": "config.toml"
      }
    }
  }
}

方式 B:命令行一键添加:

claude mcp add tmdb-media -- node dist/cli.js mcp

随仓库还附带一个 Claude Code skill .claude/skills/tmdb-scrape/SKILL.md, 覆盖 sidecar 刮削和 organize 整理两套安全工作流,用户提到「刮削 / scrape / organize / Jellyfin / 重命名 / TMDB 元数据 / 识别媒体文件夹」等时会自动触发。

在 Codex 注册

~/.codex/config.toml 加:

[mcp_servers.tmdb-media]
command = "node"
args = ["dist/cli.js", "mcp"]

[mcp_servers.tmdb-media.env]
TMDB_ACCESS_TOKEN = "<your-tmdb-v4-read-access-token>"
TMDB_MEDIA_CONFIG = "config.toml"

环境变量说明

  • TMDB_ACCESS_TOKEN — TMDB v4 read access token(Bearer,优先)。

  • TMDB_API_KEY — TMDB v3 api key(TMDB_ACCESS_TOKEN 缺失时的回退)。

  • TMDB_MEDIA_CONFIG —(可选)config.toml 路径;不设则用 $XDG_CONFIG_HOME/tmdb-media/config.toml

  • TMDB_MEDIA_LOG_LEVEL —(可选)日志级别,默认 info

鉴权只走以上环境变量,不要写进配置文件,也不要在对话里打印 / 回显。

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DipsySu/media-scraper-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server