Skip to main content
Glama

curseforge-ark-mcp

一个只读 MCP 服务器,用于《方舟:生存飞升》的 CurseForge MOD 管理、发现和更新监控。

这仍然是 v0 版本——部分验证,尚未完全验证。

2026-08-18 更新内容: CurseForge API 密钥已到账,客户端发出了首次认证调用,并且 它所读取的每个 Mod 和 File 字段路径均在实时响应中确认存在,无需修正。 样本:748 个不同的《方舟:生存飞升》MOD,1899 条文件记录。

为何仍是 v0 版本。 还有四项未确认,其中一项无法通过观察确认:

  • FileDependency 边缘形状 从未被观察到——在 1899 个抽样的 ASA 文件中,有 0 个声明了依赖关系,dependencies 数组每次都存在但为空。

  • FileRelationType 的整数值既未公开,也未在此目录中实际使用过。

  • 已观察到 FileReleaseType 的整数值 1、2 和 3,但哪个对应发布版、测试版或 Alpha 版仍未知,本服务器不会猜测。

  • 任何 供应商对批量读取 ID 数组的限制:在 300 个 ID 以内未发现限制,因此未知。

部分验证的客户端不等于已验证的客户端。版本号是对验证状态的声明,因此它是 0.2.0——而不是 1.0.0,也不刻意是 1.0.0-anything。

此仓库自身的行为是独立于 API 验证的:端点允许列表、主机锁定、路径规范化、分页边界、信封处理以及三态(缺失/空/未知)规则。所有这一切都通过一个注入的假 fetch 进行了测试,无需密钥,无需网络。截至撰写时,156 项测试,0 个失败。

设计记录:docs/adr/ADR-002-endpoint-allow-list.md(状态:已提议)。以下所有章节引用(§1、§4.3、§14.3 …)均指向该文档。


Related MCP server: neoforge-kb-mcp

它能做什么,以及它刻意不能做什么

七个工具,全部只读:

工具

回答的问题

search_mods

“哪些 ASA MOD 匹配此搜索词?”

get_mod

“项目 777001 是什么?”

list_mod_files

“此 MOD 发布了哪些文件?”

get_mod_file

“这个特定文件是什么?”

get_latest_file

“对于我正在运行的 MOD,是否有更新的文件?”

resolve_mod_dependencies

“此 MOD 依赖哪些内容?”(批量处理,每个树层级一次请求)

get_api_diagnostics

“是我、密钥还是 CurseForge 的问题?”——以及“此构建有多诚实?”

它不能:

  • 下载或安装任何内容。 GET /v1/mods/{modId}/files/{fileId}/download-url 是一个有文档记录的只读端点,位于锁定主机上,但被拒绝——因为它不在端点允许列表中(DEC-002 §11.3)。Nitrado 会自行安装 MOD。

  • 写入任何内容,任何地方。 允许列表中没有任何条目指向可变端点。CurseForge 确实在不同的主机上运行一个可变的上传 API(§14.2);主机锁定出于另一个独立原因再次拒绝它。

  • 发布或创作 MOD。 直接被拒绝(DEC-002 裁决 2)。由启动断言强制执行,而非承诺:注册任何声明非第一层级的工具会导致进程拒绝启动。

  • 触及 Nitrado。 此仓库的配置界面中不存在任何 NITRADO_* 变量,并且其缺失本身就是一种控制。此服务器不持有任何 Nitrado 令牌,也不读取任何 Nitrado 配置。

  • 定时唤醒并更新你的服务器。 没有调度器,没有轮询循环,没有持久化的“上次看到版本”状态(§10)。监控意味着模型可能观察到新版本,但它无法采取行动。


瓶颈:端点允许列表,而非方法检查

这是唯一一个在接触代码之前值得阅读的设计决策。

CurseForge 使用 POST 来读取。POST /v1/mods 和 POST /v1/mods/files 是批量检索,正是它们使得 resolve_mod_dependencies 每个依赖层级只需一次请求,而不是每个节点一次。因此,兄弟仓库的 method !== "GET" → refuse 在这里会以最昂贵的方式失败:它会工作。它会拒绝一些东西,通过自己的测试,然后悄悄地使服务器无法胜任其工作。

而明显的修复方案比 bug 本身更糟糕:

allowed = { GET }          → the batch reads are refused (broken, loudly)
allowed = { GET, POST }    → every request this client can construct is allowed

有文档记录的目录 API 仅包含 GET 和 POST。一个同时允许两者的门控会允许一切——同时看起来仍然正常。

因此,每个出站请求必须匹配一个封闭的 {method, path} 对列表中的显式条目。共七个条目,位于 src/allowlist.ts 中:

#

方法

路径

服务于

E1

GET

/v1/games

游戏 ID 解析,get_api_diagnostics

E2

GET

/v1/mods/search

search_mods

E3

GET

/v1/mods/{modId}

get_mod,get_latest_file

E4

GET

/v1/mods/{modId}/files

list_mod_files,get_latest_file

E5

GET

/v1/mods/{modId}/files/{fileId}

get_mod_file

E6

POST

/v1/mods

resolve_mod_dependencies (批量读取)

E7

POST

/v1/mods/files

resolve_mod_dependencies (批量读取)

机制上:

  • 联合匹配 {method, path}。E3 不授权 DELETE /v1/mods/123。E6 不授权 POST /v1/mods/123。

  • 主机被锁定到 https://api.curseforge.com,并且该锁定是允许一个来源,而非拒绝任何指定的其他来源。

  • ID 段绑定到 [0-9]+,而不是 [^/]+。 这是关键:宽松的 {modId} 会使 E3 吞掉 /v1/mods/search。数字绑定使得这种歧义在结构上不可能,而不是依赖于匹配顺序——并且有一个测试反转了整个列表,以证明顺序并非其保护机制。

  • 在检查之前进行一次规范化,URL 由其输出构建。百分号解码一次;拒绝任何存活的 %;折叠反斜杠;拒绝 .、.. 和空段。

  • 只有 E6/E7 可以携带请求体,在分发前进行形状检查。GET 条目上的请求体将被拒绝,而非丢弃。

  • 只有 resolve_mod_dependencies 可以访问 POST 条目(§8),在传输层强制执行。

失败模式是“未匹配的请求被拒绝”,绝不会是“未识别的请求被发送。” 添加功能是一个可审查的单行差异,其审查问题——“这个端点是只读的吗?”——是人类可以回答的。

证明它是一个允许列表的测试

GET /v1/mods/{modId}/files/{fileId}/download-url 被拒绝。它是一个有文档记录的只读端点,一个 GET,位于锁定主机上,具有格式良好的数字 ID。它被拒绝纯粹是因为它不在列表中。如果该测试因其他原因通过——主机锁定拒绝、路径拒绝——则该属性并未实现,因此测试断言了拒绝的代码和细节,而不仅仅是某个东西抛出了异常。

每个拒绝测试还断言了假 fetch 的调用次数,因为“在请求构建之前被拒绝”才是真正的规定,而分派之后抛出的错误可以满足一个较弱的断言。并且拒绝测试套件之前有一个原像测试,证明所有七个条目确实进行了分派——一个针对无法发送任何内容的客户端的拒绝测试套件可以完美通过,但证明不了任何东西。


已针对实时 API 验证——2026-08-18

样本:748 个不同的 ASA MOD,1899 条文件记录,来自深度搜索页面(索引 1000-6000)以及每个有文档记录的 sortField 1-12,加上 100 个 MOD 的完整文件列表。故意标注了日期和大小:“已验证”而没有样本量只是一种情绪,而非声明。

#

声明

结果

U1

ASA 的 gameId

83374,slug 为 ark-survival-ascended,名称为 ARK Survival Ascended——没有冒号,精确匹配的拼写会出错。仍然在每次启动时实时解析;一个测试断言该数字在 src/ 中除了注释之外任何地方都不出现。

U2

ASA 对密钥可见吗?

是的。 可见 38 个游戏,ASA 在其中。不阻止 v1。

U3

Mod 字段路径

全部正确。 id、gameId、name、slug、dateModified、links.websiteUrl、categories、allowModDistribution、latestFiles、latestFilesIndexes。

U4

File 字段路径

全部正确。 id、modId、displayName、fileName、fileDate、gameVersions、sortableGameVersions、dependencies、releaseType、isAvailable。

U8

pagination 存在性

存在于分页端点(游戏、搜索、文件)上,不存在于单条记录和批量读取中——这完全符合此客户端构建时预期的分裂。

U9

ASA MOD 是否填充了可选字段?

latestFiles、latestFilesIndexes、sortableGameVersions、gameVersions:300/300。dependencies:100% 存在,0% 非空。

U11

速率限制头

CurseForge 不发送任何限速头。 对实时 GET 和 POST 的完整头部枚举仅发现传输/CDN 头部。因此,null 在此客户端中不是匹配错误——但这不是声称不存在限制,并且自我施加的节流措施仍然存在。

U12

索引 0 之后的分页

有效;totalCount 在页面间稳定在 6848。但在结果集末尾之后,CurseForge 返回 resultCount: 0 和 totalCount: 0——totalCount 描述的是响应,而非查询。工具输出现在显示“已超出末尾”,而不是让人理解为“未找到任何内容”。

U13

基础 URL

正确。主机锁定是可靠的。

无需修正任何字段路径。 这并非自夸,而是记录事实:兄弟仓库的提交 5481c04 在首次调用真实API时就修正了三个错误的路径,正是这一先例促使这里每个路径都逐一检查,而非盲目信任。

仍未验证

范围缩小了,但并未消失。以下是经受住真实API考验的行。

#

声明

状态

为何仍开放

U5

FileDependency = { modId, relationType }

未观测到

未被证明错误——从未见过。样本中无ASA文件声明依赖关系,因此从未检查过任何边对象。其形状源自文档,且仅存在于测试夹具中。

U6

FileRelationType 数值枚举

未发布且此处不可观测

所有1899个文件(来自748个Mod)均存在dependencies字段且为空,因此从未出现关系整数。ADR-002曾预测此情况并指明了后果:未映射整数的遍历是答案,而非临时方案。实际效果:对于ASA,resolve_mod_dependencies返回单节点树,且其输出中已明确说明,因此空树不会被视为失败。

U7

FileReleaseType 数值枚举

值已见,含义未知

观察到:1(1893个文件)、2(3个)、3(3个)。至少三个成员,与上传API的alpha/beta/release三件套一致——但完全无证据表明哪个整数对应哪个。频率分布不等于值表。因1最常见而推断1 = release,正是本仓库拒绝采纳的猜测。

U10

供应商对批量读取ID数组的限制

未发现上限,测试至300

200个不同ID返回200条记录;300个返回300条。因此,限制(如果有)高于300。本客户端中的200个ID限制保持不变:这是我们主动设置的保守限制,以应对未记录速率限制,而一次未发现上限的探测并不等于找到了上限。

在工具输出中你将看到两个后果

relationType 和 releaseType 以原始整数形式呈现,且永不映射。 不会映射为 required/optional,也不会映射为 release/beta/alpha。CurseForge 未发布两者的值表,错误的标签会导致依赖列表或更新推荐出错,且无人会检查。因此,resolve_mod_dependencies 遵循每条边并明确说明:它会过度收集,其输出中会明确陈述这一点。一张大网至少是可见的大网。

具体到ASA,实时目录使得这一点变得无关紧要,这一点在使用工具前值得了解:样本中没有任何ASA Mod声明任何依赖关系。 单节点树是预期结果,而非遍历出错的症状,工具的输出来说明是哪一种情况。

get_latest_file 要求你明确“最新”的含义。 按 fileDate 最新、匹配游戏版本最新、以及具有特定 releaseType 最新,会给出不同的答案,而基于错误答案做出的Mod更新决策,正是本仓库要避免的确信错误答案类别。selection 没有默认值:

selection

同时需要

含义

newest_by_file_date

—

所有候选文件中按 fileDate 最新者

newest_matching_game_version

game_version

声明该游戏版本的最新文件

newest_with_release_type

release_type(原始整数)

携带该发布类型整数的最新文件

没有命名的 release/beta/alpha 过滤器,因为U7未解决,且本服务器不会自行编造映射。你传入你想要的整数。

此定义是一个开放的产品问题。 ADR-002的开放问题2将其标记为创始人决策,在构建时尚未做出决定,因此工具是参数化的而非固执己见的:当答案到来时,它将成为默认值,或减少一个变体——这是一个小改动而非重写。每个答案都会重述其使用的排序、过滤条件、考虑的候选数量以及候选来源。


设置

Node 20+(在22上开发)。无需配置构建步骤;npm test 会先构建。

npm install
npm test          # builds, then runs the suite — no key, no network, nothing live
npm run typecheck
npm run smoke     # LIVE once a key is configured; refuses cleanly and probes nothing without one

npm run smoke 是证伪运行,而非健康检查。有密钥时,它会逐行遍历§14.3的注册表并打印观察结果;无密钥时,它会列举所有本应进行的探测,并在未发送任何内容的情况下退出0。测试套件在任何情况下都不接触网络。

MCP 客户端配置(stdio):

{
  "mcpServers": {
    "curseforge-ark": {
      "command": "node",
      "args": ["C:/path/to/curseforge-ark-mcp/dist/src/server.js"],
      "env": { "CURSEFORGE_API_KEY": "your-key" }
    }
  }
}

服务器没有密钥会拒绝启动,并会明确说明搜索的两个位置、确切的环境变量,以及密钥并非自助服务。一个干净启动但随后在所有七个工具上抛出错误的 stdio MCP 服务器,调试起来非常痛苦。

关于密钥

API 密钥以 x-api-key 请求头形式发送。它不是 Authorization: Bearer 令牌——那是兄弟 Nitrado 服务器的方案,本仓库故意不支持两者,因为支持两者意味着此代码可能以 CurseForge 从未记录的形式传输凭据。

密钥由应用授予 Overwolf,且不可转让。 实际后果(也是此段落的唯一原因):泄露意味着撤销并重新申请,而重新申请需要排队,而非自助重置。 你不能在喝杯咖啡的功夫里重新生成它,也不能借用他人的。请妥善对待——.env 已加入 gitignore,.env.example 包含变量名和空值,任何已提交文件中均未出现密钥值。

此仓库中无作用域矩阵,这并非疏忽: CurseForge 未发布只读作用域和作用域选择,因此没有可矩阵化的内容。此服务器的只读属性源于其自身的端点允许列表,而非更窄的凭据。也没有令牌泄露应急手册——泄露的密钥仅提供对公共目录的读取访问和配额消耗,这是真实的风险,但与兄弟仓库的 Nitrado 令牌(文档中说明等同于游戏服务器的完全控制权)不属于同一类别。该规模调整在 ADR-002 §12 中进行了论证,并基于一个可被证伪的声明:CurseForge 目录数据在构造上就是公开的。

全部编辑处理

一条规则:绝不回显 API 密钥。 一个函数 src/scrub.ts 应用于错误消息和任何上游响应片段。错误消息中从不出现请求头——无论是密钥、编辑后的密钥,还是头部名称列表。get_api_diagnostics 报告是否配置了密钥,绝不会报告其值、前缀或长度。


在阅读输出前值得了解的行为

  • 空值不等于未知。 data: [] 表示 CurseForge 回答了“无”——这是真实的回答,并附带了查询以便你看到什么返回了空。缺失的字段为 null,绝不是 0、"" 或 []。未完成的请求或形状错误的响应是错误——绝不是值。

  • 缺失的 data 键是一个错误,而非空结果。 将其强制转换为 [] 会将集成故障变成“未找到结果”。

  • 分页端点上缺失 pagination 也是一个错误。 假设只有一页,就像工具报告了900个Mod中的50个,却以为是全部(U8 正是这个开放问题)。

  • pageSize > 50 会被拒绝而非截断,index + pageSize > 10000 也一样——并且会在消息中指明该索引处最大合法页面大小。模型请求200个却静默获得50个,会将一页当作整个集合来推理。

  • 当 totalCount 超过10000时,工具输出会写明尾部不可达,并建议缩小过滤器而非分页。

  • ASA 的 gameId 在运行时动态发现,通过 GET /v1/games 获取并在进程生命周期内缓存;绝不硬编码,也绝不猜测。如果无法解析,服务器会大声失败,指明搜索的内容以及密钥能看到的游戏数量——因为 gameId 是必需的搜索过滤器,错误的 gameId 会返回干净、空、完全错误的结果,而非错误。如果内置候选有误,请设置 CURSEFORGE_GAME_SLUG。

  • resolve_mod_dependencies 有深度上限,限制为4层和400个节点,并带有循环访问集。当达到限制时,结果会报告为已截断,并列出未探索的边界。


仓库布局

src/
  allowlist.ts    THE CHOKEPOINT — seven entries, host pin, normalization, bounds, body checks
  client.ts       the single transport; the ONLY place x-api-key is attached; envelope unwrap
  config.ts       refuse-to-start; no NITRADO_*, no mode switch, no settable base URL
  coerce.ts       empty / absent / unknown, kept apart
  errors.ts       the error taxonomy
  game.ts         runtime gameId resolution (injected, process-lifetime cache)
  registry.ts     ToolDef + tier, and the boot assertion that refuses a non-tier-1 tool
  scrub.ts        never echo the key. That is the whole module.
  probe-plan.ts   one probe per unverified row, asserted complete by a test
  server.ts       stdio entry point
  smoke.ts        the falsification run (live with a key, plan-only without)
  tools/          the seven tools
test/             156 tests; fixtures are synthetic in content, structural in shape
scripts/          buildinfo generator, test enumerator

src/buildinfo.ts 是生成的文件且已加入 gitignore,在每次 tsc 运行前会打上提交哈希和 dirty 标记,并通过 get_api_diagnostics 暴露。dist/ 已加入 gitignore,服务器作为长生命周期进程从中运行,因此“哪个代码产生了那个答案?”在运行时无法从 git 回答——它必须随工件一起传递。

与兄弟仓库的刻意差异

ADR-002 的开放问题7和8要求在此处明确指出差异发生的地方:

  • 相同基准,刻意为之。 Node ≥20、TypeScript 5.9.3、@modelcontextprotocol/sdk 1.30.0、zod 4.4.3、node:test 通过相同的 scripts/run-tests.mjs 枚举器运行。相同的审阅者,相同的习惯用法,降低阅读两者的成本。

  • 此处不依赖 @cfworker/json-schema。 它支持兄弟仓库的 cron 表达式验证,而这里没有写路径需要验证。

  • registry.ts 在结构上移植并保留了 tier,但移除了模式/启用列表机制——因为这里没有东西需要过滤,每个工具都是第1层,每个端点都是读取。一个模式变量背后没有实际内容,会宣传一个不存在的控制。一个五行启动断言取代了该子系统。

  • redact.ts 未移植(§12.1)。参见上文“全部编辑处理”。

  • 无 UNKNOWN_OUTCOME 错误代码。 兄弟仓库需要它,因为对 PUT 请求丢失的响应可能仍然改变了世界。此客户端能发出的所有请求都是读取,因此超时确实意味着“没有发生”,重试是安全的。

  • npm run smoke 在因缺少密钥而拒绝时退出0。 拒绝是今天运行它的预期结果,横幅会醒目标明 SMOKE NOT RUN。如果你希望流水线因缺少密钥而失败,请在流水线级别对密钥进行门控,而非依赖此退出码。


相关记录

在同级仓库 nitrado-ark-mcp 中(以下内容为只读——该仓库未受本仓库任何修改):

  • docs/decisions/EXECUTIVE-BOARD-2026-08-16-curseforge-mods.md —— 本仓库所执行的董事会会议记录(DEC-002),其主席裁决具有约束力。

  • docs/decisions/decision-log.md —— DEC-002,以及作为 §10 所依赖的范围拆分依据的 DEC-001。

  • docs/adr/ADR-001-write-path-enforcement.md —— ADR-002 所移植的形态,以及规范化规则、启动检查逻辑和拒绝启动逻辑的来源。

两个服务器保持独立。nitrado-ark-mcp 负责回答“这些项目 ID 位于 active-mods 中”;本仓库负责回答“项目 X 的最新文件为 v2.1 版本”。模型同时持有两者。两个服务器互不调用,且均不持有对方的凭证。

Available Tools

8 tools
get_api_diagnosticsDiagnose this server's CurseForge connection and honesty postureA

Answers 'is it me, the key, or CurseForge?' in one call: whether a key is configured (never the key itself, nor a prefix, nor its length), whether GET /v1/games succeeded, which ARK: Survival Ascended gameId was resolved and how, which commit this build came from and whether that build was dirty, what the endpoint allow-list currently permits, and any rate-limit headers a real response actually carried. It also reports the VERSION POSTURE: this is v0 and every field path in every tool is a hypothesis. Run this first when other tools behave strangely. Read-only.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description fully carries the behavior-disclosure burden. It declares the tool is read-only, states that it never reveals the key, prefix, or length, and even discloses the v0 hypothesis posture where field paths may be unreliable. This is unusually transparent.

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?

The description is long and dense, but nearly every clause adds a distinct diagnostic detail or caveat. It is front-loaded with the core question the tool answers. A slightly shorter or more list-like structure would improve scannability, but there is minimal wasted text.

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 zero-parameter diagnostic tool with no output schema, the description enumerates the reported areas comprehensively: key presence, API call success, gameId resolution, build metadata, allow-list, rate-limit headers, and version posture. It lacks an exact output format example, but the high-level coverage is sufficient for an agent to invoke and interpret the tool.

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?

The tool has zero parameters and the schema is an empty object, so the description cannot add parameter-level semantics. The baseline for a no-parameter tool is 4, and the description appropriately focuses on what the diagnostic returns instead.

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 uses a specific diagnostic verb and resource: it answers 'is it me, the key, or CurseForge?' in one call and enumerates exactly what it reports. The title and description clearly distinguish it from the sibling mod-focused tools.

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?

It gives explicit guidance: 'Run this first when other tools behave strangely.' This provides a clear trigger condition for use. It does not spell out when not to use it, but the diagnostic scope makes that exclusion unnecessary.

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

get_latest_fileGet a mod's newest file, by a stated definition of newestA

Answers 'is there a newer file for this mod than the one I am running?' Default selection is 'newest_by_file_date' (founder decision 2026-08-18). The other definitions still give different answers: 'newest_matching_game_version' restricts to files declaring a game version and then orders by fileDate; 'newest_with_release_type' restricts to a releaseType INTEGER you supply and then orders by fileDate. There is no named release/beta/alpha filter because CurseForge publishes no value table for that integer (ADR-002 §14.3 U7) and this server will not invent one. Every answer restates the ordering used, whether the default was applied, the filter applied, how many candidates were considered, and where the candidates came from. The matched file includes file_length_bytes; inspect that and file_name before treating it as a content pack. Read-only.

NameRequiredDescriptionDefault
mod_idYesCurseForge numeric mod (project) id.
selectionNoWhich question you are asking. Defaults to newest_by_file_date. These give different answers; pass another variant only when that is the question you mean.newest_by_file_date
game_versionNoRequired when selection is 'newest_matching_game_version'. The game version string a candidate file must declare. This server does NOT and MUST NOT learn your server's version from Nitrado (ADR-002 §9) — you supply it.
release_typeNoRequired when selection is 'newest_with_release_type'. The raw releaseType integer a candidate must carry. Unmapped on purpose: CurseForge publishes no value table, so pass the integer you mean rather than a label this server would have to guess.

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral burden, and it does so thoroughly. It declares Read-only, explains what every answer restates, notes the file_length_bytes caveat, and explains the deliberate refusal to invent release-type labels. There is no annotation to contradict.

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?

The description is dense but well organized: it front-loads the core question, then explains each selection mode and the caveats. Some internal references like 'ADR-002 §14.3 U7' add context but are slightly esoteric, keeping this from a perfect score.

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 no output schema, the description explains what the answer will contain: the ordering, default application, filter, candidate count, and candidate source. It also draws attention to file_length_bytes and file_name for content-pack inspection, so an agent has enough to invoke and interpret the call correctly.

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?

Input schema coverage is 100%, so baseline 3 applies. The description reinforces parameter requirements but largely restates schema details such as 'Required when selection is...' and 'pass the integer you mean.' It adds useful context but does not need to compensate for missing schema coverage.

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 opens with the exact question the tool answers and identifies the resource: a mod's newest file by a defined notion of 'newest.' It explains that there are three selection definitions and names the default, so an agent can clearly distinguish this from list_mod_files or get_mod_file.

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?

It gives explicit guidance on when to use the default versus the other selection variants, stating 'pass another variant only when that is the question you mean.' It also documents the required conditions for the non-default variants and explains why a named release-type filter cannot exist.

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

get_modGet one mod recordA

Fetch a single CurseForge mod (project) record by numeric id: name, slug, author summary, raw status integer, created/modified/released dates, website link, and its latestFiles with file length in bytes and raw releaseType integers. A record is a catalog row, not an install recommendation — inspect file_name and file_length_bytes. This is a single-record endpoint, so it carries no pagination and none is invented. Read-only. v0: all field paths unverified.

NameRequiredDescriptionDefault
mod_idYesCurseForge numeric mod (project) id. Digits only — the allow-list will not match anything else.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full transparency burden. It explicitly states 'Read-only', explains the absence of pagination, warns that the record is a catalog row rather than an install recommendation, and flags 'v0: all field paths unverified' as an important caveat. It does not mention error behavior or auth needs, but this is a simple single-record read.

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 dense but every sentence contributes: the field list, the catalog-vs-install clarification, the no-pagination note, the read-only flag, and the v0 caveat. It is front-loaded with the core action and resource, with no redundant phrasing.

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?

For a single-parameter read endpoint with no output schema, the description explains the expected return content, clarifies the semantic meaning of the record, rules out pagination, and discloses version uncertainty. An agent has enough information to select and invoke the tool correctly, and to interpret what it gets back.

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%, so the schema already fully documents mod_id as a CurseForge numeric mod id with a minimum, maximum, and digits-only note. The description adds only the phrase 'numeric id', which does not meaningfully extend the schema. Baseline 3 is appropriate because the structured schema handles the parameter semantics.

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 opens with a specific verb and resource: 'Fetch a single CurseForge mod (project) record by numeric id.' It enumerates concrete returned fields and explicitly contrasts itself with list/search endpoints by calling itself a single-record endpoint, making sibling differentiation clear.

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 gives clear context: this is the tool to use when you have a numeric mod id and need one catalog record. It also clarifies that pagination is not applicable, which prevents incorrect assumptions. It stops short of explicitly naming alternatives like search_mods or get_mod_file for when a different tool should be chosen.

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

get_mod_fileGet one mod file recordA

Fetch a single file record for a mod by numeric mod id and file id: display name, file name, file date, file_length_bytes, game versions, raw releaseType integer, and dependency edges with raw relationType integers. Inspect file_name and file_length_bytes before treating a file as a content pack. NOTE: this tool does NOT return a download URL. The download-url endpoint is deliberately absent from this server's endpoint allow-list (DEC-002 §11.3) — this server curates and reports, it never downloads or installs. Read-only. v0: all field paths unverified.

NameRequiredDescriptionDefault
mod_idYesCurseForge numeric mod (project) id. Digits only — the allow-list will not match anything else.
file_idYesCurseForge numeric file id.

TDQS

A4.3/5.0
Behavior5/5

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

No annotations are present, so the description correctly carries the full burden of behavioral disclosure. It explicitly states the tool is read-only, intentionally returns no download URL, and will never download or install. The v0 caveat that all field paths are unverified is valuable transparency about reliability.

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?

The description is front-loaded with purpose and returned fields, then provides caveats. Each sentenced earns its place: content-pack inspection, no-download-URL policy, read-only, and v0 unverified note. The DEC-002 citation is slightly verbose for a tool-calling agent but not wasteful.

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?

With no annotations and no output schema, the description supplies the needed context: purpose, key parameters, returned field names, raw-integer encodings, read-only behavior, the download-URL absence, and reliability caveat. Its main gap is not explicitly routing to sibling tools, which was already penalized under usage guidelines.

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 coverage is 100%, and both parameters already have meaningful descriptions ('CurseForge numeric mod project id. Digits only...' and 'CurseForge numeric file id.'). The description only restates that the IDs are numeric and adds no substantive parameter semantics beyond the schema.

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 starts with a specific verb ('Fetch') and resource ('a single file record for a mod'), and specifies the exact keys (numeric mod id and file id). This clearly distinguishes it from list_mod_files and get_latest_file in the sibling set, even without naming them. The title reinforces the singular, ID-based scope.

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?

It gives clear usage context: fetch one known file by IDs, inspect file_name and file_length_bytes before treating a file as a content pack, and do not use it when a download URL is needed because it explicitly does not return one. It stops short of naming specific sibling tools for enumeration or latest-file selection, so it is not a 5, but it is far above implied usage.

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

list_categoriesList ARK: Survival Ascended classes and categoriesA

List CurseForge classes and categories for ARK: Survival Ascended. Use this BEFORE search_mods when you need class_id, category_id, or exclude_category_ids — those integers are discovered here, never hardcoded. gameId is resolved at runtime and is not a parameter. Optional class_id narrows to categories under one class; classes_only returns only top-level classes. The documented response is a single array (no pagination object). Read-only.

NameRequiredDescriptionDefault
class_idNoRestrict to categories under this class id. Discoverable from a classes_only call.
classes_onlyNoWhen true, return only top-level classes for the game, not every nested category.

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden and meets it: it declares read-only, discloses the response shape ('single array (no pagination object)'), and flags the runtime-discovery nature of the returned IDs. It doesn't cover error/rate-limit/auth behavior, but for a read-only list endpoint the disclosed traits are the meaningful ones.

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?

Four sentences, each earning its place: purpose, when-to-use, param behavior, response shape. The routing guidance is front-loaded and there is zero filler or repetition of schema text.

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 2-optional-param, read-only list tool with 100% schema coverage and no output schema, this is nearly complete: purpose, sequencing, param semantics, and pagination behavior are all covered. The only gap is the shape of the returned category/class objects (e.g., which fields besides ids are present), which an agent would need when building exclude lists.

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?

Schema coverage is 100%, so baseline is 3, but the description adds genuine cross-tool meaning: it explains why class_id matters (to feed search_mods include/exclude params), that values must be discovered at runtime rather than hardcoded, and that gameId is intentionally absent. That's more than the schema's 'Restrict to categories under this class id' provides.

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?

States a specific verb+resource+scope: 'List CurseForge classes and categories for ARK: Survival Ascended'. It separates itself from siblings directly by naming search_mods as the tool that consumes these IDs, and its subject (classes/categories) is distinct from list_mod_files/get_mod. An agent can tell what it does without opening the schema.

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

Usage Guidelines5/5

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

Gives explicit sequencing guidance: 'Use this BEFORE search_mods when you need class_id, category_id, or exclude_category_ids — those integers are discovered here, never hardcoded.' It also prunes a likely mistake by stating gameId is resolved at runtime and not a parameter, so the agent won't hunt for a nonexistent gameId param.

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

list_mod_filesList a mod's filesA

List the published files for one mod, paginated. Each file carries its raw releaseType integer, its game versions, file_length_bytes, and its dependency edges with raw relationType integers — none of those integers is mapped to a label, because CurseForge publishes no value table for either. Inspect file_name and file_length_bytes before treating a file as a content pack. Page size is capped at 50; an over-large request is refused rather than clamped. Read-only. v0: all field paths unverified.

NameRequiredDescriptionDefault
indexNoZero-based offset. index + page_size <= 10000.
mod_idYesCurseForge numeric mod (project) id. Digits only — the allow-list will not match anything else.
page_sizeNoAt most 50. Over that is refused, not clamped.
game_versionNoFilter to files supporting this game version string. UNVERIFIED (§14.3 U9).

TDQS

A4.5/5.0
Behavior5/5

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

Even though no annotations are provided, the description discloses several important behaviors: integers are raw and unmapped, page size is capped at 50 and over-large requests are refused rather than clamped, and the tool is read-only. It also warns about inspecting file_name and file_length_bytes before treating a file as a content pack, and flags the v0 field-path verification status. This goes well beyond minimal behavioral disclosure.

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?

Three sentences with dense information and no filler. It front-loads the core purpose, then provides the most important caveats. It could arguably be split for readability, but each clause carries meaningful detail. The final 'v0' note is a valuable trust signal rather than noise.

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?

Given no output schema and no annotations, the description fills in the most important gaps: raw integer behavior, the 50-item cap, refusal rather than clamping, and read-only status. It lacks explicit return-value shape details, but with pagination and field names mentioned, an agent can infer the entry structure. Sibling tools like get_mod_file might provide the targeted-file alternative, but the description is sufficient for deciding when to call this tool.

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?

The schema already covers 100% of parameters with descriptions. The tool description complements this by explaining the key semantics of page_size (refused rather than clamped) and the raw integer caveat for the values returned. It doesn't redundantly repeat every parameter, but it adds meaningful context about how the parameters affect behavior.

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 names a specific verb ('List'), a resource ('published files for one mod'), and the pagination aspect. Distinct from siblings like get_mod_file or get_latest_file because it covers all published files for a mod rather than a single targeted file. It also clearly contrasts read-only behavior without any ambiguity.

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 implicitly indicates when to use this tool — when you need all published files for a mod, with pagination and dependency metadata — versus siblings like get_latest_file or get_mod_file which focus on specific files. It does not explicitly name alternatives, but it explains what this tool uniquely provides. The field-path caveat at the end ('v0: all field paths unverified') gives honest guidance about trust.

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

resolve_mod_dependenciesResolve a mod dependency tree (batched)A

Walk the dependency graph of one or more mods breadth-first, issuing ONE bulk POST per level rather than one GET per node. Returns every reachable mod with the raw relationType integer on each edge. IMPORTANT: this OVER-COLLECTS. CurseForge publishes no value table for relationType (ADR-002 §14.3 U6), so required, optional, tool and incompatible edges cannot be told apart and ALL are followed. Bounded at depth 4 and 400 nodes; when a bound is hit the result is reported as TRUNCATED with the unexplored frontier listed, never silently cut. Read-only. v0: all field paths unverified.

NameRequiredDescriptionDefault
mod_idsNoSeed mod ids. At least one of mod_ids or file_ids is required. At most 200.
file_idsNoSeed FILE ids, resolved through POST /v1/mods/files to find the mods they belong to before the walk begins. Use this when you know which file you are running. At most 200.
max_depthNoHow many levels to walk. Default and maximum 4.

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and succeeds: it discloses read-only behavior, highlights over-collection with 'IMPORTANT', states bounds (depth 4, 400 nodes), and explains truncation with the 'unexplored frontier' listed. It also flags 'v0: all field paths unverified', which is valuable risk context.

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?

Five dense, purposeul sentences cover algorithm, result shape, caveat, bounds, truncation, safety, and maturity. The IMORTANT warning is front-loaded after the primary verb, and there is no filler.

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?

For a tool with no output schema, it specifies the return core: every reachable mod, raw relationType integer per edge, and the TRUNCATED/frontier behavior. It also explains why over-collection occurs and how seeds work via file_ids, leaving no material gap for safe invocation.

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?

Schena description coverage is 100%, with detailed descriptions for mod_ids, file_ids, and max_depth. The main description primarily adds algorithm context (breadth-first, batched POST) but does not add new parameter semantics beyond what the schema already provides, so the baseline 3 is appropriate.

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 opens with 'Walk the dependency graph of one or more mods breadth-first', giving a specific verb and resource. It clearly distinguishes itself from sibling tools by emphasizing batched bulk POST resolution rather than per-node GETs. Nothing is vague or tautological.

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?

It provides clear context: use when you need to resolve a dependency tree, and the file_ids parameter includes the explicit guidance 'Use this when you know which file you are running.' It does not explicitly name sibling alternatives or exclusions, but the intended use case is unambiguous.

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

search_modsSearch ARK: Survival Ascended modsA

Search the CurseForge catalog for ARK: Survival Ascended mods. The gameId is resolved at runtime from GET /v1/games and is not a parameter — a wrong gameId returns a clean, empty, wrong result set rather than an error. Page size is capped at 50 by CurseForge and an over-large request is REFUSED rather than clamped, so that a page is never mistaken for a complete set. Every result states its pagination and whether more results exist, and says so explicitly when the tail of the result set is beyond the API's addressable window. class_id, category_id, and category_ids are include filters sent to CurseForge (discover ids via list_categories). exclude_category_ids is applied locally after the page returns — CurseForge has no exclude parameter — so pagination still describes the unfiltered upstream page. A hit is a catalog row, not an install: inspect file_name and file_length_bytes, then hand curseforge_mod_ids to nitrado-ark-mcp. Read-only.

NameRequiredDescriptionDefault
slugNoExact mod slug, when you already know it.
indexNoZero-based result offset. index + page_size must not exceed 10000.
class_idNoInclude: CurseForge section/class id. Discover via list_categories (is_class true).
page_sizeNoResults per page, at most 50. Over that is refused, not clamped.
sort_fieldNoCurseForge sort field, an integer 1-12 (documented range; the per-value meanings are not).
sort_orderNoSort direction.
category_idNoInclude: a single category id. Do not also pass category_ids.
category_idsNoInclude: up to 10 category ids. Overrides category_id at the vendor; this server refuses both at once rather than letting one silently win.
game_versionNoFilter to files supporting this game version string. UNVERIFIED: whether ASA mods populate game version fields at all is ADR-002 §14.3 U9.
search_filterNoFree-text search term, matched by CurseForge against mod names.
exclude_category_idsNoLOCAL exclude after the page returns. CurseForge cannot exclude. Pagination still describes the unfiltered upstream page. For gameplay-only, list_categories then pass Custom Cosmetics' id.

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries full responsibility and delivers extensively: it states runtime gameId resolution, page_size refusal rather than clamping, explicit pagination semantics, local application of exclude_category_ids, the read-only nature, and even a caveat that game_version behavior is unverified. This goes far beyond a typical tool description.

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 dense but every sentence earns its place: core purpose first, then edge cases, filter semantics, and output interpretation. It front-loads the main action and ends with a compact 'Read-only.' without repeating any schema information.

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 tool's complexity—11 optional parameters, no output schema, and no annotations—the description provides enough context for correct invocation and result interpretation. It explains the lack of a gameId parameter, pagination behavior, local filtering effects, and the key output fields (file_name, file_length_bytes, curseforge_mod_ids) to pass downstream.

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

Parameters5/5

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

Even though schema coverage is 100%, the description adds meaningful behavior beyond the schema: it distinguishes include filters sent to CurseForge from locally applied excludes, warns that category_ids overrides category_id and that passing both is refused, and notes that page_size over 50 is refused rather than clamped. This materially improves the agent's ability to pass parameters correctly.

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 opening sentence 'Search the CurseForge catalog for ARK: Survival Ascended mods' names a specific verb, resource, and context, making the action unmistakable. It also differentiates from sibling tools like get_mod and list_mod_files by describing a catalog-level search with paginated results rather than a single-resource lookup.

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 gives concrete cross-tool guidance, directing users to discover filter IDs via list_categories and providing a specific example for gameplay-only excludes. It does not explicitly state when to prefer this tool over get_mod or get_latest_file, but the search semantics and pagination make the intended context clear.

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. 8 tool updatesv0.2.0
    • First observedget_api_diagnostics
    • First observedget_latest_file
    • First observedget_mod
    • First observedget_mod_file
    • First observedlist_categories
    • First observedlist_mod_files
    • First observedresolve_mod_dependencies
    • First observedsearch_mods

TDQS

A4.5/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a clearly distinct resource and action: categories, mod search, single mod, file listing, single file, latest file, dependency graph, and diagnostics. Even the file-related tools are cleanly separated by purpose, with no two tools being interchangeable.

Naming Consistency5/5

Tool names consistently follow a lowercase snake_case verb_noun pattern: list_*, search_*, get_*, resolve_*. There are no mixed conventions, vague single-word verbs, or unpredictable naming styles.

Tool Count5/5

Eight tools is well-scoped for a read-only CurseForge catalog server. Each tool earns its place, covering browsing, retrieval, dependency resolution, and diagnostics without redundant utilities or unnecessary bloat.

Completeness4/5

The server covers the domain thoroughly: category discovery, mod search, mod details, file listing, single-file retrieval, latest-file comparison, dependency traversal, and diagnostics. The deliberate absence of a download URL is consistent with the stated curation-only purpose, but minor gaps such as no file-level search or changelog endpoint prevent a perfect completeness score.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    An MCP server for Arma Reforger and Enfusion engine modding that enables users to create mods, search API classes, and generate scripts through natural language. It provides a comprehensive suite of tools for scaffolding addons, generating prefabs, and building projects using the Workbench CLI.
    54 npm
    14
    -
  • 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