nexus-mcp
135 MCP tools for Nexus Mods — wraps the official REST API v1 and GraphQL API v2 as a Model Context Protocol server (Python + FastMCP, stdio transport). Lets any MCP client (Claude Desktop, opencode, Cursor, ...) browse games, inspect mods and files, run free-text searches, download mod files with checksum verification, manage endorsements, comments, collections, and user preferences.
Highlights
- Full API coverage — 69 read tools + 66 mutations across v1 REST and v2 GraphQL. Includes things v1 doesn't offer: free-text mod search, batch mod lookups, comment threads, collection lifecycle, and quota-free GraphQL reads.
- Built-in TTL cache — repeated identical GETs within a session don't consume quota
(games 1h, mod/file data 5 min, GraphQL POSTs 60 s). Personal state (
/user/*) is never cached. - Dual authentication — personal API key out of the box; optional OAuth2 (PKCE S256) with auto-refresh for user-context mutations that API keys cannot perform.
- Safe downloads —
nexus_download_mod_filestreams from the CDN to disk with MD5 + SHA-256 verification and a configurable size cap. - Rate-limit transparency — every v1 response carries an
_rlsnapshot of Nexus' hourly/daily limit headers.
Install
# uv (recommended for MCP servers)
uvx --from nexus-mods-mcp nexus-mcp
# pipx
pipx install nexus-mods-mcp
# pip
pip install nexus-mods-mcp
Or from a cloned repository:
pip install -r requirements.txt
python -m nexus_mcp
Works with every MCP harness
Create an API key at https://www.nexusmods.com/users/myaccount?tab=api%20access, then pick your harness below. The server is a single stdio process — no ports, no daemons, no database.
Zero-install (recommended): run from PyPI with uvx — nothing to clone,
no venv to manage, auto-fetched on first run:
{
"mcpServers": {
"nexus": {
"command": "uvx",
"args": ["--from", "nexus-mods-mcp", "nexus-mcp"],
"env": { "NEXUS_API_KEY": "<your-key>" }
}
}
}
If you installed locally (pipx install nexus-mods-mcp),
use "command": "nexus-mcp" without the uvx wrapper instead.
Claude Code (one-liner)
claude mcp add nexus -e NEXUS_API_KEY=<your-key> -- uvx --from nexus-mods-mcp nexus-mcp
opencode (opencode.json)
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"nexus": {
"type": "local",
"command": ["uvx", "--from", "nexus-mods-mcp", "nexus-mcp"],
"enabled": true,
"environment": {
"NEXUS_API_KEY": "<your-key>"
}
}
}
}
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"nexus": {
"command": "uvx",
"args": ["--from", "nexus-mods-mcp", "nexus-mcp"],
"env": {
"NEXUS_API_KEY": "<your-key>"
}
}
}
}
Cursor / Windsurf / Cline (any mcpServers JSON)
Same shape as the generic JSON above. Paste the mcpServers block into:
Cursor — .cursor/mcp.json · Windsurf — ~/.codeium/windsurf/mcp_config.json ·
Cline — extension MCP server settings.
VS Code (.vscode/mcp.json)
{
"servers": {
"nexus": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "nexus-mods-mcp", "nexus-mcp"],
"env": {
"NEXUS_API_KEY": "<your-key>"
}
}
}
}
Gemini CLI (~/.gemini/settings.json)
{
"mcpServers": {
"nexus": {
"command": "uvx",
"args": ["--from", "nexus-mods-mcp", "nexus-mcp"],
"env": {
"NEXUS_API_KEY": "<your-key>"
}
}
}
}
Codex CLI (~/.codex/config.toml)
[mcp_servers.nexus]
command = "uvx"
args = ["--from", "nexus-mods-mcp", "nexus-mcp"]
env = { "NEXUS_API_KEY" = "<your-key>" }
Environment variables
| Variable | Required | Description |
|---|---|---|
NEXUS_API_KEY |
yes | Personal API key from Nexus Mods |
NEXUS_OAUTH_CLIENT_ID |
no | OAuth client ID (see below) |
NEXUS_OAUTH_CLIENT_SECRET |
no | Only for non-public OAuth apps |
NEXUS_OAUTH_REDIRECT_URI |
no | Defaults to http://localhost/callback |
NEXUS_OAUTH_TOKEN_FILE |
no | Token store path, defaults to ~/.nexus-mcp/oauth-tokens.json |
Authentication
API key works for all public reads and most mutations. Note that the key itself is
not an authorization scope: some user-context mutations (e.g.
nexus_update_mod_direct_download) are rejected with API-key auth even for the mod's
owner — Nexus requires an OAuth user context for those.
OAuth (optional). Nexus has no self-service OAuth app registration; email
support@nexusmods.com with your app name, description, logo, source link, and callback
URI to obtain a client_id. Then run the two-step flow:
nexus_oauth_login→ returns anauthorize_url(state + PKCE challenge); open it, log in, and copy thecodefrom the redirect URL.nexus_oauth_exchange(code)→ exchanges the code for tokens, persists them toNEXUS_OAUTH_TOKEN_FILE, and validates your identity.
Tokens last ~6 h and auto-refresh (a 4xx refresh response is treated as revocation and
falls back to API-key auth). Companion tools: nexus_oauth_status, nexus_oauth_refresh,
nexus_oauth_logout. The public scope is sufficient; Bearer auth is accepted on both
v1 REST and v2 GraphQL.
Rate limits & quota
- v1 REST: 2000 requests/hour, 20 000/day per key. Every v1 response includes an
_rlsnapshot (X-RL-*headers) so agents can self-throttle. - v2 GraphQL has its own rate-limit pool and does not consume v1 quota — prefer v2
tools (
nexus_search_mods,nexus_get_mod_v2,nexus_get_mods_batch, ...) for searches and public data. - The server-side TTL cache (see Highlights) further reduces quota usage for repeated reads within a session.
Tool catalog
v1 REST (core)
| Tool | Description |
|---|---|
nexus_validate_key |
Check API key + account info (exempt from rate limits) |
nexus_get_games / nexus_get_game |
Game catalog (substring filter) / one game + categories |
nexus_get_mod / nexus_get_mod_changelogs |
Mod details (endorsements, downloads, description) / changelog per version |
nexus_get_latest_added / nexus_get_latest_updated / nexus_get_trending |
10 newest / updated / trending mods for a game |
nexus_get_updated_mods |
Mods with activity in the last 1d/1w/1m |
nexus_get_mod_files / nexus_get_file_info |
Mod file list (category filter) / one file's details (MD5, size, version) |
nexus_get_download_link |
Short-lived CDN download URL (non-premium needs key+expires from a .nxm link) |
nexus_download_mod_file |
Stream a file to disk (MD5+SHA-256 verified, max_bytes cap) |
nexus_search_by_md5 |
Identify a mod/file from an MD5 hash |
nexus_get_tracked_mods / nexus_track_mod / nexus_untrack_mod |
Manage tracked mods |
nexus_get_endorsements / nexus_endorse_mod / nexus_abstain_endorsement |
Manage endorsements |
v2 GraphQL (does not consume v1 quota)
| Tool | Description |
|---|---|
nexus_search_mods |
Free-text mod search (wildcard) + game/endorsement/download filters + sort + pagination |
nexus_get_mod_v2 |
Full mod details: raw BBCode description, tags, requirements, complete file list |
nexus_get_mods_batch |
Resolve many mods in one query: "domain:modId,domain:modId" |
nexus_get_mod_endorsers |
Users who endorsed a mod (cursor pagination) |
nexus_search_games / nexus_get_game_v2 |
Game search / rich game details (genre, forum, counts, Vortex support) |
nexus_resolve_domain |
Resolve a game display name (e.g. 'Skyrim Special Edition') to its domain_name slug — call before any tool needing domain_name |
nexus_get_files_v2 / nexus_get_files_by_uid |
File lists via v2 (by domain/modId or by uid) |
nexus_search_users / nexus_get_user_v2 / nexus_get_user_by_name |
User search (fuzzy) / public profile by id or username / exact username lookup |
nexus_search_collections / nexus_get_collection / nexus_get_collection_revision |
Collection search / details by slug / single revision |
nexus_get_categories / nexus_get_category_by_id / nexus_get_collection_games |
Collection categories (per-game or global) |
nexus_get_tags / nexus_get_tags_v2 / nexus_get_tag_by_id / nexus_get_tag_categories / nexus_get_tag_category_by_id |
Tag taxonomy |
nexus_get_comment_thread / nexus_get_comment / nexus_search_comments |
Comment reads (⚠️ search_comments is 500-ing server-side at Nexus; use get_comment_thread instead) |
nexus_get_badges |
Static catalog of earnable mod badges |
nexus_get_news |
Site/game news, interviews, features (filter by category/game) |
nexus_graphql_query / nexus_graphql_introspect |
Raw GraphQL escape hatch / schema introspection |
nexus_get_age_verification_info / nexus_get_api_applications / nexus_get_current_warnings |
Account state reads |
nexus_get_external_video / nexus_get_game_artwork / nexus_get_legacy_mods / nexus_get_file_hash(es) |
Media + legacy lookups |
nexus_search_media |
Site-wide media search (⚠️ Nexus endpoint is intermittently flaky — retry) |
nexus_get_preferences / nexus_update_preferences |
Site preferences (emails, default tabs, download location...) |
nexus_get_user_donation_preferences / nexus_update_user_donation_preferences |
Donation Points preferences |
nexus_get_favourite_games / nexus_add_favourite_game / nexus_remove_favourite_game |
Favourite games |
nexus_get_ignored_users / nexus_ignore_user / nexus_unignore_user |
Ignored users |
nexus_get_blocked_tags / nexus_block_tag / nexus_unblock_tag |
Blocked tags |
nexus_track_user / nexus_untrack_user |
Track/untrack users for update notifications |
nexus_give_kudos / nexus_remove_kudos |
Kudos |
nexus_like_comment / nexus_remove_comment_like |
Comment likes |
nexus_create_comment / nexus_edit_comment / nexus_discard_comment / nexus_restore_comment |
Comment mutations (nested replies via reply_to_id) |
nexus_create_message / nexus_upload_attachment |
Private messages (multipart attachments) |
nexus_update_about_me / nexus_update_country |
Profile updates |
nexus_get_speedtest_urls |
CDN speedtest endpoints |
nexus_get_opted_in_mods / nexus_get_transactions / nexus_get_user_monthly_summary / nexus_get_user_monthly_report / nexus_get_user_monthly_report_by_id |
Donation Points reporting (⚠️ some data is hidden under API-key auth — OAuth required) |
nexus_get_uploads |
Upload activity with scan status |
Collections, moderation & misc mutations
| Tool | Description |
|---|---|
nexus_create_collection / nexus_edit_collection |
Create/edit collections (manifest, BBCode description) |
nexus_create_or_update_revision / nexus_update_revision / nexus_publish_revision / nexus_retract_revision / nexus_discard_revision |
Revision lifecycle |
nexus_list_collection / nexus_unlist_collection / nexus_discard_collection |
Collection visibility lifecycle |
nexus_create_changelog / nexus_update_changelog |
Revision changelogs |
nexus_create_tag / nexus_update_tag / nexus_discard_tag |
Tag management (moderator) |
nexus_add_badge_to_collection / nexus_remove_badge_from_collection / nexus_reorder_item |
Collection content management |
nexus_close_collection_bug_report |
Close bug reports on your collections |
nexus_submit_moderation_fix |
Submit fixes for moderated content |
nexus_hide_comment / nexus_lock_comment / nexus_lock_comment_thread / nexus_pin_comment / nexus_unpin_comment / nexus_reorder_pinned_comments / nexus_clear_comment_moderation_status / nexus_clear_comment_thread_moderation_status |
Comment moderation (moderator/owner) |
nexus_block_mods_from_earning_dp / nexus_unblock_mods_from_earning_dp |
Donation Points earning control (moderator) |
nexus_track_app_metric |
App metrics (e.g. Vortex collection installs) |
nexus_update_mod_direct_download |
Toggle direct downloads on your own mods (OAuth required) |
nexus_start_age_verification_flow / nexus_start_age_verification_appeal_flow |
Age verification flows |
nexus_request_media_upload_url / nexus_get_collection_revision_upload_url |
Presigned upload URLs |
nexus_oauth_login / nexus_oauth_exchange / nexus_oauth_status / nexus_oauth_refresh / nexus_oauth_logout |
OAuth2 flow (PKCE S256, auto-refresh, apikey fallback) |
API quirks worth knowing
domain_nameis the lowercase URL slug (e.g.forzahorizon6,skyrimse) — not the display name.- Download links are short-lived; don't cache them. Non-premium accounts must pass the
key/expirespair extracted from a.nxmlink generated on the website. - Preference mutations (
ignore_user,block_tag, ...) apply immediately but list reads can lag a few seconds behind (eventual consistency). nexus_discard_commentis effectively one-way under API-key auth: restoring requires OAuth Bearer auth.- The v1 categories endpoint (
/v1/games/{domain}/categories.json) was removed by Nexus — categories are only available via v2. nexus_search_commentscurrently returns HTTP 500 from Nexus itself, regardless of parameters;nexus_get_comment_threadis the working alternative.- Scraping the nexusmods.com website directly gets blocked by Cloudflare — use the API tools instead.
Development
pip install -e ".[dev]" # editable install with pytest + ruff
python -m pytest # 72-test suite, fully offline (mocked HTTP)
python -m ruff check nexus_mcp tests
python -m nexus_mcp # run on stdio
CI runs on every push: ruff lint, pytest across ubuntu/windows (Python 3.10–3.12),
pip-audit, build + twine check + wheel smoke test, and an optional live API smoke test.
Tagged releases (v*) publish to PyPI automatically.
Contributing
Contributions are welcome! See CONTRIBUTING.md for setup, the tool-authoring checklist, and conventions. Bug reports and feature requests use the issue templates; questions and ideas go to Discussions; security issues go through private vulnerability reporting.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nexus_mods_mcp-1.2.0.tar.gz.
File metadata
- Download URL: nexus_mods_mcp-1.2.0.tar.gz
- Upload date:
- Size: 62.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3be251ea04568a728d500eeb799bef5848875111a2d89f81b8c8eb06a32461db
|
|
| MD5 |
59d3484e82a6d1fa1e6aa25860970661
|
|
| BLAKE2b-256 |
a0e2733e53e2a832e31c2fd9fab939e91a9f64512c1004ced74dc4b722649808
|
File details
Details for the file nexus_mods_mcp-1.2.0-py3-none-any.whl.
File metadata
- Download URL: nexus_mods_mcp-1.2.0-py3-none-any.whl
- Upload date:
- Size: 56.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ace58bca25e7d63342deb681698de6a5d85bf5cd11f0200fa3038ce402924c2
|
|
| MD5 |
e9b902542d276cc1765020fb9e3b9577
|
|
| BLAKE2b-256 |
b3bc2be60adbfe8c227b56e1a4f2da9caa32dfecf651b04221da52d764e3a063
|