Skip to content
opencode edited this page Jul 15, 2026 · 19 revisions

MCP Server Documentation

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.

Authentication

Send the token in the Authorization header:

Authorization: Bearer <token>

The MCP server accepts two token types:

Static API token (recommended)

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_mcp

This token also authorizes integration webhooks (Plex/Jellyfin/Emby), so treat it like any other API key.

JWT (REST API token)

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).

Docker / self-hosted (no account handy)

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.

Tools

Search & Browse

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

Tracked Media

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

Actions

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)

Statistics

Tool Parameters Description
get_statistics start_date, end_date Aggregated stats and activity data

Client Configuration

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), send Accept: application/json, text/event-stream; otherwise nginx returns 406.

OpenCode

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}".

VS Code

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

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

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).

Native stdio (same environment)

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_mcp

Pass 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.

Standalone TypeScript stdio server (yamtrack-mcp)

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 --help

Configure 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.

Media Types

Supported media types for tools: tv, movie, anime, manga, game, book, comic, boardgame.

Status Values

  • Completed
  • In progress
  • Planning
  • Paused
  • Dropped

Clone this wiki locally