@adhisang/minecraft-modding-mcp 4.0.0 → 4.1.1
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 +61 -0
- package/README.md +40 -23
- package/dist/build-suggested-call.d.ts +29 -0
- package/dist/build-suggested-call.js +58 -0
- package/dist/cache-registry.d.ts +3 -1
- package/dist/cache-registry.js +50 -6
- package/dist/entry-tools/analyze-symbol-service.d.ts +16 -16
- package/dist/entry-tools/batch-class-members-service.d.ts +34 -0
- package/dist/entry-tools/batch-class-members-service.js +97 -0
- package/dist/entry-tools/batch-class-source-service.d.ts +37 -0
- package/dist/entry-tools/batch-class-source-service.js +100 -0
- package/dist/entry-tools/batch-mappings-service.d.ts +36 -0
- package/dist/entry-tools/batch-mappings-service.js +66 -0
- package/dist/entry-tools/batch-runner.d.ts +72 -0
- package/dist/entry-tools/batch-runner.js +90 -0
- package/dist/entry-tools/batch-symbol-exists-service.d.ts +46 -0
- package/dist/entry-tools/batch-symbol-exists-service.js +113 -0
- package/dist/entry-tools/compare-minecraft-service.d.ts +6 -6
- package/dist/entry-tools/inspect-minecraft/handlers/artifact.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/artifact.js +83 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.d.ts +6 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +80 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-overview.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +248 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-source.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +60 -0
- package/dist/entry-tools/inspect-minecraft/handlers/file.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/file.js +54 -0
- package/dist/entry-tools/inspect-minecraft/handlers/list-files.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +100 -0
- package/dist/entry-tools/inspect-minecraft/handlers/search.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/search.js +155 -0
- package/dist/entry-tools/inspect-minecraft/handlers/versions.d.ts +6 -0
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +49 -0
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +1042 -0
- package/dist/entry-tools/inspect-minecraft/internal.js +448 -0
- package/dist/entry-tools/inspect-minecraft-service.d.ts +193 -308
- package/dist/entry-tools/inspect-minecraft-service.js +20 -1244
- package/dist/entry-tools/manage-cache-service.d.ts +16 -16
- package/dist/entry-tools/validate-project/cases/access-transformer.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/access-transformer.js +106 -0
- package/dist/entry-tools/validate-project/cases/access-widener.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/access-widener.js +86 -0
- package/dist/entry-tools/validate-project/cases/mixin.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/mixin.js +90 -0
- package/dist/entry-tools/validate-project/cases/project-summary.d.ts +102 -0
- package/dist/entry-tools/validate-project/cases/project-summary.js +415 -0
- package/dist/entry-tools/validate-project/internal.d.ts +142 -0
- package/dist/entry-tools/validate-project/internal.js +303 -0
- package/dist/entry-tools/validate-project-service.d.ts +67 -47
- package/dist/entry-tools/validate-project-service.js +13 -563
- package/dist/entry-tools/verify-mixin-target-service.d.ts +133 -0
- package/dist/entry-tools/verify-mixin-target-service.js +323 -0
- package/dist/error-mapping.d.ts +40 -0
- package/dist/error-mapping.js +139 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +147 -1354
- package/dist/mapping/internal-types.d.ts +54 -0
- package/dist/mapping/internal-types.js +14 -0
- package/dist/mapping/loaders/mojang.d.ts +2 -0
- package/dist/mapping/loaders/mojang.js +64 -0
- package/dist/mapping/loaders/tiny-loom.d.ts +2 -0
- package/dist/mapping/loaders/tiny-loom.js +73 -0
- package/dist/mapping/loaders/tiny-maven.d.ts +2 -0
- package/dist/mapping/loaders/tiny-maven.js +104 -0
- package/dist/mapping/loaders/types.d.ts +14 -0
- package/dist/mapping/loaders/types.js +2 -0
- package/dist/mapping/lookup.d.ts +52 -0
- package/dist/mapping/lookup.js +496 -0
- package/dist/mapping/parsers/normalize.d.ts +10 -0
- package/dist/mapping/parsers/normalize.js +52 -0
- package/dist/mapping/parsers/proguard.d.ts +20 -0
- package/dist/mapping/parsers/proguard.js +138 -0
- package/dist/mapping/parsers/symbol-records.d.ts +27 -0
- package/dist/mapping/parsers/symbol-records.js +216 -0
- package/dist/mapping/parsers/tiny.d.ts +9 -0
- package/dist/mapping/parsers/tiny.js +96 -0
- package/dist/mapping/types.d.ts +147 -0
- package/dist/mapping/types.js +2 -0
- package/dist/mapping-pipeline-service.js +3 -2
- package/dist/mapping-service.d.ts +8 -145
- package/dist/mapping-service.js +30 -1207
- package/dist/mixin/access-validators.d.ts +9 -0
- package/dist/mixin/access-validators.js +257 -0
- package/dist/mixin/annotation-validators.d.ts +5 -0
- package/dist/mixin/annotation-validators.js +162 -0
- package/dist/mixin/helpers.d.ts +28 -0
- package/dist/mixin/helpers.js +315 -0
- package/dist/mixin/parsed-validator.d.ts +8 -0
- package/dist/mixin/parsed-validator.js +337 -0
- package/dist/mixin/types.d.ts +208 -0
- package/dist/mixin/types.js +28 -0
- package/dist/mixin-validator.d.ts +9 -201
- package/dist/mixin-validator.js +8 -1020
- package/dist/source/access-validate.d.ts +4 -0
- package/dist/source/access-validate.js +254 -0
- package/dist/source/artifact-resolver.d.ts +111 -0
- package/dist/source/artifact-resolver.js +1271 -0
- package/dist/source/cache-metrics.d.ts +26 -0
- package/dist/source/cache-metrics.js +172 -0
- package/dist/source/class-source/members-builder.d.ts +34 -0
- package/dist/source/class-source/members-builder.js +46 -0
- package/dist/source/class-source/snippet-builder.d.ts +19 -0
- package/dist/source/class-source/snippet-builder.js +46 -0
- package/dist/source/class-source-helpers.d.ts +34 -0
- package/dist/source/class-source-helpers.js +140 -0
- package/dist/source/class-source.d.ts +42 -0
- package/dist/source/class-source.js +883 -0
- package/dist/source/descriptor-utils.d.ts +6 -0
- package/dist/source/descriptor-utils.js +37 -0
- package/dist/source/file-access.d.ts +4 -0
- package/dist/source/file-access.js +102 -0
- package/dist/source/indexer.d.ts +82 -0
- package/dist/source/indexer.js +522 -0
- package/dist/source/lifecycle/diff-utils.d.ts +9 -0
- package/dist/source/lifecycle/diff-utils.js +107 -0
- package/dist/source/lifecycle/diff.d.ts +2 -0
- package/dist/source/lifecycle/diff.js +265 -0
- package/dist/source/lifecycle/mapping-helpers.d.ts +22 -0
- package/dist/source/lifecycle/mapping-helpers.js +327 -0
- package/dist/source/lifecycle/runtime-check.d.ts +2 -0
- package/dist/source/lifecycle/runtime-check.js +142 -0
- package/dist/source/lifecycle/trace.d.ts +2 -0
- package/dist/source/lifecycle/trace.js +231 -0
- package/dist/source/lifecycle.d.ts +4 -0
- package/dist/source/lifecycle.js +5 -0
- package/dist/source/search.d.ts +51 -0
- package/dist/source/search.js +676 -0
- package/dist/source/shared-utils.d.ts +6 -0
- package/dist/source/shared-utils.js +55 -0
- package/dist/source/state.d.ts +26 -0
- package/dist/source/state.js +24 -0
- package/dist/source/symbol-resolver.d.ts +3 -0
- package/dist/source/symbol-resolver.js +212 -0
- package/dist/source/validate-mixin/pipeline/mapping-health.d.ts +3 -0
- package/dist/source/validate-mixin/pipeline/mapping-health.js +41 -0
- package/dist/source/validate-mixin/pipeline/parse.d.ts +2 -0
- package/dist/source/validate-mixin/pipeline/parse.js +10 -0
- package/dist/source/validate-mixin/pipeline/resolve.d.ts +3 -0
- package/dist/source/validate-mixin/pipeline/resolve.js +78 -0
- package/dist/source/validate-mixin/pipeline/target-lookup.d.ts +6 -0
- package/dist/source/validate-mixin/pipeline/target-lookup.js +260 -0
- package/dist/source/validate-mixin/pipeline-context.d.ts +72 -0
- package/dist/source/validate-mixin/pipeline-context.js +93 -0
- package/dist/source/validate-mixin.d.ts +22 -0
- package/dist/source/validate-mixin.js +799 -0
- package/dist/source/workspace-target.d.ts +18 -0
- package/dist/source/workspace-target.js +305 -0
- package/dist/source-resolver.d.ts +1 -0
- package/dist/source-resolver.js +1 -1
- package/dist/source-service.d.ts +164 -170
- package/dist/source-service.js +70 -6116
- package/dist/stage-emitter.d.ts +13 -0
- package/dist/stage-emitter.js +30 -0
- package/dist/stdio-supervisor.d.ts +61 -0
- package/dist/stdio-supervisor.js +326 -9
- package/dist/tool-contract-manifest.d.ts +1 -1
- package/dist/tool-contract-manifest.js +23 -6
- package/dist/tool-guidance.d.ts +82 -0
- package/dist/tool-guidance.js +734 -0
- package/dist/tool-schema-registry.d.ts +16 -0
- package/dist/tool-schema-registry.js +37 -0
- package/dist/tool-schemas.d.ts +3518 -0
- package/dist/tool-schemas.js +813 -0
- package/dist/types.d.ts +36 -0
- package/dist/version-service.js +7 -6
- package/dist/workspace-context-cache.d.ts +32 -0
- package/dist/workspace-context-cache.js +66 -0
- package/dist/workspace-mapping-service.d.ts +16 -0
- package/dist/workspace-mapping-service.js +173 -1
- package/docs/README-ja.md +416 -0
- package/docs/examples.md +483 -0
- package/docs/tool-reference.md +462 -0
- package/package.json +17 -4
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
# Tool and Configuration Reference
|
|
2
|
+
|
|
3
|
+
Use [README.md](../README.md) for quick start and client setup. Use [docs/examples.md](examples.md) for concrete request payloads.
|
|
4
|
+
|
|
5
|
+
Use this document when you need the exact input conventions, outputs, resource URIs, mapping rules, migration notes, operational pitfalls, or the full environment-variable matrix.
|
|
6
|
+
|
|
7
|
+
## Which Tool for Which Question
|
|
8
|
+
|
|
9
|
+
Start here when you are not sure which tool to reach for. In every row, the left column is the question as a user would phrase it; the right column is the tool that answers it most directly. Class lookups always take a fully-qualified class name as `name`; field and method lookups split the class into `owner` and the simple member into `name`.
|
|
10
|
+
|
|
11
|
+
| Question | Tool |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| "Does class `X` exist on MC `1.21.10`?" | `check-symbol-exists` (`kind="class"`, `nameMode="auto"` if you only have a short name). |
|
|
14
|
+
| "What is the obfuscated name of `net.minecraft.world.entity.player.Player` in MC `1.21.10`?" | `find-mapping` (`kind="class"`, `name="net.minecraft.world.entity.player.Player"`, `sourceMapping="mojang"`, `targetMapping="obfuscated"`). |
|
|
15
|
+
| "What is the descriptor of `Player.addAdditionalSaveData`?" | `check-symbol-exists` (`kind="method"`, `owner="net.minecraft.world.entity.player.Player"`, `name="addAdditionalSaveData"`, `sourceMapping="mojang"`, `signatureMode="name-only"`). `find-mapping` with `signatureMode="name-only"` also works when you additionally want the target-namespace name. |
|
|
16
|
+
| "Does this exact obf `owner + name + descriptor` triple resolve to one mapping?" | `resolve-method-mapping-exact` (always requires the full triple). |
|
|
17
|
+
| "I know a Mojang method like `ItemStack.copy` — which workspace mapping does it use?" | Discover the descriptor first with `check-symbol-exists` (`signatureMode="name-only"`), then call `resolve-workspace-symbol` (`kind="method"`, `owner="net.minecraft.world.item.ItemStack"`, `name="copy"`, `descriptor="()Lnet/minecraft/world/item/ItemStack;"`, `projectPath`). |
|
|
18
|
+
| "Summarize a symbol across mapping/existence/lifecycle in one call." | `analyze-symbol` (higher-level wrapper around `find-mapping` / `check-symbol-exists` / `trace-symbol-lifecycle`). |
|
|
19
|
+
| "Give me the source of one class I already know the FQCN of." | `get-class-source` (`mode="metadata"` to skim, `mode="snippet"` for line ranges, `mode="full"` for the whole file). |
|
|
20
|
+
| "Give me the fields/methods/constructors of one class without reading the source." | `get-class-members`. |
|
|
21
|
+
| "Find every class or member that matches `save` in one artifact." | `search-class-source`. |
|
|
22
|
+
| "I only know the simple class name `PlayerList` and want the FQCN." | `find-class`. |
|
|
23
|
+
| "Does this Mixin target the right class and descriptor?" | `validate-mixin` (works standalone with `version=1.21.10`; provide inline source, a path, or a mixin config). |
|
|
24
|
+
| "Validate every Mixin / Access Widener / Access Transformer in a workspace." | `validate-project` (`task="project-summary"` discovers everything; `task="mixin"|"access-widener"|"access-transformer"` validates a single subject). |
|
|
25
|
+
| "Inspect the Minecraft workspace or an artifact without picking a lower-level tool." | `inspect-minecraft` — use this when you want the server to resolve the artifact and pick the right sub-tool. |
|
|
26
|
+
| "Trace when a symbol was added, renamed, or removed across versions." | `trace-symbol-lifecycle` (or `analyze-symbol task="lifecycle"` for the summarized 5-version window). |
|
|
27
|
+
| "Compare two MC versions or two class versions." | `compare-minecraft` (`task="class"` for a single class diff; `task="versions"` for a full summary). |
|
|
28
|
+
| "Inspect or remap an existing `.jar` file." | `analyze-mod` / `analyze-mod-jar` / `remap-mod-jar`. |
|
|
29
|
+
|
|
30
|
+
## Essential Conventions
|
|
31
|
+
|
|
32
|
+
- Start with the top-level workflow tools when possible. `inspect-minecraft`, `analyze-symbol`, `compare-minecraft`, `analyze-mod`, `validate-project`, and `manage-cache` cover the common workflows and return summary-first results with follow-up hints.
|
|
33
|
+
- `resolve-artifact` uses `target: { kind, value }`. `kind` is one of `"version"`, `"jar"`, `"coordinate"`, `"workspace"`, or `"dependency"` (see "Workspace and dependency target shapes" below).
|
|
34
|
+
- `get-class-source` and `get-class-members` use `target: { type: "artifact", artifactId }` or `target: { type: "resolve", kind, value }` (the same `kind` set as `resolve-artifact`).
|
|
35
|
+
- `find-class`, `search-class-source`, `list-artifact-files`, and `find-mapping` keep their existing input shapes (an `artifactId` or a `version`); they do not currently accept `target.kind="workspace"` or `target.kind="dependency"`.
|
|
36
|
+
- `validate-mixin` and `validate-project task="mixin"` use `input.mode="inline" | "path" | "paths" | "config" | "project"`.
|
|
37
|
+
- Positive integer tool arguments accept numeric strings such as `"10"` for documented top-level parameters.
|
|
38
|
+
- When a parameter has a fixed safe default, `tools/list` exposes it through the JSON Schema `default` field so clients can rely on schema metadata instead of prose notes.
|
|
39
|
+
- Retryable `suggestedCall` payloads omit parameters when the supplied value already matches the tool default, keeping recovery calls smaller without changing behavior.
|
|
40
|
+
- Source-oriented tools expose `artifactContents` so callers can tell whether the backing artifact is a `source-jar` or a `decompiled-binary`. `get-class-source`, `get-class-members`, `search-class-source`, and `get-artifact-file` also expose `returnedNamespace`.
|
|
41
|
+
- `get-class-members` returns `decompiledFallback` (with `constructors`, `fields`, `methods`, each entry is `{ name, line, kind }`) and `decompiledMemberCounts` whenever bytecode enumeration yields zero but the decompiled source for the class is already indexed. The bytecode-derived `members` / `counts` are preserved as-is; the fallback is additive and carries no descriptor or access modifier. `qualityFlags` gains `"members-from-decompiled-source"` in that case. Use `get-class-source` for descriptors and full context.
|
|
42
|
+
- `get-class-members` also returns an additive `status: "ok" | "members_unavailable" | "partial"` field so callers can distinguish "really 0 members" from "extraction unavailable":
|
|
43
|
+
|
|
44
|
+
| `status` | When | Extra fields |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `"ok"` | `counts.total > 0`, OR `counts.total === 0` AND binary extraction succeeded AND `decompiledFallback` did not fire (genuinely empty class). | none |
|
|
47
|
+
| `"partial"` | `decompiledFallback` is populated (bytecode returned zero but the indexed decompiled source supplied member names; `qualityFlags` includes `"members-from-decompiled-source"`). | `decompiledFallback`, `decompiledMemberCounts` |
|
|
48
|
+
| `"members_unavailable"` | Binary signature extraction threw a non-`ERR_CLASS_NOT_FOUND` error AND no decompiled fallback was available. | `unavailableReason: string`, `suggestedCall: { tool: "get-class-source", params: { target: { type: "artifact", artifactId }, className, mode: "snippet", mapping } }` (the params validate against `get-class-source`'s input schema). |
|
|
49
|
+
|
|
50
|
+
The shape is purely additive: `members` / `counts` / `decompiledFallback` / `decompiledMemberCounts` / `qualityFlags` are unchanged for callers that ignore `status`. `ERR_CLASS_NOT_FOUND` still propagates as a thrown error rather than as `members_unavailable`. Set `MEMBERS_STATUS_LEGACY=1` at process start to omit `status` / `unavailableReason` / `suggestedCall` entirely (legacy shape).
|
|
51
|
+
- `search-class-source` accepts `queryNamespace`. When set and the artifact's `mappingApplied` differs, `intent="symbol"` queries for fully-qualified class names are translated through `find-mapping` (source=`queryNamespace`, target=artifact namespace) before the indexed search runs; the response carries a `translatedQuery` block describing the rewrite. `intent="text"` / `intent="path"` do not translate — text search is a literal match against the artifact namespace; the response surfaces a `warnings` array instead. `sourcePriority` is only consulted during translation.
|
|
52
|
+
- `resolve-artifact`, `find-mapping`, `resolve-method-mapping-exact`, `resolve-workspace-symbol`, and `check-symbol-exists` default `compact` to `true`. Pass `compact: false` for the full diagnostic shape. When enabled, compact mode strips empty arrays, null values, and empty objects from the response. For `resolve-artifact`, compact mode also omits `provenance`, `artifactContents`, `sampleEntries`, `adjacentSourceCandidates`, `binaryJarPath`, `coordinate`, `repoUrl`, and `resolvedSourceJarPath`. For mapping tools, compact mode has two projections: (1) the redundant `candidates` array is omitted entirely when the result is a single full-confidence exact-match resolution; (2) when the result is unresolved with more than three candidates, the top three keep full metadata while the tail is slimmed to `{kind, symbol, owner, name, descriptor, confidence, matchKind}` and the response surfaces `candidateDetailsTruncated: true`. `candidatesTruncated` retains its pre-compact meaning ("more candidates exist upstream than this response returned") and is set independently by the service when `maxCandidates` clipped the list — the two signals can both appear.
|
|
53
|
+
- `get-class-source`, `get-class-members`, `search-class-source`, and `list-artifact-files` accept `compact: true` (opt-in, default `false`) to strip debug/diagnostic metadata and empty fields. `get-class-source` omits `provenance`, `artifactContents`, and `qualityFlags`. `get-class-members` omits `provenance`, `artifactContents`, `qualityFlags`, and `context`; `decompiledFallback` and `decompiledMemberCounts` are preserved. `search-class-source` and `list-artifact-files` omit `artifactContents` only — the primary `hits` / `items` payload is always preserved.
|
|
54
|
+
- Windows and WSL path forms are normalized for `jarPath`, `projectPath`, and environment-variable path overrides.
|
|
55
|
+
- Heavy analysis tools are serialized in-process to protect stdio stability. Queue overflow returns `ERR_LIMIT_EXCEEDED`.
|
|
56
|
+
- All tools and JSON resources use the standard `{ result?, error?, meta }` envelope. `class-source` and `artifact-file` resources return raw text on success and structured JSON on failure.
|
|
57
|
+
|
|
58
|
+
## Workspace and dependency target shapes
|
|
59
|
+
|
|
60
|
+
`resolve-artifact`, `get-class-source`, and `get-class-members` accept two synthesizing `target.kind` values in addition to the canonical `"version"` / `"jar"` / `"coordinate"` shapes. The synthesizer rewrites the call into one of those canonical shapes before downstream resolution, so behaviour from the resolver onward is unchanged.
|
|
61
|
+
|
|
62
|
+
| target shape | When to use | Required input | Result |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| `{ kind: "workspace", scope?, strict? }` | When the caller already passes a `projectPath` and wants the tool to detect Minecraft version, compile mapping, and loader from `gradle.properties` and `build.gradle(.kts)`. | `projectPath` | Synthesised to `{ kind: "version", value: <detected> }`. Scope precedence is `target.scope` → top-level `scope` → loader-derived default (`"merged"` when a loader is detected, `"vanilla"` otherwise). When the version is not detected, raises `ERR_WORKSPACE_VERSION_UNRESOLVED` regardless of `strict`. Detected facts surface on `provenance.workspaceResolution`. |
|
|
65
|
+
| `{ kind: "dependency", group, name, version?, versionFromProject? }` | When the caller wants to resolve a Maven-coordinate dependency (e.g. `dev.architectury:architectury`) without computing the exact version themselves. | `projectPath` (unless `version` is given) | Synthesised to `{ kind: "coordinate", value: "<group>:<name>:<version>" }`. The dependency JAR is treated as non-vanilla: binary remap is suppressed. When the caller asks for a non-obfuscated mapping the resolver returns the JAR with `mappingApplied: "obfuscated"` and `qualityFlags: ["dependency-mapping-unverified"]`, plus a warning that the caller must validate symbol availability. Resolution metadata appears on `provenance.dependencyResolution`. |
|
|
66
|
+
|
|
67
|
+
Workspace detection is memoised in a process-resident `WorkspaceContextCache` (16-entry LRU, 5-minute TTL). The cache is observable through `manage-cache` with `cacheKinds: ["workspace"]`, and individual entries can be invalidated via `selector.projectPath`.
|
|
68
|
+
|
|
69
|
+
`target.kind="dependency"` resolution probes four de-duplicated `gradle.properties` keys in order — `name_version`, `camelCaseVersion`, `lastSegment(group)_name_version`, and `camelCase(lastSegment(group)_name)Version` — before falling back to the modules-2 cache layout `~/.gradle/caches/modules-2/files-2.1/<group>/<name>/`. Version tokens that contain path separators, `..`, NUL, control characters, or any character outside `[A-Za-z0-9._+-]` are rejected; in `gradle.properties` the rejection is recorded under `attempts[]` as `gradle.properties:<key>:rejected-unsafe-version` and the next key is tried. Snapshot and dev directories are excluded by default. The modules-2 fallback only resolves when exactly one valid entry remains; multiple entries raise `ERR_DEPENDENCY_VERSION_UNRESOLVED` so a global cache cannot supply a version the workspace did not declare.
|
|
70
|
+
|
|
71
|
+
## Common Pitfalls
|
|
72
|
+
|
|
73
|
+
- `mapping="mojang"` requires source-backed artifacts on legacy obfuscated versions. For unobfuscated releases such as `26.1+`, the runtime/decompile path is accepted directly for version and versioned-coordinate targets. When source jars are not available but the version's Mojang tiny mappings, the tiny-remapper jar, and `MappingService.checkMappingHealth` are all healthy, `resolve-artifact` with `target.kind="version"` will transparently tiny-remap the binary jar (`obfuscated -> mojang`) and decompile the result, and the response carries `qualityFlags` `"binary-remapped"` and `"decompiled"` plus `provenance.transformChain` `"binary-remap:obf->mojang"` and `"decompile:vineflower"`. Coordinate and jar targets are not eligible for this fallback and still surface `ERR_MAPPING_NOT_APPLIED`. Source-backed and obfuscated artifacts keep their existing `artifactId` hashes — only the new mojang-remapped variant lives in a separate cache slot.
|
|
74
|
+
- `list-artifact-files` indexes Java source paths only. Probing `assets/` or `data/` prefixes will not return non-Java resources.
|
|
75
|
+
- `search-class-source` defaults to `queryMode="auto"`. Use `queryMode="literal"` for explicit substring scans. `match="regex"` enforces `query.length <= 200` and caps results at `100`.
|
|
76
|
+
- `search-class-source` returns compact hits only. Use `get-artifact-file` or `get-class-source` to inspect returned files.
|
|
77
|
+
- `find-class` and `get-class-source` on `mapping="obfuscated"` expect Mojang obfuscated names. Deobfuscated queries warn and usually need `mapping="mojang"` or a `find-mapping` step first.
|
|
78
|
+
- `check-symbol-exists` defaults to strict FQCN class lookup. Use `nameMode="auto"` for short class names.
|
|
79
|
+
- `check-symbol-exists` can use `signatureMode="name-only"` for overload discovery, but exact `descriptor` matching is still the most reliable path.
|
|
80
|
+
- `analyze-symbol task="api-overview"` inherits `sourceMapping` as the default `classNameMapping`; it falls back to `obfuscated` only when neither value is provided.
|
|
81
|
+
- `find-mapping` accepts short class ids such as `dhl` only when `sourceMapping="obfuscated"`. Other class lookup paths still validate class names as fully-qualified.
|
|
82
|
+
- `find-mapping` still rejects the public namespace name `official`, but upstream Tiny files that use `official` internally are now bridged to the supported `obfuscated` graph automatically.
|
|
83
|
+
- `get-class-api-matrix` now uses the explicit `classNameMapping` as its base namespace even when an obfuscated identity is also available.
|
|
84
|
+
- `inspect-minecraft task="class-overview" | "search" | "class-source" | "class-members"` needs artifact context for plain `subject.kind="search" | "class" | "file"` inputs. Use `subject.kind="workspace"` when you want the tool to resolve the artifact for you. Invalid combinations return `ERR_INVALID_INPUT` with a retryable `suggestedCall`; when artifact context is the only missing piece, the suggested retry preserves the requested task.
|
|
85
|
+
- Workspace `inspect-minecraft` flows now treat `partial-source-no-net-minecraft` as a recoverable condition: `task="class-overview"` and class-like workspace `task="search"` can confirm vanilla classes through binary-backed symbol lookup, while workspace `task="list-files"` marks the response as partial and includes follow-up guidance.
|
|
86
|
+
- `analyze-mod` and `validate-project` keep their structured `subject` contracts; stale string-subject or domain-include payloads now fail with `ERR_INVALID_INPUT` plus a retryable `suggestedCall` instead of a dead-end schema error.
|
|
87
|
+
- `scope="loader"` now means runtime artifact discovery. Fabric/Quilt flows may still fall back to merged Loom artifacts, while Forge/NeoForge validation can resolve transformed loader runtime jars.
|
|
88
|
+
- `remap-mod-jar` requires Java and supports Fabric/Quilt inputs. Mojang-mapped inputs can only be copied through `targetMapping="mojang"`.
|
|
89
|
+
- `search-mod-source` enforces `query.length <= 200` and `limit <= 200`.
|
|
90
|
+
- `get-registry-data` can return names and counts only with `includeData=false`, or clip detailed payloads with `maxEntriesPerRegistry`.
|
|
91
|
+
- `validate-mixin` summary-first workflows should combine `includeIssues=false`, `reportMode="compact"`, and `warningMode="aggregated"`.
|
|
92
|
+
- `validate-mixin` top-level failures expose `failedStage` as a first-class field on the serialized `error` envelope (alongside `code`, `hints`, `suggestedCall`) — one of `"input-validation" | "resolve" | "mapping-health" | "parse" | "target-lookup"`. Branch on that before inspecting `message` to recover automatically (e.g. retry `resolve` failures with `scope="vanilla"`, retry `target-lookup` failures with a different `mapping`). Nested errors that already carry a `failedStage` are preserved so upstream tags (e.g. from `resolve-artifact`) surface unchanged.
|
|
93
|
+
- `validate-mixin` per-result `quickSummary` appends `Scope fell back from "<requested>" to "<applied>" (<reason>).` when `provenance.scopeFallback` is set and `Mapping health degraded: <degradations>.` when `toolHealth.overallHealthy === false`. Clean validations keep the original one-line summary; the extra notes only attach when the pipeline actually fell back or detected a degraded mapping.
|
|
94
|
+
- `mapping-health` stays lightweight for `obfuscated` and `mojang` requests. It avoids full Tiny mapping graph loads unless the caller requests `intermediary` or `yarn`, where Tiny namespace availability is part of the health check.
|
|
95
|
+
- `validate-mixin` runs each stage (`resolve` / `mapping-health` / `parse` / `target-lookup`) against an independent soft-deadline. When the `target-lookup` stage exhausts its budget mid-loop, completed targets stay in `targetOutcomes` with `status: "ok"` (and `slowTarget: true` plus `elapsedMs` when the per-target soft cap was exceeded) while remaining targets land as `status: "deferred-budget"`. The summary then carries `targetsDeferredBudget` and `degradedReason: "stage-budget"`, and `validationStatus` is promoted to `"partial"`. If the budget is exhausted before the first iteration, `targetOutcomes` stays empty, `targetsDeferredBudget` is omitted, and `degradedReason: "stage-budget-pre-target"`.
|
|
96
|
+
- Empty Mixin configs are treated as warning-only discovery results with `summary.total=0` instead of invalid input; malformed JSON still returns `ERR_INVALID_INPUT`.
|
|
97
|
+
|
|
98
|
+
## verify-mixin-target
|
|
99
|
+
|
|
100
|
+
Single-call probe for "does this owner / member exist, and which `@Shadow` / `@Accessor` / `@Invoker` should the mixin use?" Use it before authoring a mixin to avoid round-tripping through `find-class`, `get-class-members`, and `validate-mixin`.
|
|
101
|
+
|
|
102
|
+
Input shape:
|
|
103
|
+
|
|
104
|
+
- `owner` — fully-qualified class name (e.g. `net.minecraft.world.entity.LivingEntity`).
|
|
105
|
+
- `member` — discriminated by `kind`. `{"kind":"method","name":"tick","descriptor":"()V"}` or `{"kind":"field","name":"airSupply"}`. `descriptor` is optional; when omitted, the tool returns every overload (methods) or any matching name (fields).
|
|
106
|
+
- `mixinMemberName` (optional) — the caller-authored mixin field/method name. Drives the `accessorAdvice` rule table when the target is private (`getXxx` / `setXxx` → `@Accessor`, `invokeXxx` / `callXxx` → `@Invoker`).
|
|
107
|
+
- `target` — same shape as `resolve-artifact.target`: `{"kind":"version","value":"1.21.10"}`, `{"kind":"workspace"}` (uses `projectPath`), `{"kind":"dependency","group":"...","name":"..."}`, `{"kind":"coordinate","value":"..."}`, or `{"kind":"jar","value":"..."}`.
|
|
108
|
+
- `mapping`, `sourcePriority`, `projectPath`, `scope`, `preferProjectVersion`, `strictVersion` — same semantics as `resolve-artifact`.
|
|
109
|
+
|
|
110
|
+
Output shape:
|
|
111
|
+
|
|
112
|
+
- `exists: boolean` — true when at least one member matches by name (and descriptor when supplied).
|
|
113
|
+
- `resolvedOwner: { className, mapping }` — echoes the resolved namespace.
|
|
114
|
+
- `matches: Array<{ name, descriptor, accessFlags[], javaSignature?, sourceLine? }>` — every member matching the request.
|
|
115
|
+
- `candidates: Array<{ name, descriptor, reason }>` — populated when `exists=false`. Two reasons are emitted: `"name match, descriptor … differs from requested …"` (descriptor mismatch) or `"name … is similar to requested …"` (Levenshtein-near misses, sourced from the same `suggestSimilar` helper used by the Mixin validator).
|
|
116
|
+
- `accessorAdvice` — annotation-recommendation block. Emitted only when `matches.length === 1` (a single unique match): descriptor-mismatch / nearest-neighbor / candidate-only responses carry no advice (rule table cannot be applied against an unmatched member), and ambiguous overload responses (descriptor omitted, multiple `matches[]`) also carry no advice (a single rule cannot describe several different targets). Re-call with an explicit `descriptor` to disambiguate the overload.
|
|
117
|
+
- `provenance: { artifactId, mappingNamespace, workspaceResolution?, dependencyResolution? }` — the workspace / dependency resolution shape from `resolve-artifact` is preserved when `target.kind` was `workspace` or `dependency`.
|
|
118
|
+
|
|
119
|
+
`accessorAdvice` rule matrix (top-down; first match wins):
|
|
120
|
+
|
|
121
|
+
| # | `member.kind` | target visibility | `mixinMemberName` regex | `suggestedAnnotation` |
|
|
122
|
+
|---|---|---|---|---|
|
|
123
|
+
| 1 | any | `public` / `protected` | (any) | `"@Inject-only"` (target already visible to mixin) |
|
|
124
|
+
| 2 | `field` | `private` | `^get[A-Z]\w*$` / `^set[A-Z]\w*$` / `^is[A-Z]\w*$` | `"@Accessor"` (target field name inferred via prefix removal) |
|
|
125
|
+
| 3 | `field` | `private` | (anything else, including absent) | `"@Shadow"` (or `"@Shadow @Final"` when target is `final`) |
|
|
126
|
+
| 4 | `method` | `private` | `^invoke[A-Z]\w*$` / `^call[A-Z]\w*$` | `"@Invoker"` |
|
|
127
|
+
| 5 | `method` | `private` | any other non-empty value | `"@Shadow"` |
|
|
128
|
+
| 6 | `method` | `private` | (absent) | `null` + `candidates: [@Shadow, @Invoker]` |
|
|
129
|
+
|
|
130
|
+
`"@Inject-only"` is a pseudo-tag, NOT a real Mixin annotation. It signals "no `@Shadow` is needed because the target is already accessible to the mixin"; the caller can use `@Inject` (or a direct method call) without declaring a shadow. `accessorAdvice.exampleSnippet` is a deterministic Java fragment built from the recommendation; the tool does NOT compile-check the snippet — run a Gradle build before committing.
|
|
131
|
+
|
|
132
|
+
Errors:
|
|
133
|
+
|
|
134
|
+
- Owner not found returns `ERR_CLASS_NOT_FOUND` with `details.suggestedCall.tool === "find-class"` and `details.suggestedCall.params.artifactId` pre-filled to the resolved artifact, so the caller can immediately re-probe with the correct simple-name query.
|
|
135
|
+
- Workspace targets without a detectable Minecraft version still raise `ERR_WORKSPACE_VERSION_UNRESOLVED` (inherited from `resolve-artifact`).
|
|
136
|
+
- Namespace mismatch raises `ERR_NAMESPACE_MISMATCH` when an explicit `mapping` argument differs from the resolved artifact's `mappingApplied`. The tool does NOT yet auto-translate `owner` / `member.name` / `descriptor` between namespaces; supply them in the artifact's namespace, or omit `mapping` so the resolver picks the namespace automatically. `details` carries `requestedMapping` and `mappingApplied` so callers can branch programmatically. Auto-translation (per-member name + descriptor remap matching the `get-class-members` flow) is a planned follow-up; until then the explicit error replaces silent `ERR_CLASS_NOT_FOUND` / `exists:false` regressions when the namespaces diverge.
|
|
137
|
+
|
|
138
|
+
Set `VERIFY_MIXIN_TARGET_OFF=1` at process start to remove the tool from `tools/list` entirely and reject direct calls. Use as a rollback path while the accessor-inference rules stabilize.
|
|
139
|
+
|
|
140
|
+
## Batch lookup contract
|
|
141
|
+
|
|
142
|
+
`batch-class-source`, `batch-class-members`, `batch-symbol-exists`, and `batch-mappings` share one envelope. Each call sends a fixed shortlist (1..50 entries) and receives a per-entry result plus an aggregate summary. The batch runs `entries.length` underlying calls but resolves the shared artifact ONCE (where applicable), so the round-trip cost is `1 resolve + N per-entry` rather than `N × (resolve + per-entry)`.
|
|
143
|
+
|
|
144
|
+
Common input fields:
|
|
145
|
+
|
|
146
|
+
- `entries: Array<...>` — 1..50 per-entry payloads. Tool-specific shape (see each subsection).
|
|
147
|
+
- `concurrency: number` (1..8, default 4) — passed to the worker pool. Above 8 is rejected with `ERR_INVALID_INPUT` (`fieldErrors[0].path === "concurrency"`).
|
|
148
|
+
- `failFast: boolean` (default `false`) — when `true`, the first per-entry error sets an abort flag. Workers that have not yet picked up an entry short-circuit with `error.code === "ERR_BATCH_ABORTED"`. **In-flight workers continue to completion** — they are not cancelled (no AbortSignal wiring). Already-completed `ok` entries are still returned in `results`.
|
|
149
|
+
- `compact: boolean` (default `true`) — applies the same per-tool projection that the corresponding single tool's `compact: true` mode applies. When `false`, per-entry `result` is byte-identical to the single tool's `compact: false` output.
|
|
150
|
+
- Per-tool shared inputs (`target`, `mapping`, `projectPath`, `version`, etc.) follow the same shape as the matching single tool.
|
|
151
|
+
|
|
152
|
+
Resource behavior: `concurrency` limits per-entry dispatch for one batch call. Within one MCP server process, entries or calls that need the same artifact index or decompiled fallback share the in-flight rebuild by `artifactId`. Separate MCP server processes sharing the same cache are not coordinated by this process-local guard.
|
|
153
|
+
|
|
154
|
+
Common output:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"results": [
|
|
159
|
+
{
|
|
160
|
+
"index": 0,
|
|
161
|
+
"status": "ok",
|
|
162
|
+
"result": { ... single-tool-result-shape ... },
|
|
163
|
+
"warnings": ["..."],
|
|
164
|
+
"durationMs": 12.34
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"index": 1,
|
|
168
|
+
"status": "error",
|
|
169
|
+
"error": {
|
|
170
|
+
"code": "ERR_CLASS_NOT_FOUND",
|
|
171
|
+
"detail": "...",
|
|
172
|
+
"suggestedCall": { "tool": "get-class-source", "params": { ... } }
|
|
173
|
+
},
|
|
174
|
+
"warnings": [],
|
|
175
|
+
"durationMs": 5.6
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"summary": {
|
|
179
|
+
"total": 2,
|
|
180
|
+
"ok": 1,
|
|
181
|
+
"error": 1,
|
|
182
|
+
"sharedArtifactId": "...",
|
|
183
|
+
"sharedArtifactProvenance": { ... }
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Per-entry retry semantics: each `error.suggestedCall` proposes the **matching single tool**, never the batch tool itself. The retry mapping is fixed:
|
|
189
|
+
|
|
190
|
+
| Batch tool | Single tool retry |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `batch-class-source` | `get-class-source` (with `target: { type: "artifact", artifactId: <shared> }`) |
|
|
193
|
+
| `batch-class-members` | `get-class-members` (with `target: { type: "artifact", artifactId: <shared> }`) |
|
|
194
|
+
| `batch-symbol-exists` | `check-symbol-exists` (with `version` derived from the resolved artifact) |
|
|
195
|
+
| `batch-mappings` | `find-mapping` (with `version` carried from the top-level batch input) |
|
|
196
|
+
|
|
197
|
+
Every per-entry `suggestedCall` is validated through the same `tool-schema-registry` gate as single-tool errors (see `## Errors → suggestedCall schema validation gate`).
|
|
198
|
+
|
|
199
|
+
If the **shared resolution itself** fails (e.g. `target.kind="version"` with an unknown version), the batch returns a top-level error envelope (no `results[]`). `failFast` does not apply because no entries ran.
|
|
200
|
+
|
|
201
|
+
Rollback: `BATCH_TOOLS_OFF=1` removes all four batch tools from `tools/list`. Direct `tools/call` for any of them returns the SDK-level "Method not found" tool-result envelope (`{ content: [{ type: "text", text: "MCP error -32602: Tool <name> not found" }], isError: true }`) — no `ProblemDetails` is produced, so callers cannot rely on `error.code === "ERR_*"` for disabled tools.
|
|
202
|
+
|
|
203
|
+
### batch-class-source
|
|
204
|
+
|
|
205
|
+
Read source for many classes against one shared resolved artifact. Per-entry: `{ className, mode?, startLine?, endLine?, maxLines?, maxChars?, outputFile? }`. Shared: `target`, `mapping`, `projectPath`, `scope`, `preferProjectVersion`, `strictVersion`, `allowDecompile`. Result shape per entry mirrors `get-class-source`. Duplicate `className` entries each run independently — no de-duplication.
|
|
206
|
+
|
|
207
|
+
### batch-class-members
|
|
208
|
+
|
|
209
|
+
List members for many classes against one shared resolved artifact. Per-entry: `{ className, access?, includeSynthetic?, includeInherited?, memberPattern?, maxMembers? }`. Shared inputs match `batch-class-source`. Result shape per entry mirrors `get-class-members`, including the `status` field (`"available"` / `"unavailable"` / etc.).
|
|
210
|
+
|
|
211
|
+
### batch-symbol-exists
|
|
212
|
+
|
|
213
|
+
Probe symbol existence for many entries against one shared Minecraft-version artifact. Per-entry: `{ kind: "class" | "field" | "method", name, owner?, descriptor?, nameMode?, signatureMode?, maxCandidates? }`. Shared: `target`, `mapping`, `projectPath`, `scope`, `preferProjectVersion`, `strictVersion`, `allowDecompile`. **`target.kind` is restricted to `"workspace"` or `"version"`** — `dependency` / `jar` / `coordinate` resolve to artifacts whose `provenance.version` is the library's own version (e.g. an Architectury or mod-loader version), NOT a Minecraft version, so querying the Minecraft mapping graph with that string would be a category error. The schema rejects the disallowed kinds with `ERR_INVALID_INPUT`. The shared Minecraft version is derived from `sharedArtifact.version` (version target) or `provenance.workspaceResolution.detected.minecraftVersion` (workspace target). When neither populates, the batch raises `ERR_WORKSPACE_VERSION_UNRESOLVED` at the resolution stage.
|
|
214
|
+
|
|
215
|
+
### batch-mappings
|
|
216
|
+
|
|
217
|
+
Translate symbols across mapping namespaces with one shared Minecraft version. Per-entry: `{ kind, name, owner?, descriptor?, sourceMapping, targetMapping, signatureMode?, disambiguation?, maxCandidates? }`. Shared: top-level `version` (required) plus `sourcePriority` / `projectPath`. Per-entry `version` is rejected with an `unrecognized_keys` zod issue; the batch shape is intentionally single-version. There is no shared artifact resolution — each entry hits the mapping graph directly — so `summary.sharedArtifactId` is omitted.
|
|
218
|
+
|
|
219
|
+
## Errors
|
|
220
|
+
|
|
221
|
+
`ProblemDetails.code` may carry the codes below in addition to the existing tool-specific values.
|
|
222
|
+
|
|
223
|
+
- `ERR_WORKER_RESTART` — Synthetic envelope produced by the supervisor when the worker process exits while handling `tools/call`. The response is a `CallToolResult` with `isError: true` and `structuredContent.error.code === "ERR_WORKER_RESTART"`. `structuredContent.meta.synthetic === true` and `meta.restart` records `tool` / `durationMs` / `lastStage` / `lastStageElapsedMs` / `lastStageMeta` / `exit` / `retryRecommendation` so the caller can decide whether to retry, narrow the input, clear caches, or report a bug. Non-`tools/call` requests (`initialize`, `tools/list`, etc.) still receive the legacy raw JSON-RPC `-32603` envelope.
|
|
224
|
+
- `ERR_MIXIN_PARSE_FAILED` — Reserved code for `validate-mixin` parse-stage failures in single / inline mode. Today the runtime parser is permissive (no hard parse failure path), but emitting this code keeps the contract stable for future strict-parse modes.
|
|
225
|
+
- `ERR_STAGE_BUDGET_PRE_PARSE` — Raised when a pre-parse stage (`resolve`, `mapping-health`, or `parse` itself) exhausts its independent soft-deadline before validation can proceed. The error carries `failedStage: <stage name>`, `meta.stageBudgetExhausted: true`, and the `budgetMs` / `elapsedMs` for the offending stage. Recovery: shrink `mixinConfigPath` (e.g. validate one config file at a time) or set `MIXIN_STAGE_BUDGETS_OFF=1` to disable budgets for diagnostic reruns.
|
|
226
|
+
- `ERR_WORKSPACE_VERSION_UNRESOLVED` — Raised by `resolve-artifact`, `get-class-source`, and `get-class-members` when `target.kind="workspace"` cannot detect a Minecraft version from `gradle.properties`. Both `strict: true` and `strict: false` raise; `details.strict` records which value was supplied. The error carries `details.projectPath` and a `suggestedCall` with `target: { kind: "version", value: "<your-mc-version>" }` so the caller can fall back to an explicit version target.
|
|
227
|
+
- `ERR_DEPENDENCY_VERSION_UNRESOLVED` — Raised by the same three tools when `target.kind="dependency"` cannot infer a version from `gradle.properties` or `~/.gradle/caches/modules-2/files-2.1/<group>/<name>/`. Multiple non-snapshot entries in modules-2 also raise this error: the synthesizer refuses to pick without project-specific evidence, sets `details.ambiguous=true`, and lists the cached versions in `details.candidatesSeen`. The error carries `details.attempts` (the gradle.properties keys that were probed) plus a `suggestedCall` with `target: { kind: "dependency", group, name, version: "<your-version>" }`.
|
|
228
|
+
|
|
229
|
+
### `suggestedCall` schema validation gate
|
|
230
|
+
|
|
231
|
+
Every `ProblemDetails.suggestedCall` payload an agent receives is validated against the registered `zod` schema for the named tool BEFORE it leaves the process. Invalid payloads (e.g. a `target.value` that holds a JSON-stringified inner target — the bug in v3 chains where round-tripping the suggestion produced `ERR_INVALID_INPUT`) are dropped from the published envelope. When the gate drops a primary suggestion AND no `exampleCalls[]` fallback is available, `error.hints` gains the literal sentence `"suggested call payload failed schema validation; using fallback examples"` so the caller can observe that a suggestion was elided.
|
|
232
|
+
|
|
233
|
+
The optional `error.exampleCalls?: Array<{ tool: string; params: Record<string, unknown>; reason: string }>` field carries one or more **always-valid** alternative payloads when the primary is dropped. Each entry already passed the schema gate at construction time and is safe to re-call as-is.
|
|
234
|
+
|
|
235
|
+
`suggestedCall.params` is published **byte-identical** to the caller-supplied object — the gate validates emit-vs-drop only and never injects schema defaults into the published payload. Internal consumers that want the schema-normalized form read `validateToolParams(name, params).data` directly from `tool-schema-registry`.
|
|
236
|
+
|
|
237
|
+
## Meta fields
|
|
238
|
+
|
|
239
|
+
- `meta.restart` (synthetic worker-restart responses only) — emitted exclusively when the supervisor returns an `ERR_WORKER_RESTART` envelope. Shape: `{ tool, durationMs, lastStage, lastStageElapsedMs, lastStageMeta, exit: { code, signal }, retryRecommendation }`. `retryRecommendation` is one of `"narrow-query" | "clear-cache" | "report-bug" | "same-request"`, decided by the supervisor from `lastStage`, `exit.signal`, and the recent restart cadence (3 restarts within 60 s of the same tool → `"report-bug"`).
|
|
240
|
+
- `meta.stageBudgetExhausted` (`ERR_STAGE_BUDGET_PRE_PARSE` errors only) — set to `true` to flag that the failure is budget-driven rather than a genuine resolve / mapping-health / parse error. Pair with `failedStage` and `error.detail` (`"Stage <name> exhausted budget before parse completed."`) for diagnostics. The companion fields `meta.budgetMs` (the stage budget that was exceeded) and `meta.elapsedMs` (the actual stage elapsed time) are emitted alongside it on the same envelope so callers can decide between retry, input-shrink (`mixinConfigPath`), or `MIXIN_STAGE_BUDGETS_OFF=1` rollback without parsing message text.
|
|
241
|
+
- `validate-mixin` batch-mode entries (`results[i]`, when invoked with `input.mode = "paths" | "config" | "project"`) preserve typed error metadata when an entry fails: optional `errorCode` (e.g. `"ERR_STAGE_BUDGET_PRE_PARSE"`) and `errorDetails` (the `failedStage` / `stageBudgetExhausted` / `budgetMs` / `elapsedMs` shape from the underlying AppError) sit alongside the legacy `error` string. The shape is additive — callers that only read `error` continue to see the same human-readable message.
|
|
242
|
+
|
|
243
|
+
## Operational toggles
|
|
244
|
+
|
|
245
|
+
These environment variables are read once at worker startup and provide rollback paths to legacy behaviour. Switching them requires reconnecting the MCP server (no per-request override).
|
|
246
|
+
|
|
247
|
+
| Env | Effect | Acceptance test |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `MIXIN_STAGE_BUDGETS_OFF=1` | Sets every `validate-mixin` stage budget (including the per-target soft cap) to `Number.POSITIVE_INFINITY`. Restores the pre-budget run-to-completion behaviour. | `tests/source-service-validate-mixin-budget.test.ts` (`MIXIN_STAGE_BUDGETS_OFF=1 disables all budgets`) |
|
|
250
|
+
| `SUPERVISOR_STRUCTURED_RESTART_OFF=1` | Suppresses synthetic `CallToolResult` envelopes; `tools/call` requests killed by a worker exit fall back to the legacy raw JSON-RPC `-32603` error. | `tests/stdio-supervisor.test.ts` (`buildWorkerRestartReply returns raw -32603 when structuredRestartDisabled`) |
|
|
251
|
+
| `MIXIN_STAGE_PROGRESS_OFF=1` | Replaces the worker stage emitter with a no-op so `$/stageUpdate` notifications are never sent. Use as a fallback when the active SDK build does not surface `extra.requestId`. | `tests/stage-emitter.test.ts` (`makeStageEmitter is a no-op when disabled option is true`) |
|
|
252
|
+
| `WORKSPACE_TARGET_OFF=1` | Rejects `target.kind="workspace"` on `resolve-artifact`, `get-class-source`, and `get-class-members` with `ERR_INVALID_INPUT`. Restores the pre-workspace-target behaviour where callers must always supply `target.kind="version"`/`"jar"`/`"coordinate"`. | `tests/source-service-workspace-target.test.ts` (`synthesizeWorkspaceTarget rejects target.kind=workspace when WORKSPACE_TARGET_OFF is set`) |
|
|
253
|
+
| `DEPENDENCY_TARGET_OFF=1` | Rejects `target.kind="dependency"` on the same three tools with `ERR_INVALID_INPUT`. | `tests/source-service-dependency-target.test.ts` (`synthesizeDependencyTarget rejects target.kind=dependency when DEPENDENCY_TARGET_OFF is set`) |
|
|
254
|
+
| `WORKSPACE_FALLBACK_LEGACY=1` | Forces the `ERR_MAPPING_NOT_APPLIED` `suggestedCall` back to the pre-workspace shape (`{ target, mapping: "obfuscated" }` with the legacy scope flip on `vanilla`+`mojang`). Use when an integration relies on the legacy retry payload. | `tests/source-service-mapping-not-applied-fallback.test.ts` (`buildMappingFallbackSuggestedCall returns the legacy obfuscated retry when WORKSPACE_FALLBACK_LEGACY is set`) |
|
|
255
|
+
| `VALIDATE_PROJECT_TASKS_OFF=1` | Omits the additive `tasks` per-probe status report from `validate-project task="project-summary"` results. The headline `result.summary.status`, `result.project`, and `result.workspace` blocks are unchanged. Use as a rollback path while the per-probe contract stabilizes. | `tests/entry-tools-validate-project-tasks.test.ts` (`validate-project tasks A5: VALIDATE_PROJECT_TASKS_OFF=1 omits the tasks field`) |
|
|
256
|
+
| `MEMBERS_STATUS_LEGACY=1` | Omits the additive `status` / `unavailableReason` / `suggestedCall` fields from `get-class-members` results. Restores the pre-status response shape for callers that pre-date the new enum. | `tests/source-service-get-class-members-status.test.ts` (`B7: MEMBERS_STATUS_LEGACY=1 strips the new fields`) |
|
|
257
|
+
| `VERIFY_MIXIN_TARGET_OFF=1` | Removes `verify-mixin-target` from `tools/list` and rejects direct invocations with `ERR_INVALID_INPUT`. Use as a rollback path while the accessor-inference rules stabilize. | `tests/entry-tools-verify-mixin-target.test.ts` (`C11: VERIFY_MIXIN_TARGET_OFF=1 hides the tool from tools/list and rejects direct calls`) |
|
|
258
|
+
| `SUGGESTED_CALL_VALIDATE_OFF=1` | Bypasses the `ProblemDetails.suggestedCall` schema validation gate. Raw caller-supplied payloads are emitted unchanged (matching the pre-gate behaviour); `error.hints` does not gain the fallback line. Use only as an emergency rollback if the gate causes unexpected drops in production. | `tests/build-suggested-call.test.ts` (`D11: SUGGESTED_CALL_VALIDATE_OFF=1 bypasses validation`) |
|
|
259
|
+
| `BATCH_TOOLS_OFF=1` | Removes the 4 batch lookup tools (`batch-class-source`, `batch-class-members`, `batch-symbol-exists`, `batch-mappings`) from `tools/list`. Direct calls return the SDK "Tool not found" tool-result envelope (`isError: true`, no `ProblemDetails`). Use as an emergency rollback while the batch contract stabilizes. | `tests/manual/stdio-client-smoke.manual.ts` (`runBatchToolsOffProbe`) |
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
## Migration Notes
|
|
263
|
+
|
|
264
|
+
- Start with `inspect-minecraft` for version, artifact, class, file, and search workflows before dropping to `list-versions`, `resolve-artifact`, `get-class-source`, `get-class-members`, `search-class-source`, `get-artifact-file`, or `list-artifact-files`.
|
|
265
|
+
- Start with `analyze-symbol` for symbol mapping, existence, lifecycle, workspace, and API overview workflows before using `find-mapping`, `resolve-method-mapping-exact`, `check-symbol-exists`, `trace-symbol-lifecycle`, `resolve-workspace-symbol`, or `get-class-api-matrix` directly.
|
|
266
|
+
- `analyze-symbol task="lifecycle"` treats its required `version` as the upper bound for the lifecycle scan and intentionally limits the high-level helper to a recent 5-version window. Use `trace-symbol-lifecycle` directly when you need explicit `fromVersion` / `toVersion` control or a wider history.
|
|
267
|
+
- Start with `compare-minecraft` for version-pair, class diff, registry diff, and migration-summary flows before using `compare-versions`, `diff-class-signatures`, or `get-registry-data` directly.
|
|
268
|
+
- Start with `analyze-mod` for metadata-first mod inspection and safe remap preview/apply flows before using `analyze-mod-jar`, `decompile-mod-jar`, `get-mod-class-source`, `search-mod-source`, or `remap-mod-jar` directly.
|
|
269
|
+
- Start with `validate-project` for workspace summaries and direct Mixin, Access Widener, or Access Transformer validation before using `validate-mixin`, `validate-access-widener`, or `validate-access-transformer` directly.
|
|
270
|
+
- `validate-project task="project-summary"` discovers mixins and access wideners by default. Add `discover: ["access-transformers"]` when you also want Access Transformer files included in the workspace summary.
|
|
271
|
+
- `validate-project task="project-summary"` returns an additive `tasks` field alongside the existing aggregate `result.summary` / `result.project` blocks. The headline `result.summary.status` is unchanged; the new field reports per-probe status so a `status: "blocked"` headline still preserves which probes succeeded.
|
|
272
|
+
|
|
273
|
+
| Probe key | What it checks | `status: "ok"` evidence | Other states |
|
|
274
|
+
| --- | --- | --- | --- |
|
|
275
|
+
| `workspace.detected` | A `gradle.properties`, `settings.gradle{,.kts}`, or `build.gradle{,.kts}` file exists at `subject.projectPath`. | `evidence: ["gradle.properties", ...]` lists the gradle files that were found. | `missing` when no gradle files exist; `error` when the filesystem read itself failed. |
|
|
276
|
+
| `gradle.readable` | `gradle.properties` can be read and the workspace's gradle build scripts are enumerable. | `propertiesPath` and `buildScripts[]` (relative paths). | `skipped` when `workspace.detected` is not `ok`; `missing` when no gradle files at all; `error` on parse / read failure. |
|
|
277
|
+
| `loom.cache.found` | A Loom (Fabric / Quilt) cache directory under the workspace or `GRADLE_USER_HOME` exists. Independent of `workspace.detected` so callers can detect a global Loom cache even on non-gradle workspaces. | `cachePath` of the first matching directory. | `missing` when none of the candidate roots exist; `error` on filesystem failure. |
|
|
278
|
+
| `minecraft.artifact.resolved` | A lightweight artifact metadata probe can locate `target: { kind: "version", value: <resolvedVersion> }` against the workspace context. The probe does not decompile Minecraft or rebuild the source index. | `artifactId` and `mappingApplied`. | `skipped` when `workspace.detected` or `gradle.readable` is not `ok`; `error` when the lightweight probe cannot verify the artifact or requested mapping without full resolution (carries `error.code` and `error.detail`). |
|
|
279
|
+
| `mixins.validated` | At least one `*.mixins.json` file was discovered AND every per-config validation completed without throwing. | `counts: { ok, partial, invalid }` (validation outcomes from `validate-mixin`). | `error` when any per-config validation threw (still emits `counts`); `skipped` when discovery was empty AND `workspace.detected` / `gradle.readable` blocked; `missing` when discovery returned 0 paths and upstream probes were `ok`. A failed `minecraft.artifact.resolved` does not flip executed validators to `skipped`. |
|
|
280
|
+
| `accessWideners.validated` | At least one Access Widener file was discovered AND every validation completed without throwing. | `counts: { ok, invalid }`. | Same rules as `mixins.validated`. |
|
|
281
|
+
| `accessTransformers.validated` | At least one Access Transformer file was discovered AND every validation completed without throwing. | `counts: { ok, invalid }`. | Same rules as `mixins.validated`. |
|
|
282
|
+
|
|
283
|
+
Status precedence (top wins): `error` (item-level caught) > `ok` (validators ran) > `skipped` (upstream env blocked AND no items ran) > `missing` (no items, upstream `ok`).
|
|
284
|
+
|
|
285
|
+
Output projection: with `detail: "summary"` (or when `include` does not contain `"workspace"`), each `tasks[*]` entry is slimmed to `status`, `error?`, and `warnings?` only — `evidence` / `buildScripts` / `counts` / `propertiesPath` / `cachePath` / `artifactId` / `mapping` / `durationMs` are stripped. With `detail: "full"` (or `"standard"`) AND `include` containing `"workspace"`, every sub-field is preserved. Set `VALIDATE_PROJECT_TASKS_OFF=1` at process start to omit the field entirely (legacy shape). Use `resolve-artifact` directly when a follow-up source lookup needs a fully indexed artifact.
|
|
286
|
+
- `validate-access-widener` keeps vanilla validation when `projectPath`, `scope`, and `preferProjectVersion` are omitted. Supplying Loom workspace context switches it into runtime-aware mode, which returns `provenance` and per-entry runtime access evidence without changing the existing summary shape.
|
|
287
|
+
- `validate-access-transformer` accepts `atNamespace="srg" | "mojang" | "obfuscated"`. When `projectPath` points at a Forge or NeoForge workspace, the tool can infer that namespace automatically and validate against loader/runtime artifacts for `scope="loader"`.
|
|
288
|
+
- Start with `manage-cache` for cache inventory and safe cleanup. Use `executionMode="preview"` before `executionMode="apply"`.
|
|
289
|
+
- Replace `resolve-artifact` `targetKind` and `targetValue` with `target: { kind, value }`.
|
|
290
|
+
- Replace `get-class-source` and `get-class-members` top-level `artifactId`, `targetKind`, and `targetValue` with `target: { type: "artifact", artifactId }` or `target: { type: "resolve", kind, value }`.
|
|
291
|
+
- `resolve-method-mapping-exact` is method-only and no longer accepts `kind`.
|
|
292
|
+
- Replace `validate-mixin` `source`, `sourcePath`, `sourcePaths`, `mixinConfigPath`, and `sourceRoot` with `input.mode` plus `input.source`, `input.path`, `input.paths[]`, `input.configPaths[]`, and `sourceRoots[]`.
|
|
293
|
+
- `search-class-source` removed snippet, definition, and relation expansion. Responses now contain compact `hits[]` plus `nextCursor?`, and `symbolKind` is only valid with `intent="symbol"`.
|
|
294
|
+
|
|
295
|
+
## Resources
|
|
296
|
+
|
|
297
|
+
MCP resources provide URI-based access to Minecraft data for clients that support the resource protocol.
|
|
298
|
+
|
|
299
|
+
### Fixed Resources
|
|
300
|
+
|
|
301
|
+
| Resource | URI | Description |
|
|
302
|
+
| --- | --- | --- |
|
|
303
|
+
| `versions-list` | `mc://versions/list` | List all available Minecraft versions with metadata |
|
|
304
|
+
| `runtime-metrics` | `mc://metrics` | Runtime metrics and performance counters |
|
|
305
|
+
|
|
306
|
+
### Template Resources
|
|
307
|
+
|
|
308
|
+
| Resource | URI Template | Description |
|
|
309
|
+
| --- | --- | --- |
|
|
310
|
+
| `class-source` | `mc://source/{artifactId}/{className}` | Java source code for a class within a resolved artifact |
|
|
311
|
+
| `artifact-file` | `mc://artifact/{artifactId}/files/{filePath}` | Raw content of a file within a resolved artifact |
|
|
312
|
+
| `find-mapping` | `mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{name}` | Look up a mapping between two naming namespaces |
|
|
313
|
+
| `class-members` | `mc://artifact/{artifactId}/members/{className}` | List constructors, methods, and fields for a class |
|
|
314
|
+
| `artifact-metadata` | `mc://artifact/{artifactId}` | Metadata for a previously resolved artifact |
|
|
315
|
+
|
|
316
|
+
`versions-list`, `runtime-metrics`, `find-mapping`, `class-members`, and `artifact-metadata` return structured JSON envelopes on success (`{ result, meta }`) and failure (`{ error, meta }`).
|
|
317
|
+
|
|
318
|
+
`class-source` and `artifact-file` keep raw text responses on success, but still return structured JSON errors on failure.
|
|
319
|
+
|
|
320
|
+
## Response Envelope
|
|
321
|
+
|
|
322
|
+
All tools return exactly one of:
|
|
323
|
+
|
|
324
|
+
- Success: `{ result: { ... }, meta: { requestId, tool, durationMs, warnings[] } }`
|
|
325
|
+
- Failure: `{ error: { type, title, detail, status, code, instance, fieldErrors?, hints? }, meta: { requestId, tool, durationMs, warnings[] } }`
|
|
326
|
+
|
|
327
|
+
Tools may publish execution counters on `meta` alongside the fields above. The NBT tools use this: `nbt-apply-json-patch` surfaces `appliedOps`, `testOps`, and `changed`; `json-to-nbt` surfaces `outputBytes` and `compressionApplied`; `nbt-to-json` surfaces `inputBytes` and `compressionDetected`.
|
|
328
|
+
|
|
329
|
+
JSON resources follow the same `result/error/meta` pattern. Text resources return plain text on success.
|
|
330
|
+
|
|
331
|
+
The same JSON envelope is mirrored in MCP `structuredContent` for SDK-aware clients, and failures also set `isError=true`.
|
|
332
|
+
|
|
333
|
+
## Mapping Policy
|
|
334
|
+
|
|
335
|
+
### Namespace Definitions
|
|
336
|
+
|
|
337
|
+
| Namespace | Description |
|
|
338
|
+
| --- | --- |
|
|
339
|
+
| `obfuscated` | Mojang obfuscated names such as `a`, `b`, `c` |
|
|
340
|
+
| `mojang` | Mojang deobfuscated names from `client_mappings.txt` such as `net.minecraft.server.Main` |
|
|
341
|
+
| `intermediary` | Fabric stable intermediary names such as `net.minecraft.class_1234` and `method_5678` |
|
|
342
|
+
| `yarn` | Fabric community human-readable names such as `net.minecraft.server.MinecraftServer` and `tick` |
|
|
343
|
+
|
|
344
|
+
The legacy public namespace name `official` was removed. Requests that still send `official` now fail validation and should be updated to `obfuscated`.
|
|
345
|
+
|
|
346
|
+
### Lookup Rules
|
|
347
|
+
|
|
348
|
+
`find-mapping` supports lookup across `obfuscated`, `mojang`, `intermediary`, and `yarn`.
|
|
349
|
+
|
|
350
|
+
Symbol query inputs use `kind` plus `name` plus optional `owner` and `descriptor`:
|
|
351
|
+
|
|
352
|
+
- class: `kind="class"`, `name="a.b.C"` by default. `find-mapping` also accepts short obfuscated runtime ids such as `dhl` when `sourceMapping="obfuscated"`. For existence checks only, `nameMode="auto"` allows short names such as `Blocks`.
|
|
353
|
+
- field: `kind="field"`, `owner="a.b.C"`, `name="fieldName"`
|
|
354
|
+
- method: `kind="method"`, `owner="a.b.C"`, `name="methodName"`, `descriptor="(I)V"`
|
|
355
|
+
|
|
356
|
+
`mapping="mojang"` requires a source-backed artifact on legacy obfuscated versions. On unobfuscated releases such as `26.1+`, decompile-only/runtime paths are accepted directly for version and versioned-coordinate targets.
|
|
357
|
+
|
|
358
|
+
`resolve-artifact`, `get-class-members`, `trace-symbol-lifecycle`, and `diff-class-signatures` accept `obfuscated | mojang | intermediary | yarn` with these constraints:
|
|
359
|
+
|
|
360
|
+
- `intermediary` and `yarn` require a resolvable Minecraft version context such as `target.kind="version"` or a versioned Maven coordinate.
|
|
361
|
+
- For unobfuscated versions such as `26.1+`, requesting `intermediary` or `yarn` falls back to `obfuscated` with a warning.
|
|
362
|
+
- On legacy obfuscated versions, `mojang` requires source-backed artifacts and decompile-only paths are rejected with `ERR_MAPPING_NOT_APPLIED`.
|
|
363
|
+
- On unobfuscated versions such as `26.1+`, `mojang` uses the runtime/decompile path directly for version and versioned-coordinate targets and skips Loom source-jar approximation.
|
|
364
|
+
|
|
365
|
+
When `trace-symbol-lifecycle` omits `descriptor`, the server resolves methods by owner and name and warns if overload ambiguity prevents a unique answer.
|
|
366
|
+
|
|
367
|
+
If callers accidentally append an inline signature suffix to `trace-symbol-lifecycle.symbol`, the server strips that suffix before splitting `Class.method`. Use the separate `descriptor` field when the workflow needs exact overload matching.
|
|
368
|
+
|
|
369
|
+
`trace-symbol-lifecycle` rejects class-like `symbol` inputs such as `net.minecraft.world.item.Item` with `ERR_INVALID_INPUT`. Pass `Class.method` and keep exact overload matching in the separate `descriptor` field.
|
|
370
|
+
|
|
371
|
+
`trace-symbol-lifecycle` evaluates per-version bytecode checks with bounded parallelism. If you only need a narrower historical window, still prefer explicit `fromVersion` / `toVersion` bounds to reduce work further.
|
|
372
|
+
|
|
373
|
+
`trace-symbol-lifecycle`, `check-symbol-exists`, and `find-mapping` skip intermediary/yarn Tiny graph loading when the request only needs Mojang/obfuscated names, so cold `mojang <-> obfuscated` lifecycle and existence lookups no longer pay the full named-namespace graph cost.
|
|
374
|
+
|
|
375
|
+
For decompile-only `ERR_MAPPING_NOT_APPLIED` failures, error details include `artifactOrigin`, `nextAction`, and `suggestedCall` so clients can recover without guessing.
|
|
376
|
+
|
|
377
|
+
If `find-class` or `get-class-source` returns no hit on an `obfuscated` artifact for names like `net.minecraft.world.item.Item`, the tool warns that `obfuscated` means Mojang's runtime names and recommends retrying with `mapping="mojang"` or translating via `find-mapping`.
|
|
378
|
+
|
|
379
|
+
Method descriptor precision is best on Tiny-backed paths (`intermediary` and `yarn`). For `obfuscated <-> mojang`, Mojang `client_mappings` do not carry JVM descriptors, so descriptor queries may fall back to name matching and emit a warning.
|
|
380
|
+
|
|
381
|
+
Use `resolve-method-mapping-exact` when candidate ranking is not enough and the workflow needs strict `owner + name + descriptor` certainty.
|
|
382
|
+
|
|
383
|
+
Use `find-mapping` `disambiguation.ownerHint` and `disambiguation.descriptorHint` to narrow ambiguous candidate sets.
|
|
384
|
+
|
|
385
|
+
Use `resolve-workspace-symbol` when you need compile-visible names from actual Gradle Loom mappings in a workspace.
|
|
386
|
+
|
|
387
|
+
## Environment Variables
|
|
388
|
+
|
|
389
|
+
Path-based overrides treat blank values and the literal strings `undefined` and `null` as unset, so accidental client serialization does not create `./undefined` or `./null` cache roots or broken JAR override paths.
|
|
390
|
+
|
|
391
|
+
### Core and Repository Discovery
|
|
392
|
+
|
|
393
|
+
| Variable | Default | Description |
|
|
394
|
+
| --- | --- | --- |
|
|
395
|
+
| `MCP_CACHE_DIR` | `~/.cache/minecraft-modding-mcp` | Cache root for downloads and SQLite |
|
|
396
|
+
| `MCP_SQLITE_PATH` | `<cacheDir>/source-cache.db` | SQLite database path |
|
|
397
|
+
| `MCP_SOURCE_REPOS` | Maven Central + Fabric + Forge + NeoForge | Comma-separated Maven repository URLs |
|
|
398
|
+
| `MCP_LOCAL_M2` | `~/.m2/repository` | Local Maven repository path |
|
|
399
|
+
| `MCP_ENABLE_INDEXED_SEARCH` | `true` | Enable indexed query path for `search-class-source` |
|
|
400
|
+
| `MCP_MAPPING_SOURCE_PRIORITY` | `loom-first` | Mapping source priority (`loom-first` or `maven-first`) |
|
|
401
|
+
| `MCP_VERSION_MANIFEST_URL` | Mojang manifest URL | Override the Minecraft version manifest endpoint |
|
|
402
|
+
|
|
403
|
+
### Search, Index, and Cache Tuning
|
|
404
|
+
|
|
405
|
+
| Variable | Default | Description |
|
|
406
|
+
| --- | --- | --- |
|
|
407
|
+
| `MCP_MAX_CONTENT_BYTES` | `1000000` | Maximum bytes for file read operations |
|
|
408
|
+
| `MCP_MAX_SEARCH_HITS` | `200` | Maximum search result count |
|
|
409
|
+
| `MCP_SEARCH_SCAN_PAGE_SIZE` | `250` | Page size used by literal scan fallbacks |
|
|
410
|
+
| `MCP_INDEX_INSERT_CHUNK_SIZE` | `200` | Batch size for SQLite index inserts |
|
|
411
|
+
| `MCP_MAX_ARTIFACTS` | `200` | Maximum cached artifacts |
|
|
412
|
+
| `MCP_MAX_CACHE_BYTES` | `2147483648` | Maximum total cache size in bytes |
|
|
413
|
+
| `MCP_CACHE_GRAPH_MAX` | `16` | Mapping graph cache size |
|
|
414
|
+
| `MCP_CACHE_SIGNATURE_MAX` | `2000` | Signature cache size |
|
|
415
|
+
| `MCP_CACHE_VERSION_DETAIL_MAX` | `256` | Version detail cache size |
|
|
416
|
+
|
|
417
|
+
### Networking
|
|
418
|
+
|
|
419
|
+
| Variable | Default | Description |
|
|
420
|
+
| --- | --- | --- |
|
|
421
|
+
| `MCP_FETCH_TIMEOUT_MS` | `15000` | HTTP request timeout in milliseconds |
|
|
422
|
+
| `MCP_FETCH_RETRIES` | `2` | HTTP request retry count |
|
|
423
|
+
|
|
424
|
+
### Decompilation and Remapping
|
|
425
|
+
|
|
426
|
+
| Variable | Default | Description |
|
|
427
|
+
| --- | --- | --- |
|
|
428
|
+
| `MCP_VINEFLOWER_JAR_PATH` | unset | Override the Vineflower JAR path |
|
|
429
|
+
| `MCP_VINEFLOWER_VERSION` | `1.11.2` | Vineflower version to auto-download when no JAR path override is set |
|
|
430
|
+
| `MCP_TINY_REMAPPER_JAR_PATH` | unset | Override the tiny-remapper JAR path |
|
|
431
|
+
| `MCP_TINY_REMAPPER_VERSION` | `0.10.3` | tiny-remapper version to auto-download when no JAR path override is set |
|
|
432
|
+
| `MCP_REMAP_TIMEOUT_MS` | `600000` | Remap operation timeout in milliseconds |
|
|
433
|
+
| `MCP_REMAP_MAX_MEMORY_MB` | `4096` | Maximum JVM heap for remap operations |
|
|
434
|
+
|
|
435
|
+
### NBT Limits
|
|
436
|
+
|
|
437
|
+
| Variable | Default | Description |
|
|
438
|
+
| --- | --- | --- |
|
|
439
|
+
| `MCP_MAX_NBT_INPUT_BYTES` | `4194304` | Maximum decoded NBT input bytes accepted by `nbt-to-json` |
|
|
440
|
+
| `MCP_MAX_NBT_INFLATED_BYTES` | `16777216` | Maximum gzip-inflated bytes accepted by `nbt-to-json` |
|
|
441
|
+
| `MCP_MAX_NBT_RESPONSE_BYTES` | `8388608` | Maximum response payload bytes for NBT tools |
|
|
442
|
+
|
|
443
|
+
### Diagnostics
|
|
444
|
+
|
|
445
|
+
| Variable | Default | Description |
|
|
446
|
+
| --- | --- | --- |
|
|
447
|
+
| `MCP_SUPERVISOR_DEBUG` | unset | Set to `1` to emit verbose stdio supervisor diagnostics |
|
|
448
|
+
|
|
449
|
+
Internal worker-mode environment variables are reserved for the transport implementation and are intentionally omitted from the public reference.
|
|
450
|
+
|
|
451
|
+
## Architecture
|
|
452
|
+
|
|
453
|
+
| Component | Technology |
|
|
454
|
+
| --- | --- |
|
|
455
|
+
| Runtime | Node.js 22+ |
|
|
456
|
+
| Transport | stdio with newline and `Content-Length` framing support |
|
|
457
|
+
| Storage | SQLite for artifact metadata, source indexing, and cache bookkeeping |
|
|
458
|
+
| Decompilation | [Vineflower](https://github.com/Vineflower/vineflower) |
|
|
459
|
+
| Remapping | [tiny-remapper](https://github.com/FabricMC/tiny-remapper) |
|
|
460
|
+
| Mapping Sources | Mojang `client_mappings.txt`, Fabric Loom workspace metadata, Maven Tiny v2 |
|
|
461
|
+
|
|
462
|
+
The server runs as a long-lived stdio process. Artifacts, mappings, and generated metadata are downloaded on demand and cached locally.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhisang/minecraft-modding-mcp",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "MCP server
|
|
3
|
+
"version": "4.1.1",
|
|
4
|
+
"description": "MCP server for AI-assisted Minecraft modding: inspect decompiled source, resolve Mojang/Yarn/Intermediary mappings, diff versions, analyze Fabric/Forge/NeoForge mod JARs, and validate Mixin, Access Widener, and Access Transformer files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"dist/**/*.d.ts",
|
|
14
14
|
"README.md",
|
|
15
15
|
"LICENSE",
|
|
16
|
-
"CHANGELOG.md"
|
|
16
|
+
"CHANGELOG.md",
|
|
17
|
+
"docs/**/*.md"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
|
19
20
|
"dev": "tsx src/cli.ts",
|
|
@@ -35,9 +36,21 @@
|
|
|
35
36
|
"validate": "npm run check && npm test && npm run test:coverage && npm run test:perf"
|
|
36
37
|
},
|
|
37
38
|
"keywords": [
|
|
39
|
+
"claude",
|
|
40
|
+
"fabric",
|
|
41
|
+
"forge",
|
|
38
42
|
"mcp",
|
|
43
|
+
"mcp-server",
|
|
39
44
|
"minecraft",
|
|
40
|
-
"modding"
|
|
45
|
+
"minecraft-modding",
|
|
46
|
+
"mixin",
|
|
47
|
+
"modding",
|
|
48
|
+
"model-context-protocol",
|
|
49
|
+
"mojang-mappings",
|
|
50
|
+
"neoforge",
|
|
51
|
+
"nodejs",
|
|
52
|
+
"typescript",
|
|
53
|
+
"yarn-mappings"
|
|
41
54
|
],
|
|
42
55
|
"author": "adhi-jp",
|
|
43
56
|
"license": "MIT",
|