@adhisang/minecraft-modding-mcp 1.2.0 → 2.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.
- package/CHANGELOG.md +38 -1
- package/README.md +87 -46
- package/dist/decompiler/vineflower.js +2 -2
- package/dist/index.js +150 -175
- package/dist/mapping-pipeline-service.d.ts +1 -1
- package/dist/mapping-pipeline-service.js +5 -5
- package/dist/mapping-service.d.ts +3 -4
- package/dist/mapping-service.js +40 -46
- package/dist/mcp-helpers.d.ts +10 -2
- package/dist/mcp-helpers.js +59 -5
- package/dist/minecraft-explorer-service.d.ts +1 -1
- package/dist/minecraft-explorer-service.js +1 -1
- package/dist/mixin-validator.js +5 -5
- package/dist/mojang-tiny-mapping-service.js +26 -26
- package/dist/resources.js +7 -7
- package/dist/search-hit-accumulator.d.ts +0 -3
- package/dist/search-hit-accumulator.js +4 -4
- package/dist/source-resolver.d.ts +1 -0
- package/dist/source-resolver.js +94 -2
- package/dist/source-service.d.ts +34 -43
- package/dist/source-service.js +597 -670
- package/dist/storage/files-repo.d.ts +9 -0
- package/dist/storage/files-repo.js +42 -0
- package/dist/storage/migrations.d.ts +1 -1
- package/dist/storage/migrations.js +6 -2
- package/dist/storage/schema.d.ts +1 -0
- package/dist/storage/schema.js +7 -0
- package/dist/tool-input.d.ts +6 -0
- package/dist/tool-input.js +64 -0
- package/dist/types.d.ts +1 -1
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.0.0] - 2026-03-07
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Breaking change: the public mapping namespace `official` was removed and replaced with `obfuscated` across tool inputs, outputs, API matrix keys, diagnostics, and examples. Requests that still send `official` now fail with `ERR_INVALID_INPUT` and should be updated to `obfuscated`.
|
|
14
|
+
- Breaking change: `resolve-artifact` now accepts `target: { kind, value }` instead of top-level `targetKind` / `targetValue`. `get-class-source` and `get-class-members` now require `target: { type: "artifact", artifactId }` or `target: { type: "resolve", kind, value }` instead of top-level `artifactId` / `targetKind` / `targetValue`.
|
|
15
|
+
- Breaking change: `resolve-method-mapping-exact` is now method-only and no longer accepts `kind`; callers must send `owner` and `descriptor`.
|
|
16
|
+
- Breaking change: `validate-mixin` replaced the mutually exclusive top-level source selector fields (`source`, `sourcePath`, `sourcePaths`, `mixinConfigPath`, `sourceRoot`) with `input.mode` plus `input.source` / `input.path` / `input.paths[]` / `input.configPaths[]` and `sourceRoots[]`.
|
|
17
|
+
- Breaking change: `validate-mixin` now always returns normalized batch-style output with `mode`, `results[]`, and `summary`. The deprecated `summary.errors` field was removed; use `summary.processingErrors` instead.
|
|
18
|
+
- Breaking change: `search-class-source` now returns compact hits only. The removed `snippetLines`, `includeDefinition`, and `includeOneHop` inputs no longer trigger snippet/definition/relation expansion, `totalApprox` was removed from responses, and `symbolKind` is only valid with `intent=symbol`.
|
|
19
|
+
- MCP tool responses now mirror the `{ result?, error?, meta }` envelope in `structuredContent`, and failures also set `isError=true` for SDK-aware clients.
|
|
20
|
+
- MCP resources: JSON resources now return structured `{ result, meta }` success envelopes and `{ error, meta }` failures. Text resources (`class-source`, `artifact-file`) still return raw text on success, but now also use structured JSON errors on failure.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- `resolve-artifact`: `targetKind=coordinate` now reuses the local Gradle `modules-2` cache in addition to the local Maven repository and configured source repos, so cached third-party libraries such as Architectury can resolve without manual cache spelunking.
|
|
24
|
+
- `resolve-artifact`: `mapping=mojang` + Loom merged source discovery now flags partial source coverage with `qualityFlags=["partial-source-no-net-minecraft"]` and a warning when the selected source jar does not actually contain `net.minecraft` entries.
|
|
25
|
+
- `get-class-source` / `get-class-members`: when an artifact is resolved from a `*-sources.jar`, the server now keeps the sibling binary jar and automatically falls back to it when source coverage is incomplete instead of treating the source jar as bytecode.
|
|
26
|
+
- `get-class-source`: partial-source binary fallback now bypasses the same sibling `*-sources.jar` that triggered the miss, and fallback failures for vanilla classes point to `get-class-api-matrix` instead of misleading `find-class` recovery.
|
|
27
|
+
- `get-class-members`: bytecode lookup now follows the resolved artifact namespace (`mappingApplied`) before remapping members back to the requested namespace, fixing merged Mojang artifacts that were incorrectly forced through obfuscated class names.
|
|
28
|
+
- `find-class`: zero-hit lookups against `mapping=obfuscated` now warn when the query looks like a deobfuscated Mojang class name.
|
|
29
|
+
- `find-class`: partial-source artifacts now suppress non-vanilla matches for vanilla-looking queries (for example `Item`) and return a warning instead of misleading modded classes.
|
|
30
|
+
- Tool input parsing: positive integer parameters now accept numeric strings such as `"10"` instead of failing validation immediately.
|
|
31
|
+
- Tool input parsing now leaves nested `typedJson` and JSON Patch `value` payload fields untouched, even when their keys happen to match top-level numeric option names such as `limit` or `maxLines`.
|
|
32
|
+
|
|
33
|
+
### Performance
|
|
34
|
+
- `search-class-source`: reduce search latency, heap growth, and DB round-trips by returning compact hits only and skipping snippet hydration, relation expansion, and `totalApprox` count queries.
|
|
35
|
+
- Tool input preprocessing now stays shallow, avoiding recursive scans through large nested payloads such as NBT typed JSON and patch bodies.
|
|
36
|
+
|
|
37
|
+
## [1.2.1] - 2026-03-05
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- MCP startup regression: removed eager `SourceService` pre-initialization during server startup so `tools/list` handshakes are not blocked by SQLite initialization on slower environments.
|
|
41
|
+
- Decompiler: skip Java/Vineflower availability checks when decompiled source is already cached, avoiding unnecessary startup errors on systems without Java.
|
|
42
|
+
|
|
43
|
+
### Documentation
|
|
44
|
+
- Clarified startup behavior in README (`SourceService` remains lazy and is not pre-initialized before tool discovery).
|
|
45
|
+
|
|
8
46
|
## [1.2.0] - 2026-03-05
|
|
9
47
|
|
|
10
48
|
### Added
|
|
@@ -48,7 +86,6 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2
|
|
|
48
86
|
### Changed
|
|
49
87
|
- Lazy `SourceService` initialization — deferred until first tool/resource access, reducing cold-start latency during MCP handshake.
|
|
50
88
|
- Eagerly init `SourceService` during MCP handshake idle time for faster first-request response.
|
|
51
|
-
- Codecov workflow temporarily disabled.
|
|
52
89
|
|
|
53
90
|
### Performance
|
|
54
91
|
- Avoid duplicate UTF-8 decode during truncation.
|
package/README.md
CHANGED
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
|
|
12
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
13
|
|
|
14
|
-
It lets you explore decompiled Minecraft source, convert symbol names across four naming namespaces (`
|
|
14
|
+
It lets you explore decompiled Minecraft source, convert symbol names across four naming namespaces (`obfuscated`, `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
15
|
|
|
16
16
|
**29 tools** | **7 resources** | **4 namespace mappings** | **SQLite-backed cache**
|
|
17
17
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
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 `
|
|
21
|
+
- **Multi-Mapping Conversion** — Translate class, field, and method names between `obfuscated`, `mojang`, `intermediary`, and `yarn` namespaces
|
|
22
22
|
- **Symbol Lifecycle Tracking** — Trace when a method or field first appeared, disappeared, or changed across Minecraft versions
|
|
23
23
|
- **Mod JAR Analysis** — Extract metadata, dependencies, entrypoints, and Mixin configs from Fabric/Forge/NeoForge mod JARs
|
|
24
24
|
- **Mixin & Access Widener Validation** — Parse and validate Mixin source and `.accesswidener` files against a target Minecraft version
|
|
@@ -58,6 +58,7 @@ codex mcp list
|
|
|
58
58
|
The stdio transport auto-detects both newline-delimited and `Content-Length` framing, so Codex and newline-based MCP clients can use the same server command.
|
|
59
59
|
|
|
60
60
|
The server now lazily initializes heavyweight source/index services on first MCP request, reducing initial process startup latency for clients that only perform handshake/tool discovery.
|
|
61
|
+
To preserve handshake reliability across clients, startup does not eagerly pre-initialize `SourceService` before tool discovery.
|
|
61
62
|
|
|
62
63
|
#### Gemini CLI
|
|
63
64
|
|
|
@@ -178,11 +179,11 @@ Tools for browsing Minecraft versions, resolving source artifacts, and reading/s
|
|
|
178
179
|
| Tool | Purpose | Key Inputs | Key Outputs |
|
|
179
180
|
| --- | --- | --- | --- |
|
|
180
181
|
| `list-versions` | List available Minecraft versions from Mojang manifest + local cache | `includeSnapshots?`, `limit?` | `result.latest`, `result.releases[]`, `meta.warnings[]` |
|
|
181
|
-
| `resolve-artifact` | Resolve source artifact from `version` / `jar` / `coordinate` | `
|
|
182
|
+
| `resolve-artifact` | Resolve source artifact from `version` / `jar` / `coordinate` | `target`, `mapping?`, `sourcePriority?`, `allowDecompile?`, `projectPath?`, `scope?`, `preferProjectVersion?`, `strictVersion?` | `artifactId`, `origin`, `mappingApplied`, `qualityFlags[]`, `adjacentSourceCandidates?`, `sampleEntries?`, `warnings[]` |
|
|
182
183
|
| `find-class` | Resolve simple or fully-qualified class names inside an artifact | `className`, `artifactId`, `limit?` | `matches[]`, `total`, `warnings[]` |
|
|
183
|
-
| `get-class-source` | Get class source by
|
|
184
|
-
| `get-class-members` | Get class fields/methods/constructors from bytecode | `className`, `
|
|
185
|
-
| `search-class-source` | Search indexed class source for symbols/text/path | `artifactId`, `query`, `intent?`, `match?`, `packagePrefix?`, `fileGlob?`, `symbolKind?`, `
|
|
184
|
+
| `get-class-source` | Get class source by artifact target or resolve target on demand (`mode=metadata` by default) | `className`, `target`, `mode?`, `projectPath?`, `scope?`, `preferProjectVersion?`, `strictVersion?`, `startLine?`, `endLine?`, `maxLines?`, `maxChars?`, `outputFile?` | `mode`, `sourceText`, `returnedRange`, `truncated`, `charsTruncated?`, `outputFile?`, `artifactId`, mapping/provenance metadata |
|
|
185
|
+
| `get-class-members` | Get class fields/methods/constructors from bytecode | `className`, `target`, `mapping?`, `access?`, `includeInherited?`, `maxMembers?`, `strictVersion?` | `members.{constructors,fields,methods}`, `counts`, `truncated`, `context`, `warnings[]` |
|
|
186
|
+
| `search-class-source` | Search indexed class source for symbols/text/path | `artifactId`, `query`, `intent?`, `match?`, `packagePrefix?`, `fileGlob?`, `symbolKind?`, `queryMode?`, `limit?`, `cursor?` | `hits[]`, `nextCursor?`, `mappingApplied` |
|
|
186
187
|
| `get-artifact-file` | Read full source file with byte guard | `artifactId`, `filePath`, `maxBytes?` | `content`, `contentBytes`, `truncated`, `mappingApplied` |
|
|
187
188
|
| `list-artifact-files` | List indexed source file paths with cursor pagination | `artifactId`, `prefix?`, `limit?`, `cursor?` | `items[]`, `nextCursor?`, `mappingApplied` |
|
|
188
189
|
| `index-artifact` | Rebuild index metadata for an existing artifact | `artifactId`, `force?` | `reindexed`, `reason`, `counts`, `indexedAt`, `durationMs` |
|
|
@@ -204,8 +205,8 @@ Tools for converting symbol names between namespaces and checking symbol existen
|
|
|
204
205
|
| Tool | Purpose | Key Inputs | Key Outputs |
|
|
205
206
|
| --- | --- | --- | --- |
|
|
206
207
|
| `find-mapping` | Find mapping candidates for class/field/method symbols between namespaces | `version`, `kind`, `name`, `owner?`, `descriptor?`, `sourceMapping`, `targetMapping`, `sourcePriority?`, `disambiguation?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `ambiguityReasons?`, `provenance?`, `meta.warnings[]` |
|
|
207
|
-
| `resolve-method-mapping-exact` | Resolve one method mapping with strict owner+name+descriptor matching | `version`, `
|
|
208
|
-
| `get-class-api-matrix` | Show one class API as a mapping matrix (`
|
|
208
|
+
| `resolve-method-mapping-exact` | Resolve one method mapping with strict owner+name+descriptor matching | `version`, `name`, `owner`, `descriptor`, `sourceMapping`, `targetMapping`, `sourcePriority?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `provenance?`, `meta.warnings[]` |
|
|
209
|
+
| `get-class-api-matrix` | Show one class API as a mapping matrix (`obfuscated/mojang/intermediary/yarn`) | `version`, `className`, `classNameMapping`, `includeKinds?`, `sourcePriority?` | `classIdentity`, `rows[]`, `ambiguousRowCount?`, `meta.warnings[]` |
|
|
209
210
|
| `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[]` |
|
|
210
211
|
| `check-symbol-exists` | Strict symbol presence check for class/field/method | `version`, `kind`, `name`, `owner?`, `descriptor?`, `sourceMapping`, `sourcePriority?`, `nameMode?`, `signatureMode?` | `querySymbol`, `mappingContext`, `resolved`, `status`, `resolvedSymbol?`, `candidates[]`, `meta.warnings[]` |
|
|
211
212
|
|
|
@@ -237,7 +238,7 @@ Tools for validating Mixin source and Access Widener files against a target Mine
|
|
|
237
238
|
|
|
238
239
|
| Tool | Purpose | Key Inputs | Key Outputs |
|
|
239
240
|
| --- | --- | --- | --- |
|
|
240
|
-
| `validate-mixin` | Parse/validate Mixin source against target Minecraft version | `
|
|
241
|
+
| `validate-mixin` | Parse/validate Mixin source against target Minecraft version | `input`, `sourceRoots?`, `version`, `mapping?`, `sourcePriority?`, `projectPath?`, `scope?`, `preferProjectVersion?`, `minSeverity?`, `hideUncertain?`, `warningMode?`, `preferProjectMapping?`, `reportMode?`, `warningCategoryFilter?`, `treatInfoAsWarning?`, `explain?` | `mode`, `results[]`, `summary`, `issueSummary?`, `toolHealth?`, `confidenceScore?` |
|
|
241
242
|
| `validate-access-widener` | Parse/validate Access Widener content against target version | `content`, `version`, `mapping?`, `sourcePriority?` | `valid`, `issues[]`, `warnings[]`, `summary` |
|
|
242
243
|
|
|
243
244
|
### Registry & Diagnostics
|
|
@@ -251,33 +252,47 @@ Tools for querying generated registry data and inspecting server runtime state.
|
|
|
251
252
|
|
|
252
253
|
### Tool Constraints
|
|
253
254
|
|
|
254
|
-
`
|
|
255
|
-
`get-class-
|
|
256
|
-
`
|
|
257
|
-
|
|
255
|
+
`resolve-artifact` now takes `target: { kind, value }`.
|
|
256
|
+
`get-class-source` requires `target`, where `target.type="artifact"` selects a previously resolved `artifactId` and `target.type="resolve"` supplies `{ kind, value }` directly.
|
|
257
|
+
`get-class-members` requires the same `target` object shape and still needs a binary jar (`binaryJarPath`) to read `.class` entries.
|
|
258
|
+
Positive integer tool parameters accept numeric strings such as `"10"` in addition to JSON numbers.
|
|
259
|
+
This numeric-string coercion only applies to documented top-level tool arguments; nested `typedJson` payloads and JSON Patch `value` objects are preserved verbatim.
|
|
260
|
+
`validate-mixin` requires `input.mode` to be exactly one of `inline`, `path`, `paths`, or `config`. `input.path`/`input.paths[]` are normalized for host/WSL path formats before file reads. `input.configPaths[]` reads mixin config JSON files and auto-discovers source files for batch validation (`sourceRoots[]` override lookup roots; otherwise common roots like `src/main/java`, `src/client/java`, `common/src/{main,client}/java`, `fabric/src/{main,client}/java`, `neoforge/src/{main,client}/java`, `forge/src/{main,client}/java`, and `quilt/src/{main,client}/java` are auto-detected from configured mixin classes).
|
|
261
|
+
`validate-mixin` always returns `mode`, `results[]`, and `summary`; single-input modes still use a one-element `results[]` array.
|
|
262
|
+
`validate-mixin` per-result responses include `provenance.resolutionNotes?` when mapping fallback occurs.
|
|
258
263
|
`validate-mixin` validates `@Invoker` targets against methods only and `@Accessor` targets against fields only.
|
|
259
264
|
`validate-mixin` parser supports both `.class` literal targets and `targets = "..."` / `targets = {"a", "b"}` string forms.
|
|
260
265
|
`validate-mixin` parser handles multi-line annotations between `@Shadow`/`@Accessor` and declarations, and strips inline annotations from declaration lines.
|
|
261
266
|
`validate-mixin` distinguishes `target-mapping-failed` (warning, uncertain) from `target-not-found` (error) when class mapping fails.
|
|
262
267
|
`validate-mixin` issues and `structuredWarnings` include `category` (`mapping`, `configuration`, `validation`, `resolution`, or `parse`) to distinguish setup/tooling/parser limits from real validation errors.
|
|
263
268
|
`validate-mixin` supports post-filtering with `minSeverity`, `hideUncertain`, and `warningCategoryFilter`; `treatInfoAsWarning=false` suppresses info-level entries in `structuredWarnings`.
|
|
264
|
-
`validate-mixin`
|
|
269
|
+
`validate-mixin` per-result responses include `resolvedMembers?` tracking each member's resolution status (`resolved` or `not-found`).
|
|
265
270
|
`validate-mixin` with `explain=true` enriches each issue with `explanation` and `suggestedCall` (tool + params) for agent-driven recovery.
|
|
266
|
-
`validate-mixin`
|
|
267
|
-
`resolve-artifact` with `
|
|
268
|
-
`resolve-artifact` supports `scope` (`vanilla`/`merged`/`loader`) and optional `preferProjectVersion=true` to override `
|
|
271
|
+
`validate-mixin` summary uses `processingErrors`, `totalValidationErrors`, and `totalValidationWarnings`; the deprecated `summary.errors` field was removed.
|
|
272
|
+
`resolve-artifact` with `target.kind=version` uses Loom cache discovery from `projectPath` only when `mapping=mojang`; mapping failures include `searchedPaths`, `candidateArtifacts`, and `recommendedCommand` in error details.
|
|
273
|
+
`resolve-artifact` supports `scope` (`vanilla`/`merged`/`loader`) and optional `preferProjectVersion=true` to override `target.value` from `gradle.properties` (`minecraft_version`, `mc_version`, `minecraftVersion`) when `target.kind=version`.
|
|
274
|
+
`resolve-artifact` with `target.kind=coordinate` searches the local Maven repository, the local Gradle `modules-2` cache, and configured `MCP_SOURCE_REPOS` before reporting `ERR_SOURCE_NOT_FOUND`.
|
|
269
275
|
`resolve-artifact` includes `sampleEntries` only when a source JAR is resolved; decompile-only paths leave it unset.
|
|
276
|
+
`resolve-artifact` adds `qualityFlags=["partial-source-no-net-minecraft"]` and a warning when a merged Loom source candidate does not contain `net.minecraft` sources; `get-class-source` now bypasses that sibling `*-sources.jar` during binary fallback so the fallback can actually reach the binary artifact.
|
|
270
277
|
`find-class` returns type symbols (`class`/`interface`/`enum`/`record`) only; fully-qualified lookups are filtered by exact FQCN/file path to avoid false negatives when many classes share the same simple name.
|
|
271
|
-
`
|
|
278
|
+
`find-class` returns an explanatory warning when an `obfuscated` artifact is queried with names that look like deobfuscated Mojang classes.
|
|
279
|
+
`find-class` suppresses non-vanilla matches for vanilla-looking queries on artifacts flagged with `partial-source-no-net-minecraft`; in that situation it returns a warning instead of unrelated modded classes.
|
|
280
|
+
`search-class-source` uses `limit: 20` by default.
|
|
272
281
|
`search-class-source` `queryMode` controls text search strategy: `auto` (default) uses indexed token search with literal fallback for separator queries, `token` keeps indexed token behavior only, and `literal` uses substring scan only.
|
|
273
282
|
`search-class-source` with `match=regex` enforces `query.length <= 200` and a strict result cap of `100`.
|
|
283
|
+
`search-class-source` now returns compact file hits without snippets, line windows, relation expansion, or `totalApprox`.
|
|
284
|
+
Use `get-artifact-file` or `get-class-source` to inspect returned files after search.
|
|
285
|
+
`search-class-source` `symbolKind` is only supported when `intent=symbol`.
|
|
274
286
|
`get-artifact-file` byte truncation now preserves UTF-8 character boundaries, preventing replacement-character (`�`) corruption when `maxBytes` cuts through multibyte text.
|
|
275
287
|
`search-class-source` `fileGlob` supports `*`, `**`, and `?`; recursive patterns such as `net/minecraft/**/*.java` are supported.
|
|
276
288
|
`get-class-source` fallback matching enforces package compatibility and returns `ERR_CLASS_NOT_FOUND` when only name-colliding classes from other packages exist.
|
|
289
|
+
`get-class-source` now falls back to the sibling binary artifact when a source-backed artifact is only partial (for example, merged Loom sources without `net.minecraft` entries); if that fallback still cannot produce source, the error now carries the partial-source context and suggests `get-class-api-matrix` instead of `find-class`.
|
|
290
|
+
`get-class-source` warns when fallback source text is returned in a different namespace than the requested mapping; the source text itself is not remapped.
|
|
277
291
|
`get-class-source` mode defaults to `metadata` (symbol outline only); `mode=snippet` auto-sets `maxLines=200` when no line range/max is provided; `mode=full` returns the entire source. `outputFile` writes the selected text and returns the file path in `outputFile`.
|
|
278
292
|
Decompile fallback for `resolve-artifact`/`get-class-source` now invokes Vineflower with flags before positional `<input-jar> <output-dir>` arguments to avoid false `ERR_DECOMPILER_FAILED` outcomes on valid jars.
|
|
279
|
-
`resolve-artifact` with `
|
|
280
|
-
|
|
293
|
+
`resolve-artifact` with `target.kind=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.
|
|
294
|
+
When a resolved artifact comes from a `*-sources.jar`, `get-class-members` now keeps the sibling binary jar (for example `minecraft-merged-<version>.jar`) instead of treating the source jar as bytecode, and it now looks up the class in the resolved artifact namespace before remapping member names back to the requested mapping.
|
|
295
|
+
For `target.kind=coordinate` with a classifier (`group:artifact:version:classifier`), local Maven source lookup checks `<artifact>-<version>-<classifier>-sources.jar` first and then `<artifact>-<version>-sources.jar`.
|
|
281
296
|
Mod tool `jarPath` inputs are normalized to a canonical local `.jar` file path before existence checks, cache keying, and processing.
|
|
282
297
|
`search-mod-source` enforces `query.length <= 200` and `limit <= 200`.
|
|
283
298
|
`search-mod-source` detects source-only jars and searches `.java` entries directly without decompilation.
|
|
@@ -287,6 +302,12 @@ Mod tool `jarPath` inputs are normalized to a canonical local `.jar` file path b
|
|
|
287
302
|
`check-symbol-exists` defaults to strict FQCN class inputs; set `nameMode=auto` to allow short class names (ambiguous matches return `status=ambiguous`).
|
|
288
303
|
`check-symbol-exists` supports `signatureMode=name-only` to match methods by owner+name without requiring a descriptor. Single match returns `resolved`; multiple overloads return `ambiguous` with all candidates.
|
|
289
304
|
`check-symbol-exists` always validates input shape first and returns `ERR_INVALID_INPUT` for invalid symbol combinations, even when mapping data is unavailable.
|
|
305
|
+
Migration notes:
|
|
306
|
+
- Replace `resolve-artifact` `targetKind` + `targetValue` with `target: { kind, value }`.
|
|
307
|
+
- Replace `get-class-source` / `get-class-members` top-level `artifactId` / `targetKind` / `targetValue` with `target: { type: "artifact", artifactId }` or `target: { type: "resolve", kind, value }`.
|
|
308
|
+
- `resolve-method-mapping-exact` is method-only and no longer accepts `kind`.
|
|
309
|
+
- Replace `validate-mixin` `source` / `sourcePath` / `sourcePaths` / `mixinConfigPath` / `sourceRoot` with `input.mode` plus `input.source` / `input.path` / `input.paths[]` / `input.configPaths[]` and `sourceRoots[]`. Use `summary.processingErrors` instead of `summary.errors`.
|
|
310
|
+
- `search-class-source` removed `snippetLines`, `includeDefinition`, and `includeOneHop`; responses now contain compact `hits[]` plus `nextCursor?` only, and `symbolKind` may only be used with `intent=symbol`.
|
|
290
311
|
`remap-mod-jar` requires Java to be installed and only supports Fabric/Quilt mods.
|
|
291
312
|
|
|
292
313
|
## Resources
|
|
@@ -310,6 +331,9 @@ MCP resources provide URI-based access to Minecraft data, usable by any MCP clie
|
|
|
310
331
|
| `class-members` | `mc://artifact/{artifactId}/members/{className}` | List constructors, methods, and fields for a class |
|
|
311
332
|
| `artifact-metadata` | `mc://artifact/{artifactId}` | Metadata for a previously resolved artifact |
|
|
312
333
|
|
|
334
|
+
`versions-list`, `runtime-metrics`, `find-mapping`, `class-members`, and `artifact-metadata` return structured JSON envelopes on success (`{ result, meta }`) and failure (`{ error, meta }`).
|
|
335
|
+
`class-source` and `artifact-file` keep raw text responses on success, but still return structured JSON errors on failure.
|
|
336
|
+
|
|
313
337
|
## Response Envelope
|
|
314
338
|
|
|
315
339
|
All tools return exactly one of:
|
|
@@ -317,6 +341,9 @@ All tools return exactly one of:
|
|
|
317
341
|
- Success: `{ result: { ... }, meta: { requestId, tool, durationMs, warnings[] } }`
|
|
318
342
|
- Failure: `{ error: { type, title, detail, status, code, instance, fieldErrors?, hints? }, meta: { requestId, tool, durationMs, warnings[] } }`
|
|
319
343
|
|
|
344
|
+
JSON resources follow the same `result/error/meta` pattern. Text resources return plain text on success.
|
|
345
|
+
The same JSON envelope is mirrored in MCP `structuredContent` for SDK-aware clients, and failures also set `isError=true`.
|
|
346
|
+
|
|
320
347
|
## Examples
|
|
321
348
|
|
|
322
349
|
### Source Exploration
|
|
@@ -326,9 +353,11 @@ All tools return exactly one of:
|
|
|
326
353
|
{
|
|
327
354
|
"tool": "resolve-artifact",
|
|
328
355
|
"arguments": {
|
|
329
|
-
"
|
|
330
|
-
|
|
331
|
-
|
|
356
|
+
"target": {
|
|
357
|
+
"kind": "version",
|
|
358
|
+
"value": "1.21.10"
|
|
359
|
+
},
|
|
360
|
+
"mapping": "obfuscated",
|
|
332
361
|
"allowDecompile": true,
|
|
333
362
|
"projectPath": "/path/to/mod/workspace"
|
|
334
363
|
}
|
|
@@ -340,7 +369,10 @@ All tools return exactly one of:
|
|
|
340
369
|
{
|
|
341
370
|
"tool": "get-class-source",
|
|
342
371
|
"arguments": {
|
|
343
|
-
"
|
|
372
|
+
"target": {
|
|
373
|
+
"type": "artifact",
|
|
374
|
+
"artifactId": "<artifact-id>"
|
|
375
|
+
},
|
|
344
376
|
"className": "net.minecraft.server.Main",
|
|
345
377
|
"startLine": 50,
|
|
346
378
|
"endLine": 180,
|
|
@@ -357,8 +389,7 @@ All tools return exactly one of:
|
|
|
357
389
|
"artifactId": "<artifact-id>",
|
|
358
390
|
"query": "tickServer",
|
|
359
391
|
"intent": "symbol",
|
|
360
|
-
"match": "exact"
|
|
361
|
-
"includeOneHop": true
|
|
392
|
+
"match": "exact"
|
|
362
393
|
}
|
|
363
394
|
}
|
|
364
395
|
```
|
|
@@ -370,7 +401,7 @@ All tools return exactly one of:
|
|
|
370
401
|
"arguments": {
|
|
371
402
|
"artifactId": "<artifact-id>",
|
|
372
403
|
"className": "net.minecraft.server.Main",
|
|
373
|
-
"mapping": "
|
|
404
|
+
"mapping": "obfuscated",
|
|
374
405
|
"access": "all",
|
|
375
406
|
"includeInherited": true,
|
|
376
407
|
"maxMembers": 300
|
|
@@ -417,7 +448,7 @@ List source files under a specific package to understand project structure:
|
|
|
417
448
|
"className": "net.minecraft.server.Main",
|
|
418
449
|
"fromVersion": "1.20.1",
|
|
419
450
|
"toVersion": "1.21.10",
|
|
420
|
-
"mapping": "
|
|
451
|
+
"mapping": "obfuscated"
|
|
421
452
|
}
|
|
422
453
|
}
|
|
423
454
|
```
|
|
@@ -449,7 +480,7 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
449
480
|
"version": "1.21.10",
|
|
450
481
|
"kind": "class",
|
|
451
482
|
"name": "a.b.C",
|
|
452
|
-
"sourceMapping": "
|
|
483
|
+
"sourceMapping": "obfuscated",
|
|
453
484
|
"targetMapping": "mojang",
|
|
454
485
|
"sourcePriority": "loom-first",
|
|
455
486
|
"disambiguation": {
|
|
@@ -469,7 +500,7 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
469
500
|
"name": "tick",
|
|
470
501
|
"owner": "a.b.C",
|
|
471
502
|
"descriptor": "(I)V",
|
|
472
|
-
"sourceMapping": "
|
|
503
|
+
"sourceMapping": "obfuscated",
|
|
473
504
|
"targetMapping": "intermediary"
|
|
474
505
|
}
|
|
475
506
|
}
|
|
@@ -481,11 +512,10 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
481
512
|
"tool": "resolve-method-mapping-exact",
|
|
482
513
|
"arguments": {
|
|
483
514
|
"version": "1.21.10",
|
|
484
|
-
"kind": "method",
|
|
485
515
|
"name": "f",
|
|
486
516
|
"owner": "a.b.C",
|
|
487
517
|
"descriptor": "(Ljava/lang/String;)V",
|
|
488
|
-
"sourceMapping": "
|
|
518
|
+
"sourceMapping": "obfuscated",
|
|
489
519
|
"targetMapping": "mojang"
|
|
490
520
|
}
|
|
491
521
|
}
|
|
@@ -498,7 +528,7 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
498
528
|
"arguments": {
|
|
499
529
|
"version": "1.21.10",
|
|
500
530
|
"className": "a.b.C",
|
|
501
|
-
"classNameMapping": "
|
|
531
|
+
"classNameMapping": "obfuscated",
|
|
502
532
|
"includeKinds": "class,field,method"
|
|
503
533
|
}
|
|
504
534
|
}
|
|
@@ -515,7 +545,7 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
515
545
|
"name": "f",
|
|
516
546
|
"owner": "a.b.C",
|
|
517
547
|
"descriptor": "(Ljava/lang/String;)V",
|
|
518
|
-
"sourceMapping": "
|
|
548
|
+
"sourceMapping": "obfuscated"
|
|
519
549
|
}
|
|
520
550
|
}
|
|
521
551
|
```
|
|
@@ -530,7 +560,7 @@ Get a high-level summary of what changed between two releases, including class a
|
|
|
530
560
|
"name": "f",
|
|
531
561
|
"owner": "a.b.C",
|
|
532
562
|
"descriptor": "(I)V",
|
|
533
|
-
"sourceMapping": "
|
|
563
|
+
"sourceMapping": "obfuscated"
|
|
534
564
|
}
|
|
535
565
|
}
|
|
536
566
|
```
|
|
@@ -679,7 +709,10 @@ Check a Mixin class source for correctness against a target Minecraft version:
|
|
|
679
709
|
{
|
|
680
710
|
"tool": "validate-mixin",
|
|
681
711
|
"arguments": {
|
|
682
|
-
"
|
|
712
|
+
"input": {
|
|
713
|
+
"mode": "inline",
|
|
714
|
+
"source": "@Mixin(PlayerEntity.class)\npublic abstract class PlayerMixin {\n @Inject(method = \"tick\", at = @At(\"HEAD\"))\n private void onTick(CallbackInfo ci) {}\n}"
|
|
715
|
+
},
|
|
683
716
|
"version": "1.21.10",
|
|
684
717
|
"mapping": "yarn"
|
|
685
718
|
}
|
|
@@ -694,10 +727,13 @@ Run the same validation settings against multiple Mixin source files:
|
|
|
694
727
|
{
|
|
695
728
|
"tool": "validate-mixin",
|
|
696
729
|
"arguments": {
|
|
697
|
-
"
|
|
698
|
-
"
|
|
699
|
-
"
|
|
700
|
-
|
|
730
|
+
"input": {
|
|
731
|
+
"mode": "paths",
|
|
732
|
+
"paths": [
|
|
733
|
+
"/path/to/PlayerMixin.java",
|
|
734
|
+
"/path/to/WorldMixin.java"
|
|
735
|
+
]
|
|
736
|
+
},
|
|
701
737
|
"version": "1.21.10",
|
|
702
738
|
"mapping": "yarn"
|
|
703
739
|
}
|
|
@@ -779,14 +815,16 @@ Check server performance counters, cache sizes, and latency snapshots:
|
|
|
779
815
|
|
|
780
816
|
| Namespace | Description |
|
|
781
817
|
| --- | --- |
|
|
782
|
-
| `
|
|
818
|
+
| `obfuscated` | Mojang obfuscated names (e.g. `a`, `b`, `c`) |
|
|
783
819
|
| `mojang` | Mojang deobfuscated names from `client_mappings.txt` (e.g. `net.minecraft.server.Main`) |
|
|
784
820
|
| `intermediary` | Fabric stable intermediary names (e.g. `net.minecraft.class_1234`, `method_5678`) |
|
|
785
821
|
| `yarn` | Fabric community human-readable names (e.g. `net.minecraft.server.MinecraftServer`, `tick`) |
|
|
786
822
|
|
|
823
|
+
The legacy public namespace name `official` was removed. Requests that still send `official` now fail validation and should be updated to `obfuscated`.
|
|
824
|
+
|
|
787
825
|
### Lookup Rules
|
|
788
826
|
|
|
789
|
-
`find-mapping` supports lookup across `
|
|
827
|
+
`find-mapping` supports lookup across `obfuscated`, `mojang`, `intermediary`, and `yarn`.
|
|
790
828
|
|
|
791
829
|
Symbol query inputs use `kind` + `name` + optional `owner`/`descriptor`:
|
|
792
830
|
- class: `kind=class`, `name=a.b.C` (default FQCN). For existence checks only, `nameMode=auto` allows short names like `C`.
|
|
@@ -795,12 +833,14 @@ Symbol query inputs use `kind` + `name` + optional `owner`/`descriptor`:
|
|
|
795
833
|
|
|
796
834
|
`mapping: "mojang"` requires a source-backed artifact. If only decompile path is available, the server returns `ERR_MAPPING_NOT_APPLIED`.
|
|
797
835
|
|
|
798
|
-
`resolve-artifact`, `get-class-members`, `trace-symbol-lifecycle`, and `diff-class-signatures` accept `
|
|
799
|
-
- `intermediary` / `yarn` require a resolvable Minecraft version context (for example `
|
|
800
|
-
- for unobfuscated versions (for example 26.1+), requesting `intermediary` / `yarn` falls back to `
|
|
836
|
+
`resolve-artifact`, `get-class-members`, `trace-symbol-lifecycle`, and `diff-class-signatures` accept `obfuscated | mojang | intermediary | yarn` with constraints:
|
|
837
|
+
- `intermediary` / `yarn` require a resolvable Minecraft version context (for example `target.kind=version` or a versioned coordinate).
|
|
838
|
+
- for unobfuscated versions (for example 26.1+), requesting `intermediary` / `yarn` falls back to `obfuscated` with a warning.
|
|
801
839
|
- `mojang` requires source-backed artifacts; decompile-only paths are rejected with `ERR_MAPPING_NOT_APPLIED`.
|
|
802
840
|
|
|
803
|
-
|
|
841
|
+
If `find-class` or `get-class-source` returns no hit on an `obfuscated` artifact for names like `net.minecraft.world.item.Item`, the tool now warns that `obfuscated` means Mojang's obfuscated runtime names and recommends retrying with `mapping="mojang"` or translating via `find-mapping`.
|
|
842
|
+
|
|
843
|
+
Method descriptor precision is best on Tiny-backed paths (`intermediary`/`yarn`). For `obfuscated <-> mojang`, Mojang `client_mappings` do not carry JVM descriptors, so descriptor queries may fallback to name matching and emit a warning.
|
|
804
844
|
|
|
805
845
|
Use `resolve-method-mapping-exact` when candidate ranking is not enough and the workflow needs strict `owner+name+descriptor` certainty.
|
|
806
846
|
Use `find-mapping` `disambiguation.ownerHint` / `disambiguation.descriptorHint` to narrow ambiguous candidate sets.
|
|
@@ -866,6 +906,7 @@ The server runs as a single long-lived process communicating over stdio. Artifac
|
|
|
866
906
|
- `SourceService` is the canonical implementation for artifact resolution, ingestion, and source querying.
|
|
867
907
|
- `version` resolution downloads Mojang client JARs into cache and routes them through the same ingestion flow as `jar` and `coordinate` targets.
|
|
868
908
|
- Tool responses are always wrapped as `{ result?, error?, meta }`.
|
|
909
|
+
- Tool responses also mirror that envelope into MCP `structuredContent`, and failures set `isError=true`.
|
|
869
910
|
- `meta` includes `requestId`, `tool`, `durationMs`, and `warnings[]`.
|
|
870
911
|
|
|
871
912
|
## License
|
|
@@ -131,8 +131,6 @@ export async function decompileBinaryJar(binaryJarPath, cacheDir, options) {
|
|
|
131
131
|
const outputDir = decompileOutputDir(cacheDir, normalizedBinaryJarPath, signature).replace(/[/\\]$/, "");
|
|
132
132
|
try {
|
|
133
133
|
mkdirSync(outputDir, { recursive: true });
|
|
134
|
-
await assertVineflowerAvailable(options.vineflowerJarPath);
|
|
135
|
-
await assertJavaAvailable();
|
|
136
134
|
if (statSync(outputDir, { throwIfNoEntry: false })) {
|
|
137
135
|
const existingJavaFiles = await collectJavaFiles(outputDir);
|
|
138
136
|
if (existingJavaFiles.length > 0) {
|
|
@@ -154,6 +152,8 @@ export async function decompileBinaryJar(binaryJarPath, cacheDir, options) {
|
|
|
154
152
|
};
|
|
155
153
|
}
|
|
156
154
|
}
|
|
155
|
+
await assertVineflowerAvailable(options.vineflowerJarPath);
|
|
156
|
+
await assertJavaAvailable();
|
|
157
157
|
const profilesAttempted = [];
|
|
158
158
|
let lastDecompileError;
|
|
159
159
|
for (const profile of VINEFLOWER_FLAG_PROFILES) {
|