Token导航 LogoToken导航TokenDH.com
Mutagen MCP logo
运维云端stdio官方级别未说明来源级核验

Mutagen MCP

MCP Server

基于.NET 9和Mutagen的Skyrim SE插件分析工具,提供插件路径解析、主从关系验证、冲突检测等功能,适用于Mod Organizer 2环境。

工具数

10

提示词数

0

GitHub Stars

1

资源数

0
C#Cursor云端部署Cursor

安装说明

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

作者 / 组织

Charrdge

提供方

Charrdge

最后核验

2026/5/17 20:20

运行时

Docker

快速接入

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

命令预览

docker run -i --rm \

详细介绍

mutagen-mcp

MCP-сервер (stdio) на .NET 9 + Mutagen для чтения Skyrim SE (и родственных релизов Mutagen с ToSkyrimRelease()): статус путей, список из plugins.txt (пагинация offset / maxPlugins, фильтр только отсутствующие на диске), заголовки, мастера, компактный режим mutagen_verify_masters без массива рёбер, а также ограниченный анализ записей (цепочка оверрайдов по FormKey, сравнение двух плагинов, кандидаты ITM / удалённые записи). Тяжёлые сценарии ограничены параметрами и настройками (maxPlugins, maxNodes, MaxConflictScanRecords, …).

Требования

  • .NET SDK 9 (на машине с игрой обычно Windows; сборка кроссплатформенная; в Docker образ собирается сам).
  • Путь к plugins.txt (список и порядок плагинов для игры или профиля MO2).
  • DataFolder — первый корень поиска (обычно Skyrim Special Edition\Data с ванильными мастерами).
  • PluginSearchRoots — дополнительные корни (плоские каталоги с .esp / .esm / .esl или корень mods Mod Organizer 2). Порядок важен: последний корень в списке выигрывает, если одно и то же имя файла встречается в нескольких корнях.
  • Для MO2 (плагины в mods//…, а не в корне mods/): задайте ModlistTxtPath — путь к modlist.txt профиля. Резолвер ищет файл как modsRoot//(Data/)?/; приоритет как в MO2: ниже в modlist — выше приоритет при совпадении имён.

Если PluginSearchRoots пуст, используется только DataFolder. Без ModlistTxtPath дополнительные корни обрабатываются только плоско (корень/файл и при ProbeDataSubfolderкорень/Data/файл).

Заметка: это не дублирует Mod Organizer MCP: тот про управление профилем MO2; mutagen-mcp использует те же файлы, чтобы открыть бинарные плагины через Mutagen.

Сборка

dotnet build MutagenMcp.sln -c Release

Бинарь: src/MutagenMcp/bin/Release/net9.0/mutagen-mcp.dll.

Запуск в контейнере

MCP по stdio нуждается в интерактивном stdin у контейнера (-i). Смонтируйте Data, при MO2 — mods и modlist.txt, plugins.txt профиля; передайте внутренние пути в env.

Сборка образа (из корня репозитория):

docker build -t mutagen-mcp:local .

Минимальный пример (только игровой Data + plugins.txt):

docker run -i --rm \
  -v "/path/to/Skyrim Special Edition/Data:/data:ro" \
  -v "/path/to/profiles/MyProfile/plugins.txt:/config/plugins.txt:ro" \
  -e MutagenMcp__DataFolder=/data \
  -e MutagenMcp__PluginsTxtPath=/config/plugins.txt \
  mutagen-mcp:local

Mod Organizer 2 (игра + каталог mods + modlist.txt того же профиля, что и plugins.txt):

docker run -i --rm \
  -v "/path/to/Skyrim Special Edition/Data:/data:ro" \
  -v "/path/to/MO2/mods:/mods:ro" \
  -v "/path/to/MO2/profiles/MyProfile/plugins.txt:/config/plugins.txt:ro" \
  -v "/path/to/MO2/profiles/MyProfile/modlist.txt:/config/modlist.txt:ro" \
  -e MutagenMcp__DataFolder=/data \
  -e MutagenMcp__PluginsTxtPath=/config/plugins.txt \
  -e MutagenMcp__ModlistTxtPath=/config/modlist.txt \
  -e MutagenMcp__PluginSearchRoots__0=/mods \
  mutagen-mcp:local

Пример с плоским вторым корнем (без MO2-структуры папок):

docker run -i --rm \
  -v "/path/to/Skyrim Special Edition/Data:/data:ro" \
  -v "/path/to/mods/staging:/mods:ro" \
  -v "/path/to/profiles/MyProfile/plugins.txt:/config/plugins.txt:ro" \
  -e MutagenMcp__DataFolder=/data \
  -e MutagenMcp__PluginSearchRoots__0=/mods \
  -e MutagenMcp__PluginsTxtPath=/config/plugins.txt \
  mutagen-mcp:local

Фрагмент для Cursor (Linux / WSL; пути замените на свои; образ локально: mutagen-mcp:local):

{
  "mcpServers": {
    "mutagen-mcp": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/mnt/g/Games/steamapps/common/Skyrim Special Edition/Data:/data:ro",
        "-v", "/mnt/s/MO2_data/mods:/mods:ro",
        "-v", "/mnt/s/MO2_data/profiles/Default/plugins.txt:/config/plugins.txt:ro",
        "-v", "/mnt/s/MO2_data/profiles/Default/modlist.txt:/config/modlist.txt:ro",
        "-e", "MutagenMcp__DataFolder=/data",
        "-e", "MutagenMcp__PluginsTxtPath=/config/plugins.txt",
        "-e", "MutagenMcp__ModlistTxtPath=/config/modlist.txt",
        "-e", "MutagenMcp__PluginSearchRoots__0=/mods",
        "-e", "MutagenMcp__CacheGameEnvironment=true",
        "mutagen-mcp:local"
      ]
    }
  }
}

На Windows с Docker Desktop пути в -v часто задают как D:/Games/.../Data:/data:ro. Флаг :ro необязателен, но удобен для чтения.

При MutagenMcp__CacheGameEnvironment=true в Docker имеет смысл задать лимит памяти контейнера (например --memory=8g в args перед образом), если лоад большой.

Ограничения: контейнер должен видеть те же файлы, что и ваша установка. В Linux-контейнере на смонтированном NTFS возможны проблемы с регистром имён файлов относительно plugins.txt.

Процесс MCP, Docker и кэши

  • Нет отдельного «вечного» контейнера под MCP: при типичном конфиге docker run -i --rm … Cursor запускает контейнер на время одной сессии MCP (stdio к процессу dotnet …/mutagen-mcp.dll внутри контейнера). Выключили MCP или перезагрузили окно — процесс завершился, с --rm контейнер удаляется. Следующий старт — снова новый контейнер и пустая память процесса.
  • Кэш резолва путей (класс PluginPathResolver, RAM процесса, на диск не пишется): накопительный словарь «имя файла плагина → абсолютный путь» (или пометка, что файла нет). Общий для пакетного ResolvePluginPaths и одиночного TryResolve. Сбрасывается при смене списка корней (DataFolder + PluginSearchRoots), пути или mtime modlist.txt, флага ProbeDataSubfolder. Порядок plugins.txt на физическое расположение файлов на диске не влияет — в ключ инвалидации он не входит. Для MO2 резолв по папкам модов делается пакетно (перечисление .esp / .esm / .esl в каталоге мода), без комбинаторного числа отдельных проверок «мод × плагин».
  • mutagen_plugin_master_closure перед обходом мастеров один раз вызывает пакетный резолв для всех включённых плагинов из plugins.txt, чтобы заполнить этот словарь; дальнейшие обращения к тем же именам идут из кэша.
  • CacheGameEnvironmentотдельный кэш: полный GameEnvironment Mutagen в памяти до смены лоада/сигнатуры; см. таблицу ниже. С кэшем путей к файлам он не смешивается.

Конфигурация

src/MutagenMcp/appsettings.json, секция MutagenMcp:

КлючОписание
DataFolderПервый корень поиска плагинов (часто игровой Data)
PluginSearchRootsДополнительные корни; более поздние важнее при совпадении имён файлов в разных корнях
ModlistTxtPathПуть к MO2 modlist.txt; включает разрешение путей внутри PluginSearchRoots по папкам модов
ProbeDataSubfolderЕсли true, для каждого корня (и для mods//) проверяются и …/file.esp, и …/Data/file.esp (по умолчанию true)
PluginsTxtPathАбсолютный путь к plugins.txt
GameReleaseИмя enum Mutagen, по умолчанию SkyrimSE
PrependImplicitStandardMastersЕсли true (по умолчанию), к резолвящемуся лоаду (полный GameEnvironment, mutagen_formid_override_chain и т.д.) в начало добавляются стандартные мастера SSE (Skyrim.esm, Update.esm, DLC), если они есть на диске, но нет среди включённых строк plugins.txt (типичный MO2). Только Skyrim-релизы; false — старое поведение «только plugins.txt»
MaxPluginsPerRequestВерхняя граница для параметра maxPlugins у mutagen_list_plugins и mutagen_verify_masters (1–2000)
MaxConflictScanRecordsПотолок записей при скане одного плагина в mutagen_plugin_record_flags_report (1–100000)
MaxCompareResultsПотолок пар FormKey в mutagen_compare_two_plugins (1–10000)
MaxOverrideChainLengthВерхняя граница параметра maxChainLength у mutagen_formid_override_chain (1–256). Это только обрезка массива chain в JSON, не лимит «сколько плагинов проверить» при полном обходе
OverrideChainUseBinaryOverlayЕсли true (по умолчанию), mutagen_formid_override_chain не строит полный GameEnvironment, а открывает каждый плагин через binary overlay и ищет FormKey по top-level группам Mutagen (ContainsKey на группе), без полного перебора всех записей мода. false — прежний путь с полным лоадом и кэшем окружения
OverrideChainOverlayMaxDegreeOfParallelismДля overlay-ветки: сколько плагинов открывать параллельно (1 — по очереди). 0 — авто: от 1 до min(число_ядер, 8). Больше — быстрее на SSD при длинном plugins.txt; меньше — если упираетесь в диск или RAM
CacheGameEnvironmentЕсли true, один полный GameEnvironment переиспользуется между вызовами тяжёлых инструментов, пока не изменятся plugins.txt, пути плагинов или связанные опции (выше потребление RAM)
EnvironmentCacheMaxAgeSecondsПри CacheGameEnvironment и значении > 0 кэш сбрасывается по таймеру (секунды); 0 — только инвалидация по сигнатуре файлов
ExposeToolTimingsInJsonЕсли true (по умолчанию), тяжёлые conflict-tools добавляют в JSON поле timings (мс), чтобы видеть длительность без чтения stderr
ToolDiagnosticsLogPathЕсли задан абсолютный путь к файлу, сервер дописывает в него строки NDJSON (один JSON на строку): события кэша окружения, сборки GameEnvironment, успехи и ошибки conflict-tools с теми же таймингами, что в логах и при ExposeToolTimingsInJson. Пустая строка — выключено. Каталог создаётся при необходимости
ToolDiagnosticsProgressPluginIntervalВ mutagen_formid_override_chain каждые N позиций лоадордера пишется строка OverrideChainScanProgress в NDJSON-лог (0 — отключить). По умолчанию 64. Перед overlay-сканом пишется событие OverrideChainResolvedListings: prepMs (от старта инструмента до готовности листингов), readListingsMs (чтение лоада через Mutagen из plugins.txt), resolvePathsMs (поиск файлов на диске / MO2), плюс счётчики вроде pluginCount

Переменные окружения (перекрывают JSON): MutagenMcp__DataFolder, MutagenMcp__PluginsTxtPath, MutagenMcp__ModlistTxtPath, MutagenMcp__GameRelease, MutagenMcp__PrependImplicitStandardMasters, MutagenMcp__MaxPluginsPerRequest, MutagenMcp__MaxConflictScanRecords, MutagenMcp__MaxCompareResults, MutagenMcp__MaxOverrideChainLength, MutagenMcp__OverrideChainUseBinaryOverlay, MutagenMcp__OverrideChainOverlayMaxDegreeOfParallelism, MutagenMcp__CacheGameEnvironment, MutagenMcp__EnvironmentCacheMaxAgeSeconds, MutagenMcp__ExposeToolTimingsInJson, MutagenMcp__ToolDiagnosticsLogPath, MutagenMcp__ToolDiagnosticsProgressPluginInterval, MutagenMcp__ProbeDataSubfolder, MutagenMcp__PluginSearchRoots__0, MutagenMcp__PluginSearchRoots__1, …

Cursor / MCP (без Docker)

Пример (путь к проекту и пути к Data / MO2 подставьте свои):

{
  "mcpServers": {
    "mutagen-mcp": {
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "C:/path/to/mutagen-mcp/src/MutagenMcp/MutagenMcp.csproj",
        "-c",
        "Release",
        "--no-build"
      ],
      "env": {
        "MutagenMcp__DataFolder": "D:/Steam/steamapps/common/Skyrim Special Edition/Data",
        "MutagenMcp__PluginsTxtPath": "C:/ModOrganizer/profiles/Default/plugins.txt",
        "MutagenMcp__ModlistTxtPath": "C:/ModOrganizer/profiles/Default/modlist.txt",
        "MutagenMcp__PluginSearchRoots__0": "C:/ModOrganizer/mods",
        "MutagenMcp__CacheGameEnvironment": "true"
      }
    }
  }
}

После первой сборки можно вызывать dotnet exec .../mutagen-mcp.dll вместо dotnet run, если удобнее.

Готовый фрагмент для вставки в конфиг MCP Cursor (с кэшем окружения): docs/cursor-mcp.example.json — скопируйте содержимое в свой mcp.json / настройки MCP и поправьте пути. Новые аргументы tools (offset, onlyFileMissing, includeDirectEdges, …) не требуют правок mcp.json: схема приходит от сервера при подключении; достаточно пересобрать образ или обновить бинарь и перезапустить MCP.

Длинные ответы: пагинация и «только проблемы»

ИнструментПараметрыЗачем
mutagen_list_pluginsoffset (по умолчанию 0), maxPlugins, onlyEnabled, onlyFileMissingЛистать длинный лоадордер страницами; при onlyFileMissing: true в выборку попадают только плагины из plugins.txt, для которых нет файла на диске по текущим корням (после фильтра onlyEnabled).
mutagen_list_pluginsответtotalMatching, returnedCount, count (= returnedCount), limit, offset, hasMore / truncated, onlyFileMissing. Поля header и headerReadError в строках плагина опускаются, если null (меньше JSON).
mutagen_list_pluginsincludeHeadersОшибка чтения заголовка одного файла → headerReadError на этой строке, вызов целиком не падает.
mutagen_verify_mastersincludeDirectEdges (по умолчанию true)При false массив directEdges в JSON не включается (остаются missingMasters, orderViolations, cycles, …); число рёбер по-прежнему в counts.directEdges. Удобно при большом лоадордере, когда нужны только отчёты об ошибках.

Полный проход mutagen_verify_masters по всем включённым плагинам по-прежнему ограничен maxPlugins и серверным MaxPluginsPerRequest.

Инструменты

ИмяНазначение
mutagen_statusserverVersion — версия сборки (в Docker: 0.x.y+docker. + UTC-метка в publish, чтобы проверить, что запущен свежий образ), плюс пути к plugins.txt / modlist.txt, GameRelease, корни поиска
mutagen_list_pluginsСписок из plugins.txt; файлы ищутся по DataFolder + PluginSearchRoots (+ разбор MO2 при ModlistTxtPath). Пагинация: offset + maxPlugins; в ответе totalMatching, hasMore / truncated, returnedCount (поле count — то же число). onlyFileMissing — только плагины без файла на диске. При includeHeaders ошибка чтения заголовка даёт headerReadError на строке, а не сбой всего вызова
mutagen_plugin_headerЗаголовок одного плагина; путь через те же правила резолва
mutagen_plugin_major_records_sampleПервые N major-записей из одного плагина через binary overlay (без полного GameEnvironment); в ответе есть formKey — удобно подобрать ключ для mutagen_formid_override_chain
mutagen_plugin_lookup_form_keyОдин плагин + одна строка FormKey: быстрый поиск по top-level группам; при enumerateFallback: true (по умолчанию) при промахе — полный перебор major-записей только этого файла (на больших мастерах вроде Skyrim.esm может занять заметное время). Ответ: found, lookupStrategy, formKey, recordType, editorId
mutagen_plugin_master_closureПредки по цепочке Master в заголовке TES4 (не обратные зависимости); аргументы: pluginFileNames[], maxNodes (по умолчанию 512, до 4096). Перед BFS выполняется пакетный резолв путей для всех включённых плагинов из plugins.txt (общий кэш с остальными инструментами). В ответе: nodes, unresolvedMasters, флаг truncated
mutagen_verify_mastersПо первым maxPlugins плагинам из plugins.txt (по умолчанию только включённые): чтение списков Master без полных заголовков; ответ — directEdges (опционально), missingMasters (notInLoadOrder / disabled / fileNotFound), orderViolations (мастер ниже зависимого), cycles (SCC по рёбрам «мастер раньше зависимого»), dependentFileMissing, readErrors, truncated если в списке остались необработанные включённые. includeDirectEdges: false убирает массив directEdges из JSON (счётчик остаётся в counts.directEdges)
mutagen_formid_override_chainFormKey (hexId:PluginFile.esp, как в Mutagen) → плагины из резолвящегося лоада (включённые строки plugins.txt с файлом на диске плюс при PrependImplicitStandardMasters стандартные мастера SSE в начале, если их не было в txt), в которых есть major-запись с точно таким ключом; победитель — макс. индекс. Строка должна совпадать с тем, что возвращает Mutagen (см. mutagen_plugin_lookup_form_key / mutagen_plugin_major_records_sample): для оверрайдов суффикс после : часто совпадает с файлом, где лежит строка, а не только с колонкой мастера в xEdit. Параметр accurateRecordLookup: при true на каждом плагине используется полный перебор major-записей вместо top-level ContainsKeyочень медленно на длинном лоаде, если ключа нет; только для отладки. При totalContributors: 0 в ответе (если удалось собрать статистику) есть emptyResultDiagnostics: счётчики включённых строк plugins.txt vs резолвнутых файлов, флаги стандартных мастеров (Skyrim.esm, Update.esm, …), текстовый hint. Остальное: winnerOnly, maxChainLength (обрезка JSON), overlay vs OverrideChainUseBinaryOverlay, pluginsScannedFromEnd. Пример: 000D62:AI Overhaul.esp
mutagen_compare_two_pluginsПересечение FormKey по major-записям в двух ESP/ESM; sameBinaryShape через Equals Mutagen. recordType — подстрока имени типа записи
mutagen_plugin_record_flags_reportПо одному плагину: удалённые записи (флаг Deleted через рефлексию) и кандидаты ITM (равенство записи победителю при лоаде без этого мода). Счётчик majorRecordsExamined ограничен maxRecords. includeItmCandidates: false сильно ускоряет (нет второго полного лоада и разрешения победителя по каждой записи)

Ответы — JSON-текст. Для conflict-tools при ExposeToolTimingsInJson: true в том же JSON есть timings (мс) — удобно для агента и UI без stderr. У mutagen_formid_override_chain в overlay-режиме в timings есть resolvedListingsPrepMs (суммарно: чтение листингов + резолв путей до скана). Разбивка readListingsMs / resolvePathsMs выводится только в NDJSON-событии OverrideChainResolvedListings (см. ToolDiagnosticsLogPath), а не в поле timings JSON-ответа. Дополнительно логи в stderr: сборка GameEnvironment, RentFullEnvironment: CACHE HIT|MISS|…, те же цифры дублируются текстом. Если задан ToolDiagnosticsLogPath, события и тайминги пишутся в файл построчно (NDJSON) — удобно, когда stderr клиента MCP не сохраняется или нужен последующий разбор (jq, Grafana Loki и т.п.). В Docker смонтируйте каталог для файла, например -v "/path/to/mcp-logs:/logs" и -e MutagenMcp__ToolDiagnosticsLogPath=/logs/mutagen-mcp-diagnostics.ndjson.

Производительность тяжёлых инструментов

  • mutagen_formid_override_chain: winnerOnly: true — один победитель (макс. индекс лоадордера); overlay параллелит открытия как полный скан. winnerOnly: false — полная цепочка. accurateRecordLookup: true — перебор всех major-записей в каждом плагине лоада вместо быстрого top-level поиска: на сотнях модов и «левом» FormKey время может исчисляться минутами; по умолчанию false. В timings JSON (и NDJSON ConflictToolOk) для overlay есть resolvedListingsPrepMs. Детальная разбивка чтения лоада vs резолва путей — в NDJSON OverrideChainResolvedListings (readListingsMs, resolvePathsMs). maxChainLength только обрезка JSON.
  • mutagen_verify_masters с includeDirectEdges: false сильно уменьшает размер ответа при том же объёме работы на диске (чтение заголовков плагинов для графа).
  • mutagen_list_plugins: для обзора лоада без гигантского JSON используйте offset и умеренный maxPlugins; для поиска «дыр» в установке — onlyFileMissing.
  • Кэш резолва путей (см. выше) переиспользуется между вызовами в одном процессе: повторный mutagen_list_plugins, mutagen_verify_masters, mutagen_formid_override_chain и т.д. после первого полного прохода по именам дают гораздо меньше обращений к диску, пока не сменились корни или modlist.txt.
  • Включите CacheGameEnvironment (и при необходимости EnvironmentCacheMaxAgeSeconds), если клиент MCP часто вызывает тяжёлые инструменты с полным лоадом подряд: повторно не поднимается полный GameEnvironment (кроме сценария ITM — там по-прежнему строится второй лоад без целевого мода).
  • Для Docker задайте достаточный лимит памяти контейнера: кэш окружения держит один полный граф модов в RAM; словарь путей к плагинам обычно скромнее, но тоже живёт в процессе.
  • Не запускайте несколько долгих вызовов параллельно на одном stdio-процессе без необходимости.

Ограничения v1

  • mutagen_formid_override_chain не видит плагины, включённые в plugins.txt, но без найденного файла под DataFolder / PluginSearchRoots / MO2 — они выпадают из скана. Стандартные мастера (Skyrim.esm, …) при PrependImplicitStandardMasters: true добавляются к лоаду даже без строк в plugins.txt (см. конфиг). Пустая цепочка при корректном лоаде часто означает неверную строку FormKey относительно Mutagen, а не только «нет оверрайдов».
  • Инструменты по FormKey и сравнению плагинов используют резолв путей к файлам плагинов (внутрипроцессный кэш имён до смены корней / modlist.txt / ProbeDataSubfolder). Полный GameEnvironment поднимается в зависимости от режима (overlay vs полный лоад) и CacheGameEnvironment; держите лимиты (maxRecords, maxResults, настройки Max*) разумными.
  • Семантика ITM / сравнение записей опирается на Loqui/Mutagen Equals, а не на побайтовое совпадение с xEdit; удалённые записи определяются через MajorRecordFlags рефлексией — возможны расхождения с UI.
  • includeHeaders в mutagen_list_plugins открывает каждый плагин через Mutagen — держите maxPlugins умеренным; для длинного лоада используйте offset и при необходимости onlyFileMissing; большие JSON-ответы клиент MCP может обрывать по таймауту.
  • mutagen_plugin_master_closure строит только мастер → мастер мастера из заголовков; патчи без записи в мастерах и «кто зависит от плагина X» сюда не входят.
  • mutagen_verify_masters по умолчанию обрабатывает только первые maxPlugins включённых записей в порядке файла — не весь список целиком; увеличьте maxPlugins или MaxPluginsPerRequest для полного прохода.
  • Разрешение по modlist.txt опирается на строки +ИмяПапкиМода; при несовпадении имени папки на диске плагин может не находиться.

Лицензия

Укажите лицензию по желанию владельца репозитория (файл не добавлялся автоматически).

目录标签

目录标签

C#Cursor云端部署游戏插件分析本地部署Mod管理冲突检测SkyrimSEMutagen

支持客户端

Cursor

接入字段

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

stdio

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

none

运行时(runtime,运行环境)

Docker

工具数量(toolCount,工具数)

10

资源数量(resourceCount,资源数)

0

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

0

权限和风险

stdionone部署方式未说明

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

安装前确认

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

来源信息

继续浏览同类 MCP