Skip to content

Add MCP tools to read and edit a media file's metadata - #132

Merged
kody-bot merged 1 commit into
mainfrom
mcp-media-metadata
Oct 18, 2026
Merged

kody-bot merged 1 commit into
mainfrom
mcp-media-metadata

Conversation

@kody-bot

Copy link
Copy Markdown
Collaborator

Why

Kody (and other MCP clients) can browse MediaRSS and manage feeds, but can't fix a file's tags. The only metadata editor is the admin UI/API behind Cloudflare Access. Follow-up to #131: some older General Conference talks need their Estimated publish description line corrected so each talk gets a distinct, chronological pubDate.

Change

  • New shared module app/helpers/media-metadata-edit.ts, extracted from PUT /admin/api/media/*path/metadata. It holds the same MetadataUpdateSchema (date stays YYYY/YYYY-MM/YYYY-MM-DD), the FFmpeg tag write (-c copy -map_metadata 0, atomic replace, so every other tag and the cover art is kept), cache invalidation, and the media detail response.
  • Path containment: resolveContainedMediaFile requires the target to resolve inside the configured media root (path.resolve plus realpath, so no .. or symlink escape) and to be a regular file. The admin endpoint now uses it too. Before, it used path.join.
  • New MCP tools (app/mcp/media-metadata-tools.ts, registered from initializeTools):
    • get_media_metadata (mcp:read): { mediaRoot, relativePath } returns the full metadata.
    • update_media_metadata (mcp:write): { mediaRoot, relativePath, ...fields } with any of title, author, description, date, genre, trackNumber, copyright, narrator, album, albumArtist, composer, publisher, discNumber, language, series, seriesPosition, encodedBy, subtitle. Only the fields passed are written.
  • The admin route is now a thin wrapper over the shared helper. Same status codes and response shape.

Tests

  • Containment: .. traversal, absolute path, symlink escape, unknown root, directory, and missing file are all rejected.
  • The update writes only the provided fields and invalidates the cache. Invalid date, a time in date, an empty update, and traversal all leave the file untouched.
  • MCP tools are gated by scope (read only, write only, both, none). Only editable fields are forwarded, and errors come back as isError results.

npm run validate passes locally (305 tests).

Add get_media_metadata (mcp:read) and update_media_metadata (mcp:write)
MCP tools. Both share the admin PUT /admin/api/media/*path/metadata logic,
now extracted to app/helpers/media-metadata-edit.ts: the same validation
schema, the FFmpeg tag write (stream copy, atomic replace, other tags kept),
and cache invalidation. Paths must resolve inside the configured media root
(resolve + realpath containment, regular files only), which the admin
endpoint now enforces too.
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 216c2b9d-c7db-40b5-ae81-b2f21323e463
📥 Commits

Reviewing files that changed from the base of the PR and between fdc5801 and c5f152e.

📒 Files selected for processing: 7
  • app/helpers/media-metadata-edit.test.ts
  • app/helpers/media-metadata-edit.ts
  • app/mcp/media-metadata-tools.test.ts
  • app/mcp/media-metadata-tools.ts
  • app/mcp/metadata.ts
  • app/mcp/tools.ts
  • app/routes/admin/api/media.$path.metadata.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kody-bot
kody-bot merged commit 40338af into main Oct 18, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant