PackWarden
OfficialProvides tools for working with the public Thunderstore mod-pack API: lists game communities, searches mods by name/owner/description/category (with sorting by relevance, downloads, rating, or update time), resolves full transitive dependency closures for packages and versions (including missing deps and multi-version pins), audits a mod list for problems such as removed versions, deprecations, missing dependencies, version conflicts, duplicates, and NSFW flags, and exports r2modman/Thunderstore Mod Manager profile files (.r2z) optionally including dependencies and config files.
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 Thunderstore game communities (identifier + name). |
| Search a community by name/owner/description/category; sort by relevance, downloads, rating, updated. |
| Full transitive dependency closure for one or more packages/versions; final install set, missing deps, multi-version pins, optional tree. |
| Audit a mod list: not found, removed version, deprecated, outdated, missing deps, dependency version conflicts, duplicates, NSFW. |
| Write an |
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 buildClaude 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 --httpCursor: { "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 |
|
| Slim package-index cache |
|
| Package-list freshness |
|
| Minimum gap between outbound requests |
|
| Where |
|
| Contact put in the User-Agent. Override if you run your own copy. |
|
| Brand in server name/User-Agent |
|
| 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 testTests 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 toolscheck_pack_healthCheck mod pack healthARead-only
Audit a mod list: not found, removed versions, deprecated, outdated vs latest, missing dependencies, dependency version conflicts, duplicates.
| Name | Required | Description | Default |
|---|---|---|---|
| mods | Yes | Mods as "Owner-Name" or "Owner-Name-1.2.3" | |
| community | Yes | Thunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| mods | Yes | Mods as "Owner-Name" or "Owner-Name-1.2.3" | |
| disabled | No | Mods to include but mark disabled | |
| community | Yes | Thunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover. | |
| configFiles | No | Map of relative path (e.g. "BepInEx/config/foo.cfg") to file contents | |
| profileName | Yes | ||
| includeDependencies | No | Default true |
TDQS
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.
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.
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.
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.
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.
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 communitiesBRead-only
List game communities (identifier + name) on Thunderstore. Cached 24h.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No |
TDQS
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.
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.
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.
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.
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.
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 dependenciesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| packages | Yes | Mods as "Owner-Name" or "Owner-Name-1.2.3" | |
| community | Yes | Thunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover. | |
| includeTree | No |
TDQS
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.
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.
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.
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.
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.
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 modsARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | ||
| limit | No | ||
| query | Yes | Search words; empty string lists top mods | |
| category | No | ||
| community | Yes | Thunderstore community identifier, e.g. "lethal-company", "riskofrain2", "valheim". Use list_communities to discover. | |
| includeNsfw | No | ||
| includeDeprecated | No |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
- First observed
check_pack_health - First observed
export_r2modman_profile - First observed
list_communities - First observed
resolve_dependencies - First observed
search_mods
TDQS
Scored across 5 tools
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.
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.
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.
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
Related MCP Connectors
Package versions, licences and known vulnerabilities for npm, PyPI, crates, Go, Maven, NuGet
Check Dart/Flutter dependencies on pub.dev for updates and manage monitored projects.
Market data tools for the MCP ecosystem: server stats, events, search, leaderboards, package trends.
What breaks between versions, vulnerabilities, compatible versions, EOL dates: npm, PyPI, Rust, PHP.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables 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
- AlicenseNot gradedqualityCmaintenanceA 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 npm1ISC
- AlicenseAqualityBmaintenanceEnables creating Minecraft modpack structures, searching Modrinth mods, resolving dependencies, and checking compatibility.8391 npmMIT
- AlicenseBqualityBmaintenanceEnables reading, validating, and managing Minecraft resource packs, including structure checks, asset listing, pack comparison, and Modrinth queries.9417 npmMIT