Announcing Beacon: Self-improving memory for coding agents
← All MCP servers
MCP server

Transcriptor MCP

mcp:samson-art/transcriptor-mcp

Fetch transcripts, subtitles, chapters, metadata and frames from YouTube and 10+ video platforms

Verdict
Inconclusive

The analysis could not cover enough of the artifact to decide.

Analyzed Oct 29, 2026, 16:26 UTC at 4a9c3c6

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

0
findings
—
highest severity
0
threat classes
159
files scanned
785/785
checks satisfied
0
package advisories

Why this verdict

  • inconclusive: gap dynamic_metadata at src/mcp-core.ts

Security findings 0

No individual findings recorded

The inconclusive verdict rests on the open questions and coverage gaps below.

Notes 5

Capabilities, vulnerabilities and disclosed behavior worth knowing. Nothing here works against the person who installs it, so notes never change the verdict.

Persistence

mediumNoteConfirmed on reviewmedium confidence

The package.json prepare script runs husky on every npm install of the repository, which installs git hooks for the developer's own clone; this is a standard dev-tooling step the developer triggers, undeclared in the MCP description.

"prepare": "husky"
vector:code
Reviewer's reasoning

The prepare script runs husky only when the user runs npm install on the repository, which is a user-invoked dev step (test 4) and sets up git hooks in the user's own clone. It is not an unrequested change to another program or a global setting.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

The error handler attaches the request's user-supplied video URL to the Sentry error context on 5xx errors; this is the operator's configured telemetry for the declared feature and is undeclared in the docs, so it is a note.

requestUrl: bodyUrl
vector:code
Reviewer's reasoning

The video URL the user supplied is attached to Sentry error context on 5xx errors. Sentry is the publisher's own documented telemetry service, which is a note under the carve-outs, and the data is the user's own request input.

Credential access

mediumNoteConfirmed on reviewmedium confidence

The Whisper API key is sent as a Bearer token to whatever endpoint WHISPER_API_BASE_URL names, an operator-set variable, so the key goes wherever the operator points it; operator-controlled configuration.

Authorization: `Bearer ${config.apiKey}`,
vector:code
Reviewer's reasoning

The Whisper API key is sent to the host named by WHISPER_API_BASE_URL, which the operator sets. This is operator-controlled configuration and the key is the operator's own key for the wrapped service, so it is a note and not credential exfiltration to an unchosen host.

Data exfiltration

mediumNoteConfirmed on reviewmedium confidence

When the operator sets WHISPER_MODE=api, the server uploads the downloaded video audio to the hardcoded OpenAI endpoint for transcription; this is the declared transcription feature and a disclosed service.

const OPENAI_API_BASE = 'https://api.openai.com/v1';
vector:code
Reviewer's reasoning

Audio is uploaded to the OpenAI endpoint only when the operator sets WHISPER_MODE=api, which is a declared, operator-opted transcription feature for a disclosed service, so it is a note.

Reconnaissance

lowNoteConfirmed on reviewmedium confidence

The server's yt-dlp version check calls api.github.com on each check to read the latest yt-dlp release tag, although the changelog says the check does not use the network; this is a read-only note about the observed behavior.

fetch(GITHUB_LATEST_URL, {
vector:code
Reviewer's reasoning

The network call to api.github.com is real and the proposed note describes it accurately. It sends only an Accept header and a User-Agent with the app version, with no credentials and no user data, and it changes no user configuration, so it is not overreach. The changelog's 'does not use the network' statement misstates a behavior that is itself a note, which is a note case.

Third-party flags 1

Behavior aimed at other sites, platforms or people, such as evading rate limits or offensive-security tooling. It does not affect the person who installs it, so it never changes the verdict.

Manipulation

lowNoteConfirmed on reviewlow confidence

The server runs yt-dlp with the server's cookies and browser impersonation to fetch captions from YouTube, which is a bot-check evasion aimed at a third-party platform rather than at the user.

with the server's cookies and its browser
vector:code
Reviewer's reasoning

Fetching captions through yt-dlp with the operator's configured cookies and browser impersonation is the server's declared core transcript capability, and any bot-check evasion lands on YouTube rather than the installer. The cookies are operator-configured and the behavior is disclosed in the code, so this is a note, flagged third_party.

Open questions 1

What the analysis could not settle from the code alone.

[file request src/mcp-core.ts] How is the shared input schema object built, and is it mutated in place by any registration so that the tool input metadata the client receives can differ from the static schema?
Tool poisoning

Coverage gaps 4

Parts of the artifact the static analysis could not fully examine.

dynamic_metadata line 574: tool 'get_raw_subtitles' input schema depends on unsupported construct (unsupported): object may be changed in place
src/mcp-core.ts
dynamic_metadata line 574: tool 'get_available_subtitles' input schema depends on unsupported construct (unsupported): object may be changed in place
src/mcp-core.ts
dynamic_metadata line 574: tool 'get_video_chapters' input schema depends on unsupported construct (unsupported): object may be changed in place
src/mcp-core.ts
dynamic_metadata line 1345: resource 'transcript' uri depends on dependency-provided value (dependency): instance of a class from '@modelcontextprotocol/sdk': new ResourceTemplate('transcriptor://transcript/{videoId}', { list: undefined, })
src/mcp-core.ts