@adhisang/minecraft-modding-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +765 -0
  4. package/dist/access-widener-parser.d.ts +24 -0
  5. package/dist/access-widener-parser.js +77 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +4 -0
  8. package/dist/config.d.ts +27 -0
  9. package/dist/config.js +178 -0
  10. package/dist/decompiler/vineflower.d.ts +15 -0
  11. package/dist/decompiler/vineflower.js +185 -0
  12. package/dist/errors.d.ts +50 -0
  13. package/dist/errors.js +49 -0
  14. package/dist/hash.d.ts +1 -0
  15. package/dist/hash.js +12 -0
  16. package/dist/index.d.ts +7 -0
  17. package/dist/index.js +1447 -0
  18. package/dist/java-process.d.ts +16 -0
  19. package/dist/java-process.js +120 -0
  20. package/dist/logger.d.ts +3 -0
  21. package/dist/logger.js +21 -0
  22. package/dist/mapping-pipeline-service.d.ts +18 -0
  23. package/dist/mapping-pipeline-service.js +60 -0
  24. package/dist/mapping-service.d.ts +161 -0
  25. package/dist/mapping-service.js +1706 -0
  26. package/dist/maven-resolver.d.ts +22 -0
  27. package/dist/maven-resolver.js +122 -0
  28. package/dist/minecraft-explorer-service.d.ts +43 -0
  29. package/dist/minecraft-explorer-service.js +562 -0
  30. package/dist/mixin-parser.d.ts +34 -0
  31. package/dist/mixin-parser.js +194 -0
  32. package/dist/mixin-validator.d.ts +59 -0
  33. package/dist/mixin-validator.js +274 -0
  34. package/dist/mod-analyzer.d.ts +23 -0
  35. package/dist/mod-analyzer.js +346 -0
  36. package/dist/mod-decompile-service.d.ts +39 -0
  37. package/dist/mod-decompile-service.js +136 -0
  38. package/dist/mod-remap-service.d.ts +17 -0
  39. package/dist/mod-remap-service.js +186 -0
  40. package/dist/mod-search-service.d.ts +28 -0
  41. package/dist/mod-search-service.js +174 -0
  42. package/dist/mojang-tiny-mapping-service.d.ts +13 -0
  43. package/dist/mojang-tiny-mapping-service.js +351 -0
  44. package/dist/nbt/java-nbt-codec.d.ts +3 -0
  45. package/dist/nbt/java-nbt-codec.js +385 -0
  46. package/dist/nbt/json-patch.d.ts +3 -0
  47. package/dist/nbt/json-patch.js +352 -0
  48. package/dist/nbt/pipeline.d.ts +39 -0
  49. package/dist/nbt/pipeline.js +173 -0
  50. package/dist/nbt/typed-json.d.ts +10 -0
  51. package/dist/nbt/typed-json.js +205 -0
  52. package/dist/nbt/types.d.ts +66 -0
  53. package/dist/nbt/types.js +2 -0
  54. package/dist/observability.d.ts +88 -0
  55. package/dist/observability.js +165 -0
  56. package/dist/path-converter.d.ts +12 -0
  57. package/dist/path-converter.js +161 -0
  58. package/dist/path-resolver.d.ts +19 -0
  59. package/dist/path-resolver.js +78 -0
  60. package/dist/registry-service.d.ts +29 -0
  61. package/dist/registry-service.js +214 -0
  62. package/dist/repo-downloader.d.ts +15 -0
  63. package/dist/repo-downloader.js +111 -0
  64. package/dist/resources.d.ts +3 -0
  65. package/dist/resources.js +154 -0
  66. package/dist/search-hit-accumulator.d.ts +38 -0
  67. package/dist/search-hit-accumulator.js +153 -0
  68. package/dist/source-jar-reader.d.ts +13 -0
  69. package/dist/source-jar-reader.js +216 -0
  70. package/dist/source-resolver.d.ts +14 -0
  71. package/dist/source-resolver.js +274 -0
  72. package/dist/source-service.d.ts +404 -0
  73. package/dist/source-service.js +2881 -0
  74. package/dist/storage/artifacts-repo.d.ts +45 -0
  75. package/dist/storage/artifacts-repo.js +209 -0
  76. package/dist/storage/db.d.ts +14 -0
  77. package/dist/storage/db.js +132 -0
  78. package/dist/storage/files-repo.d.ts +78 -0
  79. package/dist/storage/files-repo.js +437 -0
  80. package/dist/storage/index-meta-repo.d.ts +35 -0
  81. package/dist/storage/index-meta-repo.js +97 -0
  82. package/dist/storage/migrations.d.ts +11 -0
  83. package/dist/storage/migrations.js +71 -0
  84. package/dist/storage/schema.d.ts +1 -0
  85. package/dist/storage/schema.js +160 -0
  86. package/dist/storage/sqlite.d.ts +20 -0
  87. package/dist/storage/sqlite.js +111 -0
  88. package/dist/storage/symbols-repo.d.ts +63 -0
  89. package/dist/storage/symbols-repo.js +401 -0
  90. package/dist/symbols/symbol-extractor.d.ts +7 -0
  91. package/dist/symbols/symbol-extractor.js +64 -0
  92. package/dist/tiny-remapper-resolver.d.ts +1 -0
  93. package/dist/tiny-remapper-resolver.js +62 -0
  94. package/dist/tiny-remapper-service.d.ts +16 -0
  95. package/dist/tiny-remapper-service.js +73 -0
  96. package/dist/types.d.ts +120 -0
  97. package/dist/types.js +2 -0
  98. package/dist/version-diff-service.d.ts +41 -0
  99. package/dist/version-diff-service.js +222 -0
  100. package/dist/version-service.d.ts +70 -0
  101. package/dist/version-service.js +411 -0
  102. package/dist/vineflower-resolver.d.ts +1 -0
  103. package/dist/vineflower-resolver.js +62 -0
  104. package/dist/workspace-mapping-service.d.ts +18 -0
  105. package/dist/workspace-mapping-service.js +89 -0
  106. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,765 @@
1
+ # @adhisang/minecraft-modding-mcp
2
+
3
+ [![npm](https://img.shields.io/npm/v/@adhisang/minecraft-modding-mcp)](https://www.npmjs.com/package/@adhisang/minecraft-modding-mcp)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![Node.js >=22](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org/)
6
+ [![CI](https://github.com/adhi-jp/minecraft-modding-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/adhi-jp/minecraft-modding-mcp/actions/workflows/ci.yml)
7
+
8
+ **[日本語](docs/README-ja.md)** | English
9
+
10
+ ---
11
+
12
+ `@adhisang/minecraft-modding-mcp` is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that gives AI assistants deep access to Minecraft's source code, mappings, and mod tooling.
13
+
14
+ It lets you explore decompiled Minecraft source, convert symbol names across four naming namespaces (`official`, `mojang`, `intermediary`, `yarn`), analyze and decompile Fabric/Forge/NeoForge mod JARs, validate Mixin and Access Widener files, read and patch NBT data, and query generated registry snapshots — all through a structured tool and resource interface designed for Claude Desktop, VS Code, and other MCP-capable clients.
15
+
16
+ **28 tools** | **7 resources** | **4 namespace mappings** | **SQLite-backed cache**
17
+
18
+ ## Features
19
+
20
+ - **Source Exploration** — Browse and search decompiled Minecraft source code with line-level precision and cursor-paginated file listing
21
+ - **Multi-Mapping Conversion** — Translate class, field, and method names between `official`, `mojang`, `intermediary`, and `yarn` namespaces
22
+ - **Symbol Lifecycle Tracking** — Trace when a method or field first appeared, disappeared, or changed across Minecraft versions
23
+ - **Mod JAR Analysis** — Extract metadata, dependencies, entrypoints, and Mixin configs from Fabric/Forge/NeoForge mod JARs
24
+ - **Mixin & Access Widener Validation** — Parse and validate Mixin source and `.accesswidener` files against a target Minecraft version
25
+ - **NBT Round-Trip** — Decode NBT binary to typed JSON, apply RFC 6902 patches, and re-encode back to NBT
26
+ - **Registry Data** — Query generated registry snapshots (blocks, items, entities, etc.) for any Minecraft version
27
+ - **Version Comparison** — Diff class signatures and registry entries between two Minecraft versions
28
+ - **JAR Remapping** — Remap Fabric mod JARs from `intermediary` to `yarn` or `mojang` namespaces
29
+ - **MCP Resources** — Access version lists, class source, artifact metadata, and mappings through URI-based resources
30
+
31
+ ## Quick Start
32
+
33
+ ### Prerequisites
34
+ - Node.js 22+
35
+ - pnpm
36
+
37
+ ### For Users (Installed Package)
38
+ ```bash
39
+ npx @adhisang/minecraft-modding-mcp
40
+ ```
41
+
42
+ ### For Developers (Repository)
43
+ ```bash
44
+ pnpm install
45
+ ```
46
+
47
+ ### Run (development)
48
+ ```bash
49
+ pnpm dev
50
+ ```
51
+
52
+ ### Build + Run (distribution shape)
53
+ ```bash
54
+ pnpm build
55
+ pnpm start
56
+ ```
57
+
58
+ ### Validate
59
+ ```bash
60
+ pnpm check
61
+ pnpm test
62
+ pnpm test:coverage
63
+ ```
64
+
65
+ ### Coverage
66
+ ```bash
67
+ pnpm test:coverage
68
+ ```
69
+
70
+ Coverage thresholds: `lines=80`, `branches=70`, `functions=80`.
71
+
72
+ Generate LCOV output for Codecov upload:
73
+
74
+ ```bash
75
+ pnpm test:coverage:lcov
76
+ ```
77
+
78
+ GitHub Actions upload workflow: `.github/workflows/codecov.yml` (triggered on `v*` tags and manual dispatch).
79
+
80
+ ### MCP Client Configuration
81
+
82
+ #### Claude Desktop
83
+
84
+ Add the following to your `claude_desktop_config.json`:
85
+
86
+ ```json
87
+ {
88
+ "mcpServers": {
89
+ "minecraft-modding": {
90
+ "command": "npx",
91
+ "args": ["-y", "@adhisang/minecraft-modding-mcp"]
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ #### VS Code
98
+
99
+ Add the following to `.vscode/mcp.json` in your workspace:
100
+
101
+ ```json
102
+ {
103
+ "servers": {
104
+ "minecraft-modding": {
105
+ "command": "npx",
106
+ "args": ["-y", "@adhisang/minecraft-modding-mcp"]
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ #### Custom Environment
113
+
114
+ Pass environment variables to override defaults:
115
+
116
+ ```json
117
+ {
118
+ "mcpServers": {
119
+ "minecraft-modding": {
120
+ "command": "npx",
121
+ "args": ["-y", "@adhisang/minecraft-modding-mcp"],
122
+ "env": {
123
+ "MCP_CACHE_DIR": "/path/to/custom/cache",
124
+ "MCP_MAPPING_SOURCE_PRIORITY": "maven-first"
125
+ }
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ## Tool Surface
132
+
133
+ ### Source Exploration
134
+
135
+ Tools for browsing Minecraft versions, resolving source artifacts, and reading/searching decompiled source code.
136
+
137
+ | Tool | Purpose | Key Inputs | Key Outputs |
138
+ | --- | --- | --- | --- |
139
+ | `list-versions` | List available Minecraft versions from Mojang manifest + local cache | `includeSnapshots?`, `limit?` | `result.latest`, `result.releases[]`, `meta.warnings[]` |
140
+ | `resolve-artifact` | Resolve source artifact from `version` / `jar` / `coordinate` | `targetKind`, `targetValue`, `mapping?`, `sourcePriority?`, `allowDecompile?` | `artifactId`, `origin`, `mappingApplied`, `qualityFlags[]`, `adjacentSourceCandidates?`, `warnings[]` |
141
+ | `get-class-source` | Get class source by `artifactId` or resolve target on demand, with line filtering | `className`, `artifactId?`, `targetKind?`, `targetValue?`, `startLine?`, `endLine?`, `maxLines?` | `sourceText`, `returnedRange`, `truncated`, `artifactId`, mapping/provenance metadata |
142
+ | `get-class-members` | Get class fields/methods/constructors from bytecode | `className`, `artifactId?`, `targetKind?`, `targetValue?`, `mapping?`, `access?`, `includeInherited?`, `maxMembers?` | `members.{constructors,fields,methods}`, `counts`, `truncated`, `context`, `warnings[]` |
143
+ | `search-class-source` | Search indexed class source for symbols/text/path | `artifactId`, `query`, `intent?`, `match?`, `packagePrefix?`, `fileGlob?`, `symbolKind?`, `snippetLines?`, `includeDefinition?`, `includeOneHop?`, `limit?`, `cursor?` | `hits[]`, `relations?`, `nextCursor?`, `totalApprox`, `mappingApplied` |
144
+ | `get-artifact-file` | Read full source file with byte guard | `artifactId`, `filePath`, `maxBytes?` | `content`, `contentBytes`, `truncated`, `mappingApplied` |
145
+ | `list-artifact-files` | List indexed source file paths with cursor pagination | `artifactId`, `prefix?`, `limit?`, `cursor?` | `items[]`, `nextCursor?`, `mappingApplied` |
146
+ | `index-artifact` | Rebuild index metadata for an existing artifact | `artifactId`, `force?` | `reindexed`, `reason`, `counts`, `indexedAt`, `durationMs` |
147
+
148
+ ### Version Comparison & Symbol Tracking
149
+
150
+ Tools for comparing class/registry changes across Minecraft versions and tracing symbol existence over time.
151
+
152
+ | Tool | Purpose | Key Inputs | Key Outputs |
153
+ | --- | --- | --- | --- |
154
+ | `trace-symbol-lifecycle` | Trace when `Class.method` exists across Minecraft versions | `symbol`, `descriptor?`, `fromVersion?`, `toVersion?`, `mapping?`, `sourcePriority?`, `maxVersions?`, `includeTimeline?` | `presence.firstSeen`, `presence.lastSeen`, `presence.missingBetween[]`, `presence.existsNow`, `timeline?`, `warnings[]` |
155
+ | `diff-class-signatures` | Compare one class between two versions and return member deltas | `className`, `fromVersion`, `toVersion`, `mapping?`, `sourcePriority?` | `classChange`, `constructors/methods/fields.{added,removed,modified}`, `summary`, `warnings[]` |
156
+ | `compare-versions` | Compare class/registry changes between two versions | `fromVersion`, `toVersion`, `category?`, `packageFilter?`, `maxClassResults?` | `classesDiff`, `registryDiff`, `summary`, `warnings[]` |
157
+
158
+ ### Mapping & Symbols
159
+
160
+ Tools for converting symbol names between namespaces and checking symbol existence.
161
+
162
+ | Tool | Purpose | Key Inputs | Key Outputs |
163
+ | --- | --- | --- | --- |
164
+ | `find-mapping` | Find mapping candidates for class/field/method symbols between namespaces | `version`, `kind`, `name`, `owner?`, `descriptor?`, `sourceMapping`, `targetMapping`, `sourcePriority?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `provenance?`, `meta.warnings[]` |
165
+ | `resolve-method-mapping-exact` | Resolve one method mapping with strict owner+name+descriptor matching | `version`, `kind` (`method`), `name`, `owner`, `descriptor`, `sourceMapping`, `targetMapping`, `sourcePriority?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `provenance?`, `meta.warnings[]` |
166
+ | `get-class-api-matrix` | Show one class API as a mapping matrix (`official/mojang/intermediary/yarn`) | `version`, `className`, `classNameMapping`, `includeKinds?`, `sourcePriority?` | `classIdentity`, `rows[]`, `meta.warnings[]` |
167
+ | `resolve-workspace-symbol` | Resolve compile-visible symbol names for a Gradle workspace (`build.gradle/.kts`) | `projectPath`, `version`, `kind`, `name`, `owner?`, `descriptor?`, `sourceMapping`, `sourcePriority?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `workspaceDetection`, `meta.warnings[]` |
168
+ | `check-symbol-exists` | Strict symbol presence check for class/field/method | `version`, `kind`, `name`, `owner?`, `descriptor?`, `sourceMapping`, `sourcePriority?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `meta.warnings[]` |
169
+
170
+ ### NBT Utilities
171
+
172
+ Tools for decoding, patching, and encoding Java Edition NBT binary data using a typed JSON representation.
173
+
174
+ | Tool | Purpose | Key Inputs | Key Outputs |
175
+ | --- | --- | --- | --- |
176
+ | `nbt-to-json` | Decode Java Edition NBT binary (`base64`) to typed JSON | `nbtBase64`, `compression?` (`none`, `gzip`, `auto`) | `typedJson`, `meta.compressionDetected`, `meta.inputBytes` |
177
+ | `nbt-apply-json-patch` | Apply RFC 6902 patch (`add/remove/replace/test`) to typed NBT JSON | `typedJson`, `patch` | `typedJson`, `meta.appliedOps`, `meta.testOps`, `meta.changed` |
178
+ | `json-to-nbt` | Encode typed JSON back to Java Edition NBT binary (`base64`) | `typedJson`, `compression?` (`none`, `gzip`) | `nbtBase64`, `meta.outputBytes`, `meta.compressionApplied` |
179
+
180
+ ### Mod Analysis
181
+
182
+ Tools for extracting metadata from mod JARs, decompiling mod source, searching mod code, and remapping mod namespaces.
183
+
184
+ | Tool | Purpose | Key Inputs | Key Outputs |
185
+ | --- | --- | --- | --- |
186
+ | `analyze-mod-jar` | Extract mod metadata/dependencies/entrypoints from mod JAR | `jarPath`, `includeClasses?` | `modId`, `loader`, `dependencies`, `entrypoints`, `mixinConfigs`, class stats |
187
+ | `decompile-mod-jar` | Decompile mod JAR and optionally return one class source | `jarPath`, `className?` | `outputDir`, `fileCount`, `files?`, `source?`, `warnings[]` |
188
+ | `get-mod-class-source` | Read one class source from decompiled mod cache | `jarPath`, `className` | `className`, `content`, `totalLines`, `warnings[]` |
189
+ | `search-mod-source` | Search decompiled mod source by class/method/field/content | `jarPath`, `query`, `searchType?`, `limit?` | `hits[]`, `totalHits`, `truncated`, `warnings[]` |
190
+ | `remap-mod-jar` | Remap a Fabric mod JAR from intermediary to yarn/mojang names | `inputJar`, `targetMapping`, `mcVersion?`, `outputJar?` | `outputJar`, `mcVersion`, `fromMapping`, `targetMapping`, `resolvedTargetNamespace`, `warnings[]` |
191
+
192
+ ### Validation
193
+
194
+ Tools for validating Mixin source and Access Widener files against a target Minecraft version.
195
+
196
+ | Tool | Purpose | Key Inputs | Key Outputs |
197
+ | --- | --- | --- | --- |
198
+ | `validate-mixin` | Parse/validate Mixin source against target Minecraft version | `source`, `version`, `mapping?`, `sourcePriority?` | `valid`, `issues[]`, `warnings[]`, `summary` |
199
+ | `validate-access-widener` | Parse/validate Access Widener content against target version | `content`, `version`, `mapping?`, `sourcePriority?` | `valid`, `issues[]`, `warnings[]`, `summary` |
200
+
201
+ ### Registry & Diagnostics
202
+
203
+ Tools for querying generated registry data and inspecting server runtime state.
204
+
205
+ | Tool | Purpose | Key Inputs | Key Outputs |
206
+ | --- | --- | --- | --- |
207
+ | `get-registry-data` | Get generated registry snapshots (blocks/items/entities etc.) | `version`, `registry?` | `registries` (all or selected), `warnings[]` |
208
+ | `get-runtime-metrics` | Inspect runtime counters and latency snapshots | none | `result.*` runtime metrics, `meta` envelope |
209
+
210
+ ### Tool Constraints
211
+
212
+ `get-class-source` requires either `artifactId` or `targetKind`+`targetValue`. Supplying both is rejected.
213
+ `get-class-members` requires either `artifactId` or `targetKind`+`targetValue`, and needs a binary jar (`binaryJarPath`) to read `.class` entries.
214
+ `search-class-source` uses `limit: 20` by default; `snippetLines` defaults to `8` and is clamped to `1..80`; `includeDefinition` and `includeOneHop` default to `false`.
215
+ `search-class-source` with `match=regex` enforces `query.length <= 200` and a strict result cap of `100`.
216
+ `resolve-artifact` with `targetKind=jar` only auto-adopts the exact sibling `"<jar-basename>-sources.jar"`. Other adjacent `*-sources.jar` files are returned as `adjacentSourceCandidates` info only and are never auto-selected.
217
+ Mod tool `jarPath` inputs are normalized to a canonical local `.jar` file path before existence checks, cache keying, and processing.
218
+ `search-mod-source` enforces `query.length <= 200` and `limit <= 200`.
219
+ `remap-mod-jar` requires Java to be installed and only supports Fabric/Quilt mods.
220
+
221
+ ## Resources
222
+
223
+ MCP resources provide URI-based access to Minecraft data, usable by any MCP client that supports the resource protocol.
224
+
225
+ ### Fixed Resources
226
+
227
+ | Resource | URI | Description |
228
+ | --- | --- | --- |
229
+ | `versions-list` | `mc://versions/list` | List all available Minecraft versions with their metadata |
230
+ | `runtime-metrics` | `mc://metrics` | Runtime metrics and performance counters for the MCP server |
231
+
232
+ ### Template Resources
233
+
234
+ | Resource | URI Template | Description |
235
+ | --- | --- | --- |
236
+ | `class-source` | `mc://source/{artifactId}/{className}` | Java source code for a class within a resolved artifact |
237
+ | `artifact-file` | `mc://artifact/{artifactId}/files/{filePath}` | Raw content of a file within a resolved artifact |
238
+ | `find-mapping` | `mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{name}` | Look up a mapping between two naming namespaces |
239
+ | `class-members` | `mc://artifact/{artifactId}/members/{className}` | List constructors, methods, and fields for a class |
240
+ | `artifact-metadata` | `mc://artifact/{artifactId}` | Metadata for a previously resolved artifact |
241
+
242
+ ## Response Envelope
243
+
244
+ All tools return exactly one of:
245
+
246
+ - Success: `{ result: { ... }, meta: { requestId, tool, durationMs, warnings[] } }`
247
+ - Failure: `{ error: { type, title, detail, status, code, instance, fieldErrors?, hints? }, meta: { requestId, tool, durationMs, warnings[] } }`
248
+
249
+ ## Examples
250
+
251
+ ### Source Exploration
252
+
253
+ #### Resolve from Minecraft version
254
+ ```json
255
+ {
256
+ "tool": "resolve-artifact",
257
+ "arguments": {
258
+ "targetKind": "version",
259
+ "targetValue": "1.21.10",
260
+ "mapping": "official",
261
+ "allowDecompile": true
262
+ }
263
+ }
264
+ ```
265
+
266
+ #### Get class source with line window
267
+ ```json
268
+ {
269
+ "tool": "get-class-source",
270
+ "arguments": {
271
+ "artifactId": "<artifact-id>",
272
+ "className": "net.minecraft.server.Main",
273
+ "startLine": 50,
274
+ "endLine": 180,
275
+ "maxLines": 80
276
+ }
277
+ }
278
+ ```
279
+
280
+ #### Search by method symbol
281
+ ```json
282
+ {
283
+ "tool": "search-class-source",
284
+ "arguments": {
285
+ "artifactId": "<artifact-id>",
286
+ "query": "tickServer",
287
+ "intent": "symbol",
288
+ "match": "exact",
289
+ "includeOneHop": true
290
+ }
291
+ }
292
+ ```
293
+
294
+ #### Get class member list
295
+ ```json
296
+ {
297
+ "tool": "get-class-members",
298
+ "arguments": {
299
+ "artifactId": "<artifact-id>",
300
+ "className": "net.minecraft.server.Main",
301
+ "mapping": "official",
302
+ "access": "all",
303
+ "includeInherited": true,
304
+ "maxMembers": 300
305
+ }
306
+ }
307
+ ```
308
+
309
+ #### List artifact files with prefix filter
310
+
311
+ List source files under a specific package to understand project structure:
312
+
313
+ ```json
314
+ {
315
+ "tool": "list-artifact-files",
316
+ "arguments": {
317
+ "artifactId": "<artifact-id>",
318
+ "prefix": "net/minecraft/world/level/",
319
+ "limit": 50
320
+ }
321
+ }
322
+ ```
323
+
324
+ ### Version Comparison & Symbol Tracking
325
+
326
+ #### Trace `Class.method` lifecycle
327
+ ```json
328
+ {
329
+ "tool": "trace-symbol-lifecycle",
330
+ "arguments": {
331
+ "symbol": "net.minecraft.server.Main.tickServer",
332
+ "descriptor": "()V",
333
+ "fromVersion": "1.20.1",
334
+ "toVersion": "1.21.10",
335
+ "includeTimeline": true
336
+ }
337
+ }
338
+ ```
339
+
340
+ #### Diff one class across two versions
341
+ ```json
342
+ {
343
+ "tool": "diff-class-signatures",
344
+ "arguments": {
345
+ "className": "net.minecraft.server.Main",
346
+ "fromVersion": "1.20.1",
347
+ "toVersion": "1.21.10",
348
+ "mapping": "official"
349
+ }
350
+ }
351
+ ```
352
+
353
+ #### Compare two Minecraft versions
354
+
355
+ Get a high-level summary of what changed between two releases, including class additions/removals and registry diffs:
356
+
357
+ ```json
358
+ {
359
+ "tool": "compare-versions",
360
+ "arguments": {
361
+ "fromVersion": "1.20.4",
362
+ "toVersion": "1.21.10",
363
+ "category": "all",
364
+ "packageFilter": "net.minecraft.world",
365
+ "maxClassResults": 100
366
+ }
367
+ }
368
+ ```
369
+
370
+ ### Mapping & Symbols
371
+
372
+ #### Lookup mapping candidates
373
+ ```json
374
+ {
375
+ "tool": "find-mapping",
376
+ "arguments": {
377
+ "version": "1.21.10",
378
+ "kind": "class",
379
+ "name": "a.b.C",
380
+ "sourceMapping": "official",
381
+ "targetMapping": "mojang",
382
+ "sourcePriority": "loom-first"
383
+ }
384
+ }
385
+ ```
386
+
387
+ #### Lookup method mapping with descriptor
388
+ ```json
389
+ {
390
+ "tool": "find-mapping",
391
+ "arguments": {
392
+ "version": "1.21.10",
393
+ "kind": "method",
394
+ "name": "tick",
395
+ "owner": "a.b.C",
396
+ "descriptor": "(I)V",
397
+ "sourceMapping": "official",
398
+ "targetMapping": "intermediary"
399
+ }
400
+ }
401
+ ```
402
+
403
+ #### Resolve exact method mapping
404
+ ```json
405
+ {
406
+ "tool": "resolve-method-mapping-exact",
407
+ "arguments": {
408
+ "version": "1.21.10",
409
+ "kind": "method",
410
+ "name": "f",
411
+ "owner": "a.b.C",
412
+ "descriptor": "(Ljava/lang/String;)V",
413
+ "sourceMapping": "official",
414
+ "targetMapping": "mojang"
415
+ }
416
+ }
417
+ ```
418
+
419
+ #### Show class API mapping matrix
420
+ ```json
421
+ {
422
+ "tool": "get-class-api-matrix",
423
+ "arguments": {
424
+ "version": "1.21.10",
425
+ "className": "a.b.C",
426
+ "classNameMapping": "official",
427
+ "includeKinds": "class,field,method"
428
+ }
429
+ }
430
+ ```
431
+
432
+ #### Resolve workspace compile-visible symbol
433
+ ```json
434
+ {
435
+ "tool": "resolve-workspace-symbol",
436
+ "arguments": {
437
+ "projectPath": "/path/to/mod/workspace",
438
+ "version": "1.21.10",
439
+ "kind": "method",
440
+ "name": "f",
441
+ "owner": "a.b.C",
442
+ "descriptor": "(Ljava/lang/String;)V",
443
+ "sourceMapping": "official"
444
+ }
445
+ }
446
+ ```
447
+
448
+ #### Check symbol existence
449
+ ```json
450
+ {
451
+ "tool": "check-symbol-exists",
452
+ "arguments": {
453
+ "version": "1.21.10",
454
+ "kind": "method",
455
+ "name": "f",
456
+ "owner": "a.b.C",
457
+ "descriptor": "(I)V",
458
+ "sourceMapping": "official"
459
+ }
460
+ }
461
+ ```
462
+
463
+ ### NBT Utilities
464
+
465
+ #### Decode Java NBT base64 to typed JSON
466
+ ```json
467
+ {
468
+ "tool": "nbt-to-json",
469
+ "arguments": {
470
+ "nbtBase64": "<base64-nbt>",
471
+ "compression": "auto"
472
+ }
473
+ }
474
+ ```
475
+
476
+ #### Patch typed NBT JSON
477
+ ```json
478
+ {
479
+ "tool": "nbt-apply-json-patch",
480
+ "arguments": {
481
+ "typedJson": {
482
+ "rootName": "Level",
483
+ "root": { "type": "compound", "value": {} }
484
+ },
485
+ "patch": [
486
+ { "op": "add", "path": "/root/value/name", "value": { "type": "string", "value": "Alex" } }
487
+ ]
488
+ }
489
+ }
490
+ ```
491
+
492
+ #### Encode typed JSON back to NBT base64
493
+ ```json
494
+ {
495
+ "tool": "json-to-nbt",
496
+ "arguments": {
497
+ "typedJson": {
498
+ "rootName": "Level",
499
+ "root": { "type": "compound", "value": {} }
500
+ },
501
+ "compression": "gzip"
502
+ }
503
+ }
504
+ ```
505
+
506
+ ### Mod Analysis Workflow
507
+
508
+ A typical mod analysis workflow progresses through metadata extraction, decompilation, source reading, and search:
509
+
510
+ #### 1. Analyze mod metadata
511
+
512
+ Extract loader type, mod ID, dependencies, and Mixin configurations from a mod JAR:
513
+
514
+ ```json
515
+ {
516
+ "tool": "analyze-mod-jar",
517
+ "arguments": {
518
+ "jarPath": "/path/to/mymod-1.0.0.jar",
519
+ "includeClasses": true
520
+ }
521
+ }
522
+ ```
523
+
524
+ #### 2. Decompile the mod JAR
525
+
526
+ Decompile all classes and optionally retrieve a specific class inline:
527
+
528
+ ```json
529
+ {
530
+ "tool": "decompile-mod-jar",
531
+ "arguments": {
532
+ "jarPath": "/path/to/mymod-1.0.0.jar",
533
+ "className": "com.example.mymod.MyMod"
534
+ }
535
+ }
536
+ ```
537
+
538
+ #### 3. Read a specific class from decompiled source
539
+
540
+ After decompilation, read any class without re-decompiling:
541
+
542
+ ```json
543
+ {
544
+ "tool": "get-mod-class-source",
545
+ "arguments": {
546
+ "jarPath": "/path/to/mymod-1.0.0.jar",
547
+ "className": "com.example.mymod.mixin.PlayerMixin"
548
+ }
549
+ }
550
+ ```
551
+
552
+ #### 4. Search across decompiled mod source
553
+
554
+ Find method references, field usages, or text patterns across the entire decompiled mod:
555
+
556
+ ```json
557
+ {
558
+ "tool": "search-mod-source",
559
+ "arguments": {
560
+ "jarPath": "/path/to/mymod-1.0.0.jar",
561
+ "query": "onPlayerTick",
562
+ "searchType": "method",
563
+ "limit": 50
564
+ }
565
+ }
566
+ ```
567
+
568
+ #### 5. Remap mod JAR to readable names
569
+
570
+ Remap a Fabric mod from `intermediary` to `yarn` names for easier reading:
571
+
572
+ ```json
573
+ {
574
+ "tool": "remap-mod-jar",
575
+ "arguments": {
576
+ "inputJar": "/path/to/mymod-1.0.0.jar",
577
+ "targetMapping": "yarn",
578
+ "mcVersion": "1.21.10"
579
+ }
580
+ }
581
+ ```
582
+
583
+ ### Validation
584
+
585
+ #### Validate Mixin source
586
+
587
+ Check a Mixin class source for correctness against a target Minecraft version:
588
+
589
+ ```json
590
+ {
591
+ "tool": "validate-mixin",
592
+ "arguments": {
593
+ "source": "@Mixin(PlayerEntity.class)\npublic abstract class PlayerMixin {\n @Inject(method = \"tick\", at = @At(\"HEAD\"))\n private void onTick(CallbackInfo ci) {}\n}",
594
+ "version": "1.21.10",
595
+ "mapping": "yarn"
596
+ }
597
+ }
598
+ ```
599
+
600
+ #### Validate Access Widener
601
+
602
+ Check an Access Widener file for valid entries against the target version:
603
+
604
+ ```json
605
+ {
606
+ "tool": "validate-access-widener",
607
+ "arguments": {
608
+ "content": "accessWidener v2 named\naccessible class net/minecraft/server/Main\naccessible method net/minecraft/server/Main tick ()V",
609
+ "version": "1.21.10",
610
+ "mapping": "yarn"
611
+ }
612
+ }
613
+ ```
614
+
615
+ ### Registry & Diagnostics
616
+
617
+ #### Get all registries for a version
618
+
619
+ Retrieve the full set of generated registries (blocks, items, entities, etc.) for a Minecraft version:
620
+
621
+ ```json
622
+ {
623
+ "tool": "get-registry-data",
624
+ "arguments": {
625
+ "version": "1.21.10"
626
+ }
627
+ }
628
+ ```
629
+
630
+ #### Get a single registry
631
+
632
+ Fetch only a specific registry type:
633
+
634
+ ```json
635
+ {
636
+ "tool": "get-registry-data",
637
+ "arguments": {
638
+ "version": "1.21.10",
639
+ "registry": "minecraft:block"
640
+ }
641
+ }
642
+ ```
643
+
644
+ #### Force reindex an artifact
645
+
646
+ Rebuild the search index for an artifact after cache or tooling changes:
647
+
648
+ ```json
649
+ {
650
+ "tool": "index-artifact",
651
+ "arguments": {
652
+ "artifactId": "<artifact-id>",
653
+ "force": true
654
+ }
655
+ }
656
+ ```
657
+
658
+ #### Inspect runtime metrics
659
+
660
+ Check server performance counters, cache sizes, and latency snapshots:
661
+
662
+ ```json
663
+ {
664
+ "tool": "get-runtime-metrics",
665
+ "arguments": {}
666
+ }
667
+ ```
668
+
669
+ ## Mapping Policy
670
+
671
+ ### Namespace Definitions
672
+
673
+ | Namespace | Description |
674
+ | --- | --- |
675
+ | `official` | Mojang obfuscated names (e.g. `a`, `b`, `c`) |
676
+ | `mojang` | Mojang deobfuscated names from `client_mappings.txt` (e.g. `net.minecraft.server.Main`) |
677
+ | `intermediary` | Fabric stable intermediary names (e.g. `net.minecraft.class_1234`, `method_5678`) |
678
+ | `yarn` | Fabric community human-readable names (e.g. `net.minecraft.server.MinecraftServer`, `tick`) |
679
+
680
+ ### Lookup Rules
681
+
682
+ `find-mapping` supports lookup across `official`, `mojang`, `intermediary`, and `yarn`.
683
+
684
+ Symbol query inputs use `kind` + `name` + optional `owner`/`descriptor`:
685
+ - class: `kind=class`, `name=a.b.C` (FQCN only)
686
+ - field: `kind=field`, `owner=a.b.C`, `name=fieldName`
687
+ - method: `kind=method`, `owner=a.b.C`, `name=methodName`, `descriptor=(I)V`
688
+
689
+ `mapping: "mojang"` requires a source-backed artifact. If only decompile path is available, the server returns `ERR_MAPPING_NOT_APPLIED`.
690
+
691
+ `resolve-artifact`, `get-class-members`, `trace-symbol-lifecycle`, and `diff-class-signatures` accept `official | mojang | intermediary | yarn` with constraints:
692
+ - `intermediary` / `yarn` require a resolvable Minecraft version context (for example `targetKind=version` or a versioned coordinate).
693
+ - for unobfuscated versions (for example 26.1+), requesting `intermediary` / `yarn` falls back to `official` with a warning.
694
+ - `mojang` requires source-backed artifacts; decompile-only paths are rejected with `ERR_MAPPING_NOT_APPLIED`.
695
+
696
+ Method descriptor precision is best on Tiny-backed paths (`intermediary`/`yarn`). For `official <-> mojang`, Mojang `client_mappings` do not carry JVM descriptors, so descriptor queries may fallback to name matching and emit a warning.
697
+
698
+ Use `resolve-method-mapping-exact` when candidate ranking is not enough and the workflow needs strict `owner+name+descriptor` certainty.
699
+ Use `resolve-workspace-symbol` when you need compile-visible names from actual Gradle Loom mappings in a workspace.
700
+
701
+ ## Environment Variables
702
+
703
+ ### Core
704
+
705
+ | Variable | Default | Description |
706
+ | --- | --- | --- |
707
+ | `MCP_CACHE_DIR` | `.cache/minecraft-modding-mcp` | Cache root for downloads and SQLite |
708
+ | `MCP_SQLITE_PATH` | `<cacheDir>/source-cache.db` | SQLite database path |
709
+ | `MCP_SOURCE_REPOS` | Maven Central + Fabric + Forge + NeoForge | Comma-separated Maven repository URLs |
710
+ | `MCP_LOCAL_M2` | `~/.m2/repository` | Local Maven repository path |
711
+ | `MCP_ENABLE_INDEXED_SEARCH` | `true` | Enable indexed query path for `search-class-source` |
712
+ | `MCP_MAPPING_SOURCE_PRIORITY` | `loom-first` | Mapping source priority (`loom-first` or `maven-first`) |
713
+ | `MCP_VERSION_MANIFEST_URL` | Mojang manifest URL | Override manifest endpoint for testing/private mirrors |
714
+
715
+ ### Limits & Tuning
716
+
717
+ | Variable | Default | Description |
718
+ | --- | --- | --- |
719
+ | `MCP_MAX_CONTENT_BYTES` | `1000000` | Maximum bytes for file read operations |
720
+ | `MCP_MAX_SEARCH_HITS` | `200` | Maximum search result count |
721
+ | `MCP_MAX_ARTIFACTS` | `200` | Maximum cached artifacts |
722
+ | `MCP_MAX_CACHE_BYTES` | `2147483648` | Maximum total cache size in bytes |
723
+ | `MCP_FETCH_TIMEOUT_MS` | `15000` | HTTP request timeout in milliseconds |
724
+ | `MCP_FETCH_RETRIES` | `2` | HTTP request retry count |
725
+
726
+ ### Decompilation & Remapping
727
+
728
+ | Variable | Default | Description |
729
+ | --- | --- | --- |
730
+ | `MCP_VINEFLOWER_JAR_PATH` | unset | External Vineflower JAR path (auto-downloaded if unset) |
731
+ | `MCP_TINY_REMAPPER_JAR_PATH` | unset | External tiny-remapper JAR path (auto-downloaded if unset) |
732
+ | `MCP_REMAP_TIMEOUT_MS` | `600000` | Remap operation timeout in milliseconds |
733
+ | `MCP_REMAP_MAX_MEMORY_MB` | `4096` | Maximum JVM heap for remap operations |
734
+
735
+ ### NBT
736
+
737
+ | Variable | Default | Description |
738
+ | --- | --- | --- |
739
+ | `MCP_MAX_NBT_INPUT_BYTES` | `4194304` | Maximum decoded NBT input bytes accepted by `nbt-to-json` |
740
+ | `MCP_MAX_NBT_INFLATED_BYTES` | `16777216` | Maximum gzip-inflated bytes accepted by `nbt-to-json` |
741
+ | `MCP_MAX_NBT_RESPONSE_BYTES` | `8388608` | Maximum response payload bytes for NBT tools |
742
+
743
+ ## Architecture
744
+
745
+ | Component | Technology |
746
+ | --- | --- |
747
+ | Runtime | Node.js 22+ (native `node:sqlite`) |
748
+ | Transport | stdio (MCP standard) |
749
+ | Storage | SQLite — artifact metadata, source index, mapping cache |
750
+ | Decompilation | [Vineflower](https://github.com/Vineflower/vineflower) (auto-downloaded) |
751
+ | Remapping | [tiny-remapper](https://github.com/FabricMC/tiny-remapper) (requires Java) |
752
+ | Mapping Sources | Mojang `client_mappings.txt`, Fabric Loom workspace, Maven Tiny v2 |
753
+
754
+ The server runs as a single long-lived process communicating over stdio. Artifacts (source JARs, binary JARs, mapping files) are downloaded on demand and cached in SQLite. The search index is built lazily on first query and persisted for subsequent calls.
755
+
756
+ ## Development Notes
757
+
758
+ - `SourceService` is the canonical implementation for artifact resolution, ingestion, and source querying.
759
+ - `version` resolution downloads Mojang client JARs into cache and routes them through the same ingestion flow as `jar` and `coordinate` targets.
760
+ - Tool responses are always wrapped as `{ result?, error?, meta }`.
761
+ - `meta` includes `requestId`, `tool`, `durationMs`, and `warnings[]`.
762
+
763
+ ## License
764
+
765
+ [MIT](LICENSE)