Skip to main content
Glama

PackWarden — Thunderstore Mod-Pack MCP Server (v0.1.0)

PackWarden is not affiliated with or endorsed by Thunderstore. "Thunderstore" is used only to describe compatibility. Mod data comes from the public Thunderstore API (https://thunderstore.io).

An MCP server that helps AI assistants build and maintain Thunderstore mod packs (Lethal Company, Risk of Rain 2, Valheim, and every other Thunderstore community).

Tools

Tool

What it does

list_communities

List Thunderstore game communities (identifier + name).

search_mods

Search a community by name/owner/description/category; sort by relevance, downloads, rating, updated.

resolve_dependencies

Full transitive dependency closure for one or more packages/versions; final install set, missing deps, multi-version pins, optional tree.

check_pack_health

Audit a mod list: not found, removed version, deprecated, outdated, missing deps, dependency version conflicts, duplicates, NSFW.

export_r2modman_profile

Write an .r2z profile (r2modman / Thunderstore Mod Manager "Import profile → From file"), optionally with deps and config files. Nothing is uploaded.

Mods are referenced as Owner-Name (latest) or Owner-Name-1.2.3.

Related MCP server: nexus-mcp

Install

Requires Node.js ≥ 18.17.

git clone <repo> thunderstore-mcp && cd thunderstore-mcp
npm install && npm run build

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):

{
  "mcpServers": {
    "thunderstore": {
      "command": "node",
      "args": ["/absolute/path/to/thunderstore-mcp/dist/main.js"],
      "env": { "TSMCP_EXPORT_DIR": "/absolute/path/for/profiles" }
    }
  }
}

Restart Claude Desktop.

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
  "mcpServers": {
    "thunderstore": {
      "command": "node",
      "args": ["/absolute/path/to/thunderstore-mcp/dist/main.js"]
    }
  }
}

Streamable HTTP (remote / self-hosted)

npm run start:http            # http://127.0.0.1:3333/mcp
PORT=8080 HOST=0.0.0.0 node dist/main.js --http

Cursor: { "mcpServers": { "thunderstore": { "url": "http://127.0.0.1:3333/mcp" } } }. The HTTP mode is stateless (POST-only, JSON responses) and has no auth. Put it behind a reverse proxy with TLS and auth before exposing it.

Configuration (env)

Var

Default

Meaning

TSMCP_CACHE_DIR

~/.cache/thunderstore-mcp

Slim package-index cache

TSMCP_LIST_TTL_MS

3600000 (1h)

Package-list freshness

TSMCP_MIN_INTERVAL_MS

1000

Minimum gap between outbound requests

TSMCP_EXPORT_DIR

./exports

Where .r2z files are written

TSMCP_CONTACT

support@packwarden.dev

Contact put in the User-Agent. Override if you run your own copy.

TSMCP_BRAND

PackWarden

Brand in server name/User-Agent

TSMCP_BASE_URL

https://thunderstore.io

API base

Be a good API citizen

  • One full package list download per community per TTL, then conditional requests (If-Modified-Since). Results are cached on disk as a slim index.

  • Outbound requests are serialized (concurrency 1) and spaced ≥1s apart. On 429/5xx the client backs off and honours Retry-After.

  • Identifying User-Agent with a contact address.

  • If the network fails, the server keeps serving stale cache.

Tests (live API)

npm test                         # default community: valheim
TEST_COMMUNITY=valheim npm test

Tests cover stdio and streamable HTTP end-to-end against the live Thunderstore API.

Limitations

  • Large communities are heavy. The first load of Lethal Company is about 330 MB of JSON, takes about 14 s, and uses about 1.4 GB of RAM. After that, loads from cache take about 3 s.

  • Resolution follows r2modman behaviour (highest requested version wins). It does not do semver range solving, because Thunderstore pins exact versions.

  • No profile code sharing, which would need an upload to Thunderstore. Only file export is supported.

  • Search is local keyword scoring, not Thunderstore's own search ranking.

Available Tools

5 tools
check_pack_healthCheck mod pack healthA
Read-only

Audit a mod list: not found, removed versions, deprecated, outdated vs latest, missing dependencies, dependency version conflicts, duplicates.

NameRequiredDescriptionDefault
modsYesMods as "Owner-Name" or "Owner-Name-1.2.3"
communityYesThunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and network reach are known. The description adds real value by disclosing the specific diagnostics produced, but omits cost/scale behavior — with up to 500 mods and open-world lookups a call is potentially slow or rate-limited — and gives no hint of what the result object looks like despite there being no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the action first and the diagnostic list after; no filler, no restatement of the name. It reads as a bare feature enumeration rather than prose, which is efficient but slightly telegraphic.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only audit tool with no output schema, enumerating the report categories effectively substitutes for describing return values. What's missing is scale/performance context for a 500-item input and any mention of how results are ordered or whether failures are partial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the 'Owner-Name' / 'Owner-Name-1.2.3' format and the list_communities cross-reference, so the baseline of 3 applies. The description adds nothing about the parameters themselves — in particular it never explains that supplying a pinned version changes which checks apply (e.g. version conflicts vs outdated).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('Audit') plus resource ('a mod list') followed by an explicit enumeration of the seven conditions detected (not found, removed versions, deprecated, outdated, missing dependencies, version conflicts, duplicates). An agent knows exactly what the tool returns conceptually. It stops short of 5 because it never contrasts itself with the closely related resolve_dependencies sibling, which also operates on a mod list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: you call it when you want to audit a mod list. There is no statement of when to prefer it over resolve_dependencies (which presumably fixes the dependency issues this tool reports), no preconditions, and no note that the community must already be identified via list_communities (that hint lives only in the parameter schema).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_r2modman_profileExport r2modman profileA

Write an r2modman / Thunderstore Mod Manager profile file (.r2z) that can be imported via 'Import profile > From file'. Optionally resolves dependencies and bundles config files. Does not upload anything.

NameRequiredDescriptionDefault
modsYesMods as "Owner-Name" or "Owner-Name-1.2.3"
disabledNoMods to include but mark disabled
communityYesThunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover.
configFilesNoMap of relative path (e.g. "BepInEx/config/foo.cfg") to file contents
profileNameYes
includeDependenciesNoDefault true

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds useful behavior beyond annotations: it writes a local profile file and does not upload anything, clarifying the openWorldHint context. It does not disclose where the file is written, whether an existing file is overwritten, or what the return value is, which are important for a write operation with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with no filler. The output format and import path are front-loaded, and the negative scope is stated briefly at the end.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a file-writing tool with no output schema, the description covers purpose and key optional behaviors but omits crucial operational details: output file path/name, overwrite behavior, and return value. It is adequate but leaves gaps an agent would need to know before invoking it safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 83% schema description coverage, the schema already documents most parameters, including mods format, community examples, configFiles structure, and includeDependencies default. The description only implicitly references includeDependencies ('resolves dependencies') and configFiles ('bundles config files'), so it meets the baseline without adding much beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: writing an r2modman/Thunderstore profile file (.r2z) importable through 'Import profile > From file'. It also adds a clear negative scope ('Does not upload anything'), though it does not explicitly differentiate from sibling tools such as resolve_dependencies or search_mods.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives context for the output (a profile file for manual import) and notes optional dependency resolution and config bundling, which implies when to enable those features. However, it does not explicitly state when to use this tool versus resolve_dependencies or check_pack_health, nor does it give exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_communitiesList Thunderstore communitiesB
Read-only

List game communities (identifier + name) on Thunderstore. Cached 24h.

NameRequiredDescriptionDefault
filterNo

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and network behavior are covered. The description adds one genuinely non-obvious trait: results are cached for 24h, which matters for staleness expectations. It stops there, saying nothing about ordering, size of the result set, or whether the cache is bypassable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the purpose and followed by the caching note; nothing is padded. It is close to optimally sized for a trivial read tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter read tool with no output schema, the description covers the resource and return fields, which is most of what an agent needs. The undocumented filter parameter and the absence of guidance on consuming the identifiers leave a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One parameter (filter) has 0% schema description coverage, so the description carries the full burden and says nothing about it. It's unclear whether filter is a substring/prefix match on name or identifier, case sensitivity, or behavior when empty — the caller must guess.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ("List game communities ... on Thunderstore") and even names the returned fields (identifier + name), so an agent knows exactly what comes back. It doesn't explicitly distinguish itself from siblings like search_mods or resolve_dependencies, but the resource noun makes the separation obvious.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No statement of when to call this versus alternatives, and no mention that the identifiers returned are inputs to the other community-scoped tools (search_mods, resolve_dependencies). The use case is inferable but never stated, and no exclusions or prerequisites are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_dependenciesResolve dependenciesA
Read-only

Full transitive dependency closure for one or more package versions (latest if no version given). Returns final install set (highest requested version wins, as r2modman does), missing deps, multi-version pins, and the tree.

NameRequiredDescriptionDefault
packagesYesMods as "Owner-Name" or "Owner-Name-1.2.3"
communityYesThunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover.
includeTreeNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

This description adds significant behavioral context beyond the simple 'readOnlyHint' annotation. It explicitly lists all return states (final install set, missing deps, multi-version pins, and the tree), detailing the complex outputs of the closure operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is highly dense and functional. It front-loads the most important technical term ('Full transitive dependency closure') and defines the scope of the operation in a single, efficient paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of dependency management and the lack of an output schema, this definition is exceptionally complete. It covers the input logic, the conflict resolution rules, and precisely what data the agent can expect back.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

While schema coverage is moderate at 67%, the description adds crucial semantic meaning. It clarifies that the input `packages` are used for dependency resolution, not merely listing files, and connects the `includeTree` flag to a specific structural output ('the tree').

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the core purpose: calculating 'Full transitive dependency closure.' It specifies the resource (package versions) and the specific technical function performed by the tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides helpful usage rules by stating how the tool handles missing parameters ('latest if no version given'). It also sets expectations regarding logic, noting that 'highest requested version wins,' guiding the agent on the tool's internal decision-making process.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_modsSearch modsA
Read-only

Search a community's mods by name/owner/description/category. First call per community downloads and caches the full package list (can take 10-60s for large games).

NameRequiredDescriptionDefault
sortNo
limitNo
queryYesSearch words; empty string lists top mods
categoryNo
communityYesThunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover.
includeNsfwNo
includeDeprecatedNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint) and open-world reach, and the description adds a genuinely non-obvious behavioral trait: the first call per community downloads and caches the full package list, taking 10-60s on large games. That latency warning is exactly what an agent needs to plan around; it lacks detail on cache invalidation or freshness, keeping it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the search scope leads, and the latency caveat follows. No filler, no restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no output schema, the description covers the core search behavior and the cold-cache cost but leaves optional parameters (sort, limit, includeNsfw, includeDeprecated) and result-shape/limit expectations unexplained. Adequate to call the tool, not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low (29%), so the description should compensate more. It does add real meaning by enumerating the searchable fields, but says nothing about sort, limit, includeNsfw, includeDeprecated, or defaults, leaving most optional parameters undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search a community's mods') plus the fields searched (name/owner/description/category), which is enough to distinguish it from unrelated siblings like resolve_dependencies or list_communities. It stops short of explicitly naming the adjacent alternatives or when to prefer them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the community-scoped search framing but gives no explicit when-to-use/when-not guidance and no mention of alternatives (e.g., list_communities for discovery). The caching note is operational context rather than routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updates
    • First observedcheck_pack_health
    • First observedexport_r2modman_profile
    • First observedlist_communities
    • First observedresolve_dependencies
    • First observedsearch_mods

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct action: listing communities, searching mods, resolving dependencies, auditing a pack, and exporting a profile. There is mild overlap between resolve_dependencies and check_pack_health (both report missing dependencies) and between resolve_dependencies and export_r2modman_profile (which can optionally resolve), but the descriptions clearly delineate the primary intent of each.

Naming Consistency5/5

All five tools follow a strict verb_noun snake_case pattern: resolve_dependencies, search_mods, check_pack_health, export_r2modman_profile, list_communities. No camelCase or stylistic deviations; 'r2modman' is a proper noun used consistently within a well-formed name.

Tool Count5/5

Five tools is a tight, purpose-fit surface for a Thunderstore/r2modman pack workflow: discover, search, resolve, validate, export. No tool feels redundant or vestigial, and nothing obviously needed for the core loop is missing from the count.

Completeness3/5

The surface covers discovery through export, but has notable gaps: no way to inspect a single mod's details/version history, no tool to read or parse an existing profile (import is only via the external manager), and no explicit dependency download/fetch step. Agents can work around some of this via resolve_dependencies and search_mods, but profile inspection is a dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to search, browse, and manage mods across Nexus Mods, mod.io, Thunderstore, and Modrinth, as well as perform local diagnostics like detecting games and parsing crash logs.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local MCP server for Nexus Mods mod discovery and research, backed by the v2 GraphQL API, enabling search of games, mods, collections, and users.
    121 npm
    1
    ISC
  • A
    license
    A
    quality
    B
    maintenance
    Enables creating Minecraft modpack structures, searching Modrinth mods, resolving dependencies, and checking compatibility.
    8
    391 npm
    MIT