-
Notifications
You must be signed in to change notification settings - Fork 0
MCP
Yamtrack includes a Model Context Protocol (MCP) server that exposes media tracking tools for AI assistants like Claude Desktop, OpenCode, Typem, and Hermes.
The MCP server is served over Streamable HTTP at /mcp — uvicorn on port 8002, also proxied by nginx at :8000/mcp/. Authenticate with a JWT or your static account API token.
Send the token in the Authorization header:
Authorization: Bearer <token>
The MCP server accepts two token types:
Each user already has a static API token — the same one shown (with a copy button) and regenerable from Account settings → Integrations. It is short, never expires, and is the recommended token for MCP: set it once and you never have to refresh it.
Use it directly as the bearer token, or pass it to stdio via the YAMTRACK_JWT env var or --token:
YAMTRACK_JWT=<your-account-token> uv run python src/manage.py run_mcpThis token also authorizes integration webhooks (Plex/Jellyfin/Emby), so treat it like any other API key.
You can also use a JWT from the REST API token endpoint. It expires after one hour, so re-run to get a fresh access token when you see auth errors:
curl -X POST https://your-yamtrack-instance.com/api/token/ \
-H "Content-Type: application/json" \
-d '{"username":"your-username","password":"your-password"}'Use the returned access token as the bearer token for MCP (or the YAMTRACK_JWT env var for stdio).
If you run the container and just need a token for an existing user, mint a JWT inside the container. The MCP server and API share the same SECRET, so the token is accepted:
docker exec -i yamtrack uv run python -c "
from rest_framework_simplejwt.tokens import AccessToken
from django.contrib.auth import get_user_model
u = get_user_model().objects.first() # or .get(username='...')
print(str(AccessToken.for_user(u)))
"Copy the printed token into the Authorization: Bearer <token> header (or the YAMTRACK_JWT env var for stdio).
Read-only tools (search, details) work without authentication.
| Tool | Parameters | Description |
|---|---|---|
search_media |
query, media_type, page, source
|
Search external providers for media |
get_details |
source, media_type, media_id, season_number
|
Get metadata from a provider |
| Tool | Parameters | Description |
|---|---|---|
list_tracked_media |
media_type, status, sort, search
|
List user's tracked media |
get_home |
sort |
Dashboard with in-progress and planning items |
get_history |
source, media_type, media_id, season_number, episode_number
|
Change history for an item |
| Tool | Parameters | Description |
|---|---|---|
create_entry |
media_id, source, media_type, status, score, progress, notes
|
Start tracking new media |
update_entry |
media_type, instance_id, status, score, progress, notes
|
Update tracked media |
update_progress |
media_type, instance_id, operation
|
Increase or decrease progress |
update_score |
media_type, instance_id, score
|
Update score (0-10) |
| Tool | Parameters | Description |
|---|---|---|
get_statistics |
start_date, end_date
|
Aggregated stats and activity data |
The MCP server speaks Streamable HTTP at http://<host>:8002/mcp (uvicorn) or via nginx at http://<host>:8000/mcp/. Pick the config that matches your client.
When calling the endpoint directly (e.g. with
curl), sendAccept: application/json, text/event-stream; otherwise nginx returns406.
OpenCode connects natively over Streamable HTTP. Add under mcp.servers in opencode.json (project root or ~/.config/opencode/opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"servers": {
"yamtrack": {
"type": "remote",
"url": "http://localhost:8002/mcp",
"oauth": false,
"enabled": true,
"headers": {
"Authorization": "Bearer <your-jwt-token>"
}
}
}
}
}Set "oauth": false so OpenCode uses the static Authorization header instead of attempting OAuth discovery. Interpolate from the environment with "Authorization": "Bearer {env:YAMTRACK_JWT}".
Add to .vscode/mcp.json (workspace) or your user profile. VS Code uses the servers key and type: "http" for Streamable HTTP:
{
"servers": {
"yamtrack": {
"type": "http",
"url": "http://localhost:8002/mcp",
"headers": {
"Authorization": "Bearer <your-jwt-token>"
}
}
}
}VS Code tries Streamable HTTP first and falls back to SSE. Use ${input:yamtrack-token} in the header value to be prompted, or hard-code the token.
Hermes reads MCP servers from ~/.hermes/config.yaml under mcp_servers (YAML). Its MCP client speaks both stdio and HTTP, so point it at the HTTP endpoint:
mcp_servers:
yamtrack:
url: "http://localhost:8002/mcp"
headers:
Authorization: "Bearer <your-jwt-token>"claude_desktop_config.json is stdio-only and silently drops entries that use url / type: "http". For a local HTTP server, bridge it with mcp-remote (Node.js 18+):
{
"mcpServers": {
"yamtrack": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8002/mcp", "--transport", "http-only"],
"env": {
"MCP_REMOTE_HEADERS": "Authorization: Bearer <your-jwt-token>"
}
}
}
}The --transport http-only flag skips SSE negotiation. For a remote/self-hosted HTTPS instance, use Settings → Connectors → Add custom connector and paste https://your-yamtrack-instance.com/mcp/ instead (OAuth or API key).
If the client runs where Yamtrack's code is available (same host, or inside the container), launch the server directly — no HTTP, no bridge:
YAMTRACK_JWT=<your-jwt-token> uv run python src/manage.py run_mcp
# or inside the container:
docker exec -i yamtrack uv run python src/manage.py run_mcpPass the token via the YAMTRACK_JWT env var or the --token argument. Without a token only read-only tools work. Status messages are written to stderr so they don't corrupt the stdio JSON-RPC stream.
For clients on a machine without the Yamtrack code, use the standalone TypeScript stdio server. It talks to any Yamtrack instance over the REST API, so it needs no Django, no Python, and no HTTP bridge — just Node.js 18+.
Repo: yamtrack-mcp (also vendored as the mcp/ git submodule in the main repo).
git clone https://github.com/URD0TH/yamtrack-mcp
cd yamtrack-mcp
npm install
npm run build
node dist/index.js --helpConfigure it in stdio-only clients (e.g. Claude Desktop) directly, no mcp-remote needed:
{
"mcpServers": {
"yamtrack": {
"command": "node",
"args": ["/abs/path/to/yamtrack-mcp/dist/index.js"],
"env": {
"YAMTRACK_JWT": "<your-token>",
"YAMTRACK_BASE_URL": "https://your-yamtrack-instance.com/api"
}
}
}
}Auth precedence: --token / YAMTRACK_JWT, else --username + --password (mints a JWT and auto-refreshes it on expiry). Read-only tools work without a token. Exposes the same tools listed above plus manual_create, delete_entry, and get_me.
Supported media types for tools: tv, movie, anime, manga, game, book, comic, boardgame.
CompletedIn progressPlanningPausedDropped