ytptube-mcp
# ytptube MCP Server
A local stdio [Model Context Protocol](https://modelcontextprotocol.io/) server
that lets an MCP client inspect and, when explicitly enabled, manage a
self-hosted [ytptube](https://github.com/arabcoders/ytptube) HTTP API.
## What is this?
This server gives an AI assistant a focused interface to your ytptube instance
without putting API credentials in prompts or source control. It can inspect
downloads, history, tasks, presets, logs, and service configuration. Changes
are disabled by default and are rejected locally before the server makes a
network request.
Ask your MCP client things such as:
- "Is my ytptube instance reachable?"
- "What is downloading right now?"
- "Show the latest completed downloads."
- "Inspect this video URL before I add it."
- "What scheduled tasks are configured?"
- "List my download presets."
When you deliberately enable write access, it can also add downloads, manage
the queue and history, update tasks and presets, and generate metadata.
## Features
- **Safe by default** — `YTPTUBE_ALLOW_MUTATIONS=false` blocks every
state-changing request before it reaches ytptube.
- **Focused API access** — inspect health, configuration, queue/history,
archive entries, scheduled tasks, presets, and recent logs.
- **Validated inputs** — download and task URLs must use HTTP or HTTPS; write
tools reject raw yt-dlp CLI strings.
- **Credential-aware** — authentication is optional, but the username and
password must be configured together and sensitive API results are redacted.
- **Small deployment surface** — standard input/output transport and a
configured ytptube HTTP API; no file browser, shell access, notifications,
task/preset deletion, or SSE.
## Quick start
### Prerequisites
- Node.js `^20.19.0` or `>=22.12.0`.
- A reachable self-hosted ytptube HTTP API.
- An MCP-compatible client, such as Codex or Claude Desktop.
### Install from npm
```sh
npm install --global ytptube-mcp
```
This makes the `ytptube-mcp` command available on your `PATH`. Configure the
server through your MCP client's environment, as shown below.
### Install from source
```sh
git clone https://github.com/Snuffy2/ytptube-mcp.git
cd ytptube-mcp
npm ci
cp .env.example .env
# Edit .env and set YTPTUBE_BASE_URL.
npm run build
```
The build produces `dist/index.js`. Re-run `npm run build` after changing the
TypeScript source.
At startup, the built server reads the `.env` file from the checkout that
contains `dist/index.js`, even when an MCP client starts it from another
directory. Explicit environment variables take precedence over `.env`.
## Configure your MCP client
For an npm installation, use the `ytptube-mcp` command and keep values specific
to your ytptube instance in its environment configuration:
```toml
[mcp_servers.ytptube]
command = "ytptube-mcp"
[mcp_servers.ytptube.env]
YTPTUBE_BASE_URL = "https://media.example.net/ytptube"
YTPTUBE_ALLOW_MUTATIONS = "false"
# Set these two together only when the API requires authentication.
# YTPTUBE_USERNAME = "your-user"
# YTPTUBE_PASSWORD = "your-password"
```
For a source checkout, run its built server with Node. Replace the placeholder
with the absolute path to your checkout:
```toml
[mcp_servers.ytptube]
command = "node"
args = ["/absolute/path/to/ytptube-mcp/dist/index.js"]
```
The checkout's `.env` file supplies its configuration. Do not commit actual
credentials or store them in shared shell history.
### Environment variables
| Variable | Required | Description |
| ----------------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------- |
| `YTPTUBE_BASE_URL` | Yes | Root URL of the ytptube API, including any reverse-proxy path prefix. |
| `YTPTUBE_USERNAME` and `YTPTUBE_PASSWORD` | Together, if needed | Optional HTTP API credentials. Providing only one is a configuration error. |
| `YTPTUBE_AUTH_MODE` | No | `basic` (default) sends HTTP Basic authentication; `apikey` uses the API fallback query parameter. |
| `YTPTUBE_TIMEOUT_MS` | No | Request timeout from `100` through `300000` milliseconds; defaults to `30000`. |
| `YTPTUBE_ALLOW_MUTATIONS` | No | Exact string `true` enables state-changing tools. Defaults to `false`. |
## Safety and write access
The server is read-only by default. With `YTPTUBE_ALLOW_MUTATIONS=false`, a
request such as `ytptube_add_downloads` returns `MUTATIONS_DISABLED` locally
and sends no request to ytptube. Read-only inspection tools remain available.
Set the value to the exact string `true` only for a session that must change
state, then restart the server/client so it receives the new setting. Return
it to `false` when you are done.
```dotenv
YTPTUBE_ALLOW_MUTATIONS=true
```
The gate covers download additions/retries, queue controls, history and archive
changes, task and preset changes, and metadata generation. Clearing history
does not remove media unless the request explicitly asks for it.
## Available Tools
Every tool name begins with `ytptube_`. Tools marked **Yes** in the Mutating
column require `YTPTUBE_ALLOW_MUTATIONS=true`; otherwise the server rejects the
request before contacting ytptube.
### Health and Inspection Tools
| Tool | Description | Mutating |
| ---------------------------------- | ------------------------------------------------------------------ | -------- |
| `ytptube_ping` | Check whether the configured ytptube API is reachable. | No |
| `ytptube_get_system_configuration` | Read system configuration with sensitive fields redacted. | No |
| `ytptube_get_ytdlp_options` | Read the active yt-dlp option configuration. | No |
| `ytptube_validate_cli_options` | Parse and validate yt-dlp CLI options without starting a download. | No |
| `ytptube_inspect_url` | Inspect URL metadata without adding it to the download queue. | No |
| `ytptube_list_logs` | Read recent application logs when file logging is enabled. | No |
| `ytptube_live_queue` | Read current in-memory queue progress and counts. | No |
### Queue and History Tools
| Tool | Description | Mutating |
| ---------------------------- | -------------------------------------------------------------------- | -------- |
| `ytptube_list_history` | List a paginated queue or completed-history page. | No |
| `ytptube_get_history_item` | Read one queue or history item by ID. | No |
| `ytptube_add_downloads` | Add one or more URLs to the download queue. | Yes |
| `ytptube_retry_history_item` | Requeue a history item using only its saved download-request fields. | Yes |
| `ytptube_queue_control` | Start, pause, force-start, reorder, or cancel queued downloads. | Yes |
| `ytptube_clear_history` | Delete selected queue/history records; media deletion is opt-in. | Yes |
### Archive and Metadata Tools
| Tool | Description | Mutating |
| -------------------------------- | ---------------------------------------------------------------------- | -------- |
| `ytptube_list_archive` | List archive entries for a preset, optionally filtered by archive IDs. | No |
| `ytptube_set_history_archive` | Archive or unarchive a history item using its configured archive file. | Yes |
| `ytptube_generate_task_metadata` | Generate task metadata, NFO, and image sidecar files. | Yes |
| `ytptube_generate_history_nfo` | Generate an NFO sidecar for a completed history item. | Yes |
### Task Tools
| Tool | Description | Mutating |
| -------------------------- | -------------------------------------------------------------------- | -------- |
| `ytptube_list_tasks` | List scheduled tasks with pagination. | No |
| `ytptube_get_task` | Read a scheduled task by numeric ID. | No |
| `ytptube_inspect_task_url` | Preview task handling and items for a URL without queuing downloads. | No |
| `ytptube_create_tasks` | Create one or more scheduled tasks. | Yes |
| `ytptube_patch_task` | Partially update a scheduled task. | Yes |
| `ytptube_update_task` | Replace a scheduled task using the API PUT contract. | Yes |
### Preset Tools
| Tool | Description | Mutating |
| ----------------------- | ----------------------------------------------------------------- | -------- |
| `ytptube_list_presets` | List download presets with pagination and sorting. | No |
| `ytptube_get_preset` | Read a download preset by numeric ID. | No |
| `ytptube_create_preset` | Create a download preset. | Yes |
| `ytptube_patch_preset` | Partially update a non-default download preset. | Yes |
| `ytptube_update_preset` | Replace a non-default download preset using the API PUT contract. | Yes |
### Important limits
- Task URL inspection is a preview; ytptube does not offer a scheduled-task
"run now" endpoint.
- Global yt-dlp options are read-only through this server.
- Write tools do not accept raw yt-dlp CLI strings. The validation tool only
parses and validates a string; it never starts a download.
- Download `extras` accepts only `ignore_conditions`, a non-empty array of
condition names. Use `"*"` to ignore all conditions.
- Per-download authentication and settings belong in presets. Task create and
update inputs reject arbitrary configuration and cookies.
## Development
Install [`prek`](https://prek.j178.dev/installation/) to run the repository's
quality hooks or refresh its hooks with the dependency-update script.
```sh
# Install dependencies, type-check, test, and build.
./scripts/test.sh
# Run the repository quality hooks.
prek run --all-files
```
`prek` is the repository's only linter and formatter. It checks repository
files, GitHub Actions syntax, formatting, and TypeScript types.
## Troubleshooting
**The server says `YTPTUBE_BASE_URL is required`.** Set a valid HTTP or HTTPS
base URL in the MCP client environment or `.env`, including any proxy prefix.
**Authentication fails.** Confirm the URL is correct for your proxy and that
both `YTPTUBE_USERNAME` and `YTPTUBE_PASSWORD` are set. Use `basic` unless
your ytptube API/proxy specifically requires the `apikey` fallback.
**A mutation is unavailable.** Confirm it is really required, set
`YTPTUBE_ALLOW_MUTATIONS=true`, restart the MCP client/server, perform the
operation, and then disable mutations again.
**A tool returns redacted values.** This is intentional: the server protects
credentials and sensitive values when it formats API results and errors.
## Contributing
Please open an issue before starting a large change. Keep the stdio transport,
the ytptube HTTP API boundary, and the read-only default intact. Run the local
test script and `prek` before opening a pull request.
## License
This project is licensed under the [MIT License](LICENSE.md).
TDQS
Scored across 28 tools
Every tool has a distinct purpose: reading vs writing, history vs tasks vs presets vs system state. Even the patch/update pairs are clearly differentiated by partial vs full replacement.
All tools use the 'ytptube_' prefix followed by a verb_noun pattern (e.g., list_tasks, create_preset, validate_cli_options). Minor deviations like 'live_queue' are still readable and do not break the overall consistency.
With 28 tools, the server exceeds the 25-tool threshold for 'too many'. While each tool covers a distinct API operation, the sheer number makes the surface area heavy and harder to navigate.
Core download lifecycle and task/preset management are covered, but obvious gaps exist: there is no delete operation for tasks or presets, and system configuration and yt-dlp options are read-only with no set/update functionality.