nexus-mcp
140 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 — 74 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, verifies MD5 + SHA-256 checksums against the expected hashes, and enforces 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 |
NEXUS_MCP_TOOLS |
no | Tool profile: all (default), read (74 read-only tools only), or rw (all but the 12 destructive tools) |
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 verification, 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.- Web scraping (nexus_scrape_page, nexus_scrape_mod_page, nexus_scrape_mod_posts): read public nexusmods.com pages without an API key and consuming no quota - HTTPS only, SSRF-guarded; some pages may still be Cloudflare-blocked, in which case use the API tools instead.
Development
pip install -e ".[dev]" # editable install with pytest + ruff
python -m pytest # 95-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
Metadata
Release files for nexus-mods-mcp 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| nexus_mods_mcp-1.4.0.tar.gz | 82.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nexus_mods_mcp-1.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 149.3 kB
Release files / nexus_mods_mcp-1.4.0.tar.gz
| Download URL | nexus_mods_mcp-1.4.0.tar.gz |
|---|---|
| Size | 82.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6dce6f6a7ebe5ee691862bacf7d312de964138c7942d2c13a988584dcd48db69
|
|
BLAKE2b-256 checksum How to use checksums |
d7bb9f9b931dde8bcf688fece7946d1b1a0cfa9e9b178cca85ae0771c90be3c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / nexus_mods_mcp-1.4.0-py3-none-any.whl
| Download URL | nexus_mods_mcp-1.4.0-py3-none-any.whl |
|---|---|
| Size | 67.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4c3b26cffeea0985304a66933f2de48c90232dae925998c6ea12202f9fd79635
|
|
BLAKE2b-256 checksum How to use checksums |
5ac33e1a6eeda3b2fd6295c776328a423b42c67996ec0685c0b24c1263e7c61a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Security for nexus-mods-mcp 1.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.