Token导航 LogoToken导航TokenDH.com
MCP Ffxiv Lumina logo
AI代理未说明官方级别未说明来源级核验

MCP Ffxiv Lumina

MCP Server

一个基于Lumina构建的MCP服务器,提供本地化、可查询的《最终幻想14》游戏数据访问,适用于AI助手和任何MCP兼容客户端。

工具数

27

提示词数

0

GitHub Stars

0

资源数

0
C#Claude数据访问Claude DesktopClaudeCursorVS Code

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

MelkyWay

提供方

MelkyWay

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

mcp ffxiv发光体

用于《最终幻想XIV》游戏数据的MCP(模型上下文协议)服务器,基于 流明娜.

通过MCP stdio传输提供对FFXIV游戏数据表的本地化、可查询访问。专为与Claude Desktop、AI助手和任何兼容MCP的客户端一起使用而设计。

______________________________________________________________________

先决条件

  • .NET 10 SDK
  • 本地FFXIV安装(PC或Steam——标准配置 SquareEnix/FINAL FANTASY XIV 目录)
  • 游戏必须至少启动过一次,这样EXD数据文件才会出现在磁盘上

______________________________________________________________________

设置

# Clone and build
git clone https://github.com/MelkyWay/mcp-ffxiv-lumina
cd mcp-ffxiv-lumina
dotnet build -c Release

# Run directly, supplying gamePath on the command line
dotnet run --project src/McpLumina -- --McpLumina:GamePath "C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn"

______________________________________________________________________

配置

编辑 src/McpLumina/appsettings.json:

{
  "McpLumina": {
    "gamePath": "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn",
    "languageDefault": "en",
    "cacheEnabled": true,
    "cacheTTLSeconds": 300,
    "logLevel": "Information",
    "schemaPath": "C:\\path\\to\\EXDSchema"
  }
}
字段类型必填默认描述
gamePath字符串--FFXIV安装根目录的路径
languageDefaultstring"en"未指定时的默认语言: en, fr, de, ja
cacheEnabledbooltrue启用内存中的响应缓存
cacheTTLSecondsint300缓存TTL(秒)
logLevelstring"Information"日志冗长(Trace, Debug, Information, Warning, Error)
schemaPathstringno--本地路径 EXD示意图 克隆。当设置时, describe_sheet 报告真实字段名,而不是 Column_N 指数。

所有设置也可以通过环境变量使用 McpLumina__ 前缀:

McpLumina__GamePath="C:\..." McpLumina__LanguageDefault=ja dotnet run --project src/McpLumina
注: 所有日志记录都会进入stderr。stdout专门为MCP stdio帧流保留。

EXDSchema(可选)

EXD示意图 是一个由社区维护的FFXIV表列定义存储库。通过配置时 schemaPath, describe_sheet 返回真实字段名(例如。 Name, ClassJob)而不是位置索引(Column_0, Column_10),以及 get_row / search_rows 接受这些名字 return_fieldstext_fields.

git clone https://github.com/xivdev/EXDSchema C:\EXDSchema
cd C:\EXDSchema
git checkout ver/2026.03.17.0000.0000   # branch matching your game version

使用 refresh_schema 获取并切换到最新分支,而无需重新启动服务器。

______________________________________________________________________

MCP客户端配置

服务器通过以下方式进行通信 标准 使用MCP协议。任何兼容MCP的客户端(Claude Desktop、Cursor、带MCP扩展的VS Code、自定义代理等)都可以通过启动流程和管道stdio进行连接。

已发布二进制文件(推荐)

dotnet publish src/McpLumina -c Release -r win-x64 --self-contained -o publish/

将您的客户端指向二进制文件:

command: C:\path\to\publish\mcp-lumina.exe
env:     McpLumina__GamePath = C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn
任何代码更改后,重新运行 dotnet publish 并重新启动MCP客户端以获取新的二进制文件。已发布的二进制文件不会自动更新。

当从多个客户端同时运行服务器时(例如Claude Desktop+Codex+自定义代理),强烈推荐这种方法。使用 dotnet run 相反,它将锁定调试二进制文件,并导致任何试图启动服务器的第二个客户端启动失败。

发展(dotnet run)

command: dotnet
args:    run --project C:\path\to\mcp-ffxiv-lumina\src\McpLumina --no-launch-profile
env:     McpLumina__GamePath = C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn

示例:克劳德桌面(claude_desktop_config.json)

{
  "mcpServers": {
    "ffxiv": {
      "command": "C:\\path\\to\\publish\\mcp-lumina.exe",
      "env": {
        "McpLumina__GamePath": "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn"
      }
    }
  }
}

______________________________________________________________________

工具参考

该服务器公开了四类二十七个工具:

  • 服务器工具 --健康、模式管理、语言信息
  • 通用图纸工具 --任意访问任何游戏数据表
  • FFXIV便利工具 --常见游戏实体的预成形响应
  • 补充工具 --社区维护的下降和补充数据(通过 转身)

______________________________________________________________________

health()

返回服务器状态、游戏版本、缓存设置和正常运行时间。使用此选项确认服务器是否正常运行,并检查自上次验证服务器以来游戏是否已修补。

{
  "status": "ok",
  "serverVersion": "1.0.0",
  "gamePath": "C:\\...",
  "detectedVersion": "2026.03.17.0000.0000",
  "validatedVersion": "2026.03.17.0000.0000",
  "schemaAvailable": true,
  "schemaVersion": "ver/2026.03.17.0000.0000",
  "cacheEnabled": true,
  "cacheTTLSeconds": 300,
  "uptimeSeconds": 42,
  "warnings": []
}

如果游戏已被修补, status 将是 "degraded" 带着一个 GameVersionMismatch 警告。通用工具(get_row, search_rows等等)不受影响;FFXIV便利工具(get_jobs, get_duties)可能会返回不正确的数据,直到 ServerConstants.cs 已更新。

如果配置了架构,但其分支版本比游戏版本旧 SchemaOutdated 发出警告。呼叫 refresh_schema 为了解决这个问题。

______________________________________________________________________

refresh_schema()

git fetch + git checkout -B 在配置中 schemaPath 目录中提取最新的列定义,然后清除所有缓存的描述和响应数据,以便后续调用使用更新的模式。返回成功或失败的消息。

{ "refreshed": true, "message": "Checked out ver/2026.03.17.0000.0000." }

如果 schemaPath 未配置,返回 ConfigError.如果git操作失败,则返回 InternalError 使用git输出。

______________________________________________________________________

list_languages()

返回四种支持的语言中的哪一种(en, fr, de, ja)在此安装中可用。

{
  "languages": [
    { "code": "en", "displayName": "English",  "available": true },
    { "code": "fr", "displayName": "French",   "available": true },
    { "code": "de", "displayName": "German",   "available": true },
    { "code": "ja", "displayName": "Japanese", "available": true }
  ]
}

______________________________________________________________________

list_sheets()

返回此安装中可用的所有游戏数据表的名称。工作表名称解析自 exd/root.exl 在启动时进行缓存,并在服务器生命周期内进行缓存。结果按字母顺序排序。

{
  "count": 756,
  "sheets": ["Achievement", "Action", "BeastTribe", "ClassJob", "ContentFinderCondition", "Item", "..."]
}

______________________________________________________________________

describe_sheet(sheet)

返回指定工作表的列元数据和近似行数。以前用这个 get_rowsearch_rows 了解可用字段及其类型。

{
  "sheet": "ClassJob",
  "rowCountApprox": 42,
  "columns": [
    { "index": 0,  "name": "Column_0",  "type": "string" },
    { "index": 1,  "name": "Column_1",  "type": "string" },
    { "index": 7,  "name": "Column_7",  "type": "uint"   },
    { "index": 30, "name": "Column_30", "type": "string" }
  ],
  "languages": ["en", "fr", "de", "ja"]
}

当配置EXDSchema时, name 值是真实的字段名(例如。 "Name", "ClassJob")而不是 Column_N列类型报告如下: string, bool, int, uint, float.

______________________________________________________________________

get_row(sheet, row_id, languages?)

返回单行的所有列值。当请求多种语言时,字符串列作为语言键词典返回。非字符串列返回标量值。

// Request
{ "sheet": "Item", "row_id": 2, "languages": "en,ja" }

// Response
{
  "sheet": "Item",
  "rowId": 2,
  "languagesRequested": ["en", "ja"],
  "languagesReturned": ["en", "ja"],
  "fallbackUsed": false,
  "fields": {
    "Column_0": { "en": "Weathered Shortsword", "ja": "古びたショートソード" },
    "Column_1": 1,
    "Column_5": 0
  }
}

fallbackUsed: true 表示请求的语言不可用,已替换为另一种语言。

______________________________________________________________________

get_rows(sheet, row_ids, languages?)

批量 get_row。接受行ID数组。每次通话最多100个ID。缺少行ID的情况在中报告 missingRowIds.

// Request
{ "sheet": "Item", "row_ids": [1, 2, 3], "languages": "en" }

// Response
{
  "rows": [...],
  "missingRowIds": []
}

______________________________________________________________________

search_rows(sheet, query, text_fields?, languages?, limit?, offset?, column_filters?)

在所有字符串列(或特定列)中搜索不区分大小写的子字符串匹配。在文本匹配之前,可以选择按精确的整数值对行进行预过滤。

// Request — all WHM actions containing "Holy"
{
  "sheet": "Action",
  "query": "Holy",
  "text_fields": "Column_0",
  "languages": "en",
  "column_filters": "Column_10=24"
}

// Response
{
  "sheet": "Action",
  "query": "Holy",
  "columnFilters": { "Column_10": 24 },
  "totalMatches": 2,
  "offset": 0,
  "limit": 50,
  "rowsScanned": 49000,
  "results": [...]
}

演出 这是整张纸的完整O(n)扫描。使用 text_fields 以限制搜索哪些字符串列。使用 column_filters 在文本匹配之前按整数值删除行——这在按引用列(如ClassJob)过滤时特别有效。

参数默认值最大值
limit50200
offset010 000

______________________________________________________________________

get_jobs(languages?)

返回所有用派生角色分组丰富的ClassJob行(基类和作业)。

{
  "jobs": [
    {
      "rowId": 19,
      "name":         { "en": "paladin", "ja": "ナイト" },
      "abbreviation": { "en": "PLD",     "ja": "ナイト" },
      "role":      "Tank",
      "isJob":     true,
      "isLimited": false,
      "jobIndex":  1
    }
  ]
}
注: name 值是存储在游戏数据中的内部小写键(例如。 "paladin"),而不是显示大写形式。
  • isJob: false --基层阶级(如掠夺者); isJob: true --工作(如战士)
  • isLimited: true --蓝色法师
  • role 值: Tank, Healer, Melee DPS, Physical Ranged DPS, Magical Ranged DPS, Limited, None
注: role 标签仅为英文。它们是派生值,而不是来自游戏字符串。

______________________________________________________________________

get_duties(category?, languages?)

返回ContentFinderCondition行,可选择按类别筛选。省略 category 退还所有税款。

类别: dungeon | trial | raid | ultimate | criterion | unreal

{
  "category": "ultimate",
  "count": 6,
  "duties": [
    {
      "rowId": 1006,
      "name": { "en": "Futures Rewritten (Ultimate)" },
      "category": "ultimate",
      "isHighEndDuty": true,
      "levelRequired": 100,
      "itemLevelRequired": 735
    }
  ]
}
贴片灵敏度: ContentType ID是针对特定游戏版本验证的硬编码常量(请参见 ServerConstants.cs).A. GameVersionMismatch 警告来自 health() 这意味着在依赖这些过滤器之前,应该对其进行重新验证。

______________________________________________________________________

get_items(query?, limit?, offset?, languages?)

按名称搜索项目表。返回物品等级、装备等级、堆栈大小、图标、稀有性、NPC价格和HQ资格。

参数说明
query不区分大小写的名称子字符串过滤器
limit / offset分页(最大限制200)
{
  "totalMatches": 1,
  "items": [
    {
      "rowId": 4179,
      "name":       { "en": "Hi-Potion" },
      "icon":       20,
      "itemLevel":  1,
      "equipLevel": 0,
      "stackSize":  999,
      "rarity":     1,
      "filterGroup": 8,
      "priceMid":   150,
      "canBeHq":    false
    }
  ]
}

稀有度值: 1 =普通(白色), 2 =不常见(绿色), 3 =稀有(蓝色), 4 =遗迹(紫色)。

注: 项目名称以单数小写语法形式存储(例如。 "potion",不 "Potion").

______________________________________________________________________

get_actions(query?, classJobId?, limit?, offset?, languages?)

从动作表中搜索玩家动作(能力、法术、武器技能)。仅 IsPlayerAction = true 返回行,过滤掉约47k NPC/系统条目。

参数说明
query不区分大小写的名称子字符串过滤器
classJobId按ClassJob行ID筛选(例如。 25 黑法师)。 0 =角色/跨类行动
limit / offset分页(最大限制200)
{
  "totalMatches": 31,
  "actions": [
    {
      "rowId": 162,
      "name": { "en": "Flare" },
      "icon": 2652,
      "classJobId": 25,
      "classJobLevel": 50,
      "actionCategoryId": 2,
      "actionCategoryName": "Spell",
      "isRoleAction": false,
      "isPvP": false,
      "castTimeMs": 2000,
      "recastTimeMs": 2500,
      "maxCharges": 0
    }
  ]
}

操作类别ID: 2 =拼写, 3 =武器, 4 =能力。铸造和重铸时间以毫秒为单位。 maxCharges > 1 表示基于电荷的冷却。

______________________________________________________________________

get_traits(query?, classJobId?, limit?, offset?, languages?)

从特质表中返回被动工作特征。结果按级别排序。

参数说明
query不区分大小写的名称子字符串过滤器
classJobId按ClassJob行ID筛选(例如。 24 白法师)
limit / offset分页(最大限制200)
{
  "totalMatches": 12,
  "traits": [
    {
      "rowId": 47,
      "name":        { "en": "Maim and Mend" },
      "description": { "en": "Increases the potency of physical attacks by 10% and all healing magic potency by 30%." },
      "classJobId":  22,
      "level":       20
    }
  ]
}

______________________________________________________________________

get_statuses(query?, category?, limit?, offset?, languages?)

从“状态”工作表中搜索状态效果(缓冲和去缓冲)。

参数说明
query不区分大小写的名称子字符串过滤器
categorybeneficialdetrimental.全部省略。
limit / offset分页(最大限制200)
{
  "totalMatches": 1,
  "statuses": [
    {
      "rowId": 17,
      "name":               { "en": "Paralysis" },
      "description":        { "en": "Unable to execute actions." },
      "icon":               215003,
      "statusCategory":     2,
      "statusCategoryName": "detrimental",
      "canDispel":          true,
      "maxStacks":          0
    }
  ]
}

maxStacks = 0 表示状态不可堆叠。

______________________________________________________________________

get_mounts(query?, limit?, offset?, languages?)

从“装载”表中搜索装载。

{
  "totalMatches": 3,
  "mounts": [
    {
      "rowId":      1,
      "name":       { "en": "Company Chocobo" },
      "icon":       4087,
      "isFlying":   true,
      "extraSeats": 0
    }
  ]
}

extraSeats > 0 表示多座安装。

______________________________________________________________________

get_minions(query?, limit?, offset?, languages?)

从“伙伴”表中搜索小黄人(伙伴)。

{
  "totalMatches": 1,
  "minions": [
    {
      "rowId": 8,
      "name": { "en": "Bahamut" },
      "icon": 59114
    }
  ]
}

______________________________________________________________________

get_achievements(query?, limit?, offset?, languages?)

从成就表中搜索成就。

{
  "totalMatches": 1,
  "achievements": [
    {
      "rowId":                   1,
      "name":                    { "en": "To Crush Your Enemies I" },
      "description":             { "en": "Defeat 100 enemies." },
      "points":                  5,
      "icon":                    112001,
      "achievementCategoryName": "Battle"
    }
  ]
}

______________________________________________________________________

get_races(languages?)

返回比赛表中的所有八场比赛。每个种族都有男性和女性的名字(可能因语言而异)。

行ID: 1=海尔, 2=Elezen, 3=拉拉费尔, 4= 混合, 5= 罗加丁, 6=Au-Ra, 7= 格鲁吉亚, 8= 观看

{
  "races": [
    {
      "rowId":     4,
      "masculine": { "en": "Miqo'te", "ja": "ミコッテ" },
      "feminine":  { "en": "Miqo'te", "ja": "ミコッテ" }
    }
  ]
}

______________________________________________________________________

get_worlds(query?)

从世界表中返回公共玩家可访问的世界(服务器)及其数据中心。

{
  "totalMatches": 1,
  "worlds": [
    {
      "rowId":          73,
      "name":           "Cactuar",
      "internalName":   "Cactuar",
      "dataCenterId":   8,
      "dataCenterName": "Aether",
      "isPublic":       true
    }
  ]
}
注: 世界名称是专有名词,在所有语言中都是相同的。

______________________________________________________________________

get_weather(query?, limit?, offset?, languages?)

从天气表中搜索天气类型。

{
  "totalMatches": 2,
  "weathers": [
    {
      "rowId": 7,
      "name": { "en": "Rain", "ja": "雨" },
      "icon": 60913
    }
  ]
}

______________________________________________________________________

get_titles(query?, limit?, offset?, languages?)

从标题表中搜索玩家标题。每个标题都有男性和女性的形式,以及一个位置标志。

{
  "totalMatches": 1,
  "titles": [
    {
      "rowId":     1,
      "masculine": { "en": "the Insatiable" },
      "feminine":  { "en": "the Insatiable" },
      "isPrefix":  false
    }
  ]
}

isPrefix: true --标题出现在角色名称之前(例如。 "Warrior of Light Firstname"). isPrefix: false --出现在(例如。 "Firstname the Insatiable").

______________________________________________________________________

get_currencies(languages?)

从物品表中返回游戏内货币(吉尔、巨石、印章、MGP等)。由...确定 ItemUICategory = 63, FilterGroup = 16, StackSize > 1.

{
  "currencies": [
    {
      "rowId":     1,
      "name":      { "en": "Gil" },
      "icon":      65002,
      "stackSize": 999999999
    },
    {
      "rowId":     28,
      "name":      { "en": "Allagan Tomestone of Poetics" },
      "icon":      65023,
      "stackSize": 2000
    }
  ]
}

stackSize 是每个字符的上限。

______________________________________________________________________

get_materia(query?, stat?, limit?, offset?, languages?)

从物料表中搜索物料项。返回每个材质项目的增强属性、级别(I-XII)和奖励值。结果按统计名称和级别排序。

  • query --项目名称子字符串过滤器(例如。 "Savage Aim")
  • stat --英文统计名称子字符串过滤器(例如。 "Critical Hit", "Gathering")
  • 输出中的统计名称始终为英语(专有名词,跨地区相同)
  • bonus0 适用于前天堂主属性(力量/敏捷性/活力/智力/心智等级I-VI),其中每一等级的值未存储在表格中
{
  "totalMatches": 12,
  "materia": [
    {
      "rowId":       5669,
      "name":        { "en": "Savage Aim Materia I" },
      "icon":        20221,
      "stat":        "Critical Hit",
      "baseParamId": 27,
      "tier":        1,
      "bonus":       1
    },
    {
      "rowId":       41772,
      "name":        { "en": "Savage Aim Materia XII" },
      "icon":        20298,
      "stat":        "Critical Hit",
      "baseParamId": 27,
      "tier":        12,
      "bonus":       54
    }
  ]
}

奖金等级因统计组而异。一些例子:

统计组IIIIIIIVVVIVIIIIXXneneneba十一XII
战斗子目标(暴击、突袭等)123461682412361854
收集/感知34561015122014252036
工艺34561116142118272233
CP/GP12346879810911

______________________________________________________________________

get_localized_labels(kind, languages?)

返回知名FFXIV枚举的标签集,适用于填充UI下拉菜单或构建查找表。

种类值: jobs | roles | categories | ultimates | criterion | unreal

{
  "kind": "jobs",
  "labels": [
    { "rowId": 19, "name": { "en": "Paladin", "ja": "ナイト" } }
  ]
}

______________________________________________________________________

get_tomestone_currencies(status?, languages?)

返回Allagan Tomestone货币 TomestonesItem 纸张,显示其当前的旋转状态。状态来源于稳定 Category 表中的字段——基础项名称会更改每个补丁,但映射不会。

状态含义示例(补丁7.2)
current活跃有限tomestone(每周上限)数学
previous以前的有限tomestone助记
older旧版限量版tomestone太阳测量学
poetics永恒的无上限巨著诗学的Allagan tomestone
retired不再流通的历史巨著神话、士兵、法律

省略 status 全部归还。结果首先按当前排序。

{
  "totalMatches": 23,
  "currencies": [
    {
      "rowId":     48,
      "name":      { "en": "Allagan Tomestone of Mathematics" },
      "icon":      65049,
      "status":    "current",
      "stackSize": 2000
    },
    {
      "rowId":     28,
      "name":      { "en": "Allagan Tomestone of Poetics" },
      "icon":      65023,
      "status":    "poetics",
      "stackSize": 2000
    }
  ]
}

______________________________________________________________________

get_mob_drops(monsterQuery?, itemQuery?, limit?, offset?, languages?)

从维护的社区返回怪物掉落数据 转身 数据集(2644怪物→项目对)。每个条目都将一个怪物链接到它可以掉落的物品。没有可用的下降率或数量数据,只有对。

参数说明
monsterQuery不区分大小写的怪物名称子字符串过滤器
itemQuery不区分大小写的项目名称子字符串过滤器
limit / offset分页(最大限制200)
{
  "totalMatches": 4,
  "drops": [
    {
      "bNpcNameId": 2061,
      "mobName":  { "en": "elder hapalit" },
      "itemId":   5439,
      "itemName": { "en": "Ogre Horn" }
    }
  ]
}
两者 monsterQueryitemQuery 可以组合以将结果缩小到特定的怪物/物品对。

______________________________________________________________________

get_triple_triad_cards(query?, limit?, offset?, languages?)

返回从连接的Triple Triad卡数据 TripleTriadCardTripleTriadCardResident。包括定向游戏价值、明星稀有性、卡片类型、售价、风味文本和获取来源。

参数说明
query不区分大小写的卡片名称子字符串过滤器
limit / offset分页(最大限制200)
{
  "totalMatches": 465,
  "cards": [
    {
      "rowId":       42,
      "name":        { "en": "Garuda", "ja": "ガルーダ" },
      "description": { "en": "Summoned by the Ixal tribes of Xelphatol..." },
      "startsWithVowel": false,
      "top":         7,
      "bottom":      1,
      "left":        7,
      "right":       6,
      "stars":       3,
      "type":        "Primal",
      "saleValue":   500,
      "acquisitionSource": "Challenge: Vorsaile Heuloix",
      "obtainTypeIcon":    60051
    }
  ]
}
  • stars --稀有等级1-5(★至★★★★★)
  • typeNormal | Primal | Scion | Society | Garlean
  • saleValue --NPC卖出价格(单位:gil); 0 意味着无法销售
  • acquisitionSource"Challenge: [NPC name]" 对于从NPC挑战者手中赢得的卡片, "Requires: [Quest name]" 用于内容门控卡,或 null 如果未知
  • obtainTypeIcon --获取方法的图标ID(如果不可用,则为0)
  • typeacquisitionSource 以所请求的主要语言解决; top/bottom/left/right 语言中立

______________________________________________________________________

错误响应

所有工具在失败时返回结构化错误:

{
  "code": "SheetNotFound",
  "message": "Sheet 'Foobaz' was not found in the game data.",
  "detail": null
}
代码含义
ConfigError配置无效或缺失(例如。 schemaPath 通话时未设置 refresh_schema)
SheetNotFound游戏数据中不存在命名表
RowNotFound工作表中不存在行ID
LanguageUnavailable请求的语言代码无效或未安装
ValidationError输入参数值错误
InternalError意外的服务器错误

______________________________________________________________________

测试

所有测试

FFXIV_GAME_PATH="C:/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn" dotnet test

仅进行单元测试(无需安装FFXIV)

dotnet test --filter "Category!=Integration"

仅集成测试

FFXIV_GAME_PATH="C:/..." dotnet test --filter "Category=Integration"

如果 FFXIV_GAME_PATH 未设置,集成测试已设置 跳过 而不是失败——CI在没有安装游戏的情况下通过。

快照测试

快照基线 get_jobsget_duties (最后通牒)住在 tests/McpLumina.Tests/Integration/Snapshots/他们根据已知的好游戏版本验证工具响应的确切形状和内容。

补丁后,如果快照失败:

  • 新增工作或职责→ 更新快照文件(预期漂移)
  • 数据混乱或类型错误→ 列索引 ServerConstants.cs 需要更新(请参阅下面的维护)

______________________________________________________________________

维护:补丁后运行手册

便利工具(get_jobs, get_duties, get_actions, get_items)使用 Lumina.Excel 键入具有命名属性的工作表,因此游戏数据中的列布局会发生变化 需要手动更新索引。唯一对补丁敏感的值是用于职责类别筛选的ContentType ID。

  1. 检查Lumina的新版本。 Lumina通常在FFXIV主要补丁发布后的几天内发布更新的NuGet包。更新中的版本 src/McpLumina/McpLumina.csproj 重建:
   dotnet build
  1. 运行集成测试:
   FFXIV_GAME_PATH="C:/..." dotnet test --filter "Category=Integration"
  1. 如果职责类别过滤返回错误结果,验证中的ContentType ID ServerConstants.cs (ContentTypeIds)仍然可以通过检查ContentType表来映射到正确的内容类别 get_row.
  1. 碰撞 KnownGoodGameVersion.ValueServerConstants.cs 到新游戏版本字符串(从 game/ffxivgame.ver).
  1. 运行完整的测试套件 --所有220个测试都应该运行(147个单元通过,无需安装游戏;73个集成需要 FFXIV_GAME_PATH).
  1. 刷新EXDSchema 如果已配置:
   refresh_schema()

或手动: cd && git fetch && git checkout ver/.

  1. 重新发布二进制文件 因此MCP客户端会获取更新的版本:
   dotnet publish src/McpLumina -c Release -r win-x64 --self-contained -o publish/

然后重新启动所有连接的MCP客户端(Claude Desktop、Codex等)。

  1. 发布时,请注明已验证的FFXIV补丁版本。

______________________________________________________________________

架构说明

补丁弹性

通用工具(get_row, search_rows等)使用Lumina的非类型化 RawExcelSheet / RawRow API和对修补程序后的列布局更改不敏感。FFXIV专用便利工具(get_jobs, get_duties, get_actions, get_items)使用 Lumina.Excel 源生成的键入工作表(ClassJob, ContentFinderCondition, Action, Item)具有命名属性,因此它们也能适应列布局的变化——只有ContentType ID常量 ServerConstants.cs 补丁后需要手动验证。

缓存

响应以可配置的TTL(默认5分钟)缓存在内存中。工作表列表在服务器生命周期内缓存。 describe_sheet 结果缓存在生命周期字典中(服务器运行时它们不会更改) ResponseCacheService.呼叫 refresh_schema 清除两个缓存,以便立即反映更新的列名。缓存在重新启动后不会持久化。

______________________________________________________________________

已知限制(V1)

  • 角色标签仅为英文。 get_jobs 回报 "Tank", "Healer"等作为硬编码的英文字符串,而不是游戏源的本地化标签。
  • get_actions 返回内部操作名称。 操作表存储内部小写名称;显示名称(大写)不能通过简单键入的字段获得。
  • 没有跨表链接解析。 参考其他表格(例如。 ClassJob → ClassJobCategory)在通用工具中不会自动遵循。
  • 没有查询DSL。 没有SQL风格的WHERE子句。使用 search_rows 用于文本搜索和 get_row/get_rows 对于已知的ID。
  • search_rows 这是一次全面扫描。 没有索引。大纸张(操作:~49k行,项目:~44k行)在每次调用时扫描每一行。
  • ContentType ID是硬编码的。 职责类别过滤依赖于已知的ContentType行ID,这些ID依赖于补丁版本。
  • 仅限stdio传输。 V1不支持HTTP/SSE传输。
  • 仅限内存缓存。 缓存不会在服务器重新启动时持久化。

______________________________________________________________________

工具合同版本控制

工具输入/输出模式遵循semver约定:

  • 补丁 (1.0.x):仅修复Bug;没有架构更改
  • 次要的 (1.x.0):仅添加更改——新的可选响应字段、新工具
  • 主要的 (x.0.0):中断模式更改;提供迁移说明

除非按要求记录,否则消费者应将所有响应字段视为可能为空,并应忽略未知字段以实现前向兼容性。

目录标签

目录标签

C#Claude数据访问游戏数据查询本地部署本地化支持MCP协议最终幻想14

支持客户端

Claude DesktopClaudeCursorVS Code

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

none

工具数量(toolCount,工具数)

27

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明none部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP