@adhisang/minecraft-modding-mcp 7.0.0-rc.2 → 7.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 +50 -3
- package/README.md +1 -1
- package/dist/artifact-identity.d.ts +130 -0
- package/dist/artifact-identity.js +142 -0
- package/dist/cache-registry.d.ts +16 -0
- package/dist/cache-registry.js +78 -10
- package/dist/config.js +2 -2
- package/dist/entry-tools/analyze-mod-service.d.ts +4 -4
- package/dist/entry-tools/analyze-symbol-service.d.ts +2 -2
- package/dist/entry-tools/entry-tool-schema.d.ts +2 -2
- package/dist/json-rpc-framing.d.ts +20 -0
- package/dist/json-rpc-framing.js +155 -23
- package/dist/mapping/loaders/tiny-maven.d.ts +9 -0
- package/dist/mapping/loaders/tiny-maven.js +10 -2
- package/dist/minecraft-explorer-service.js +2 -2
- package/dist/path-resolver.d.ts +13 -2
- package/dist/path-resolver.js +12 -1
- package/dist/repo-downloader.d.ts +19 -7
- package/dist/repo-downloader.js +123 -3
- package/dist/source/artifact-resolver.js +14 -6
- package/dist/source/class-source.js +56 -1
- package/dist/source-resolver.d.ts +0 -1
- package/dist/source-resolver.js +25 -94
- package/dist/stdio-supervisor.d.ts +150 -4
- package/dist/stdio-supervisor.js +710 -68
- package/dist/storage/db.js +5 -1
- package/dist/tool-schemas.d.ts +55 -55
- package/dist/types.d.ts +18 -1
- package/docs/tool-reference.md +24 -12
- package/package.json +1 -1
package/dist/storage/db.js
CHANGED
|
@@ -135,7 +135,11 @@ export function openDatabase(config, logger = buildDefaultLogger()) {
|
|
|
135
135
|
path: config.sqlitePath,
|
|
136
136
|
reason: errorMessage
|
|
137
137
|
});
|
|
138
|
-
throw
|
|
138
|
+
throw createError({
|
|
139
|
+
code: ERROR_CODES.DB_FAILURE,
|
|
140
|
+
message: `Failed to open SQLite database at ${config.sqlitePath}: ${errorMessage}`,
|
|
141
|
+
details: { sqlitePath: config.sqlitePath, reason: caughtError?.code }
|
|
142
|
+
});
|
|
139
143
|
}
|
|
140
144
|
// The rebuild runs INSIDE the handler for the failure it is recovering
|
|
141
145
|
// from, so it needs a guard of its own: without one a throw from here left
|
package/dist/tool-schemas.d.ts
CHANGED
|
@@ -258,10 +258,10 @@ export declare const resolveArtifactShape: {
|
|
|
258
258
|
full: "full";
|
|
259
259
|
}>>;
|
|
260
260
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
261
|
-
entries: "entries";
|
|
262
261
|
workspace: "workspace";
|
|
263
|
-
|
|
262
|
+
entries: "entries";
|
|
264
263
|
source: "source";
|
|
264
|
+
candidates: "candidates";
|
|
265
265
|
warnings: "warnings";
|
|
266
266
|
registry: "registry";
|
|
267
267
|
preview: "preview";
|
|
@@ -335,10 +335,10 @@ export declare const resolveArtifactSchema: z.ZodObject<{
|
|
|
335
335
|
full: "full";
|
|
336
336
|
}>>;
|
|
337
337
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
338
|
-
entries: "entries";
|
|
339
338
|
workspace: "workspace";
|
|
340
|
-
|
|
339
|
+
entries: "entries";
|
|
341
340
|
source: "source";
|
|
341
|
+
candidates: "candidates";
|
|
342
342
|
warnings: "warnings";
|
|
343
343
|
registry: "registry";
|
|
344
344
|
preview: "preview";
|
|
@@ -426,10 +426,10 @@ export declare const getClassSourceShape: {
|
|
|
426
426
|
full: "full";
|
|
427
427
|
}>>;
|
|
428
428
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
429
|
-
entries: "entries";
|
|
430
429
|
workspace: "workspace";
|
|
431
|
-
|
|
430
|
+
entries: "entries";
|
|
432
431
|
source: "source";
|
|
432
|
+
candidates: "candidates";
|
|
433
433
|
warnings: "warnings";
|
|
434
434
|
registry: "registry";
|
|
435
435
|
preview: "preview";
|
|
@@ -518,10 +518,10 @@ export declare const getClassSourceSchema: z.ZodObject<{
|
|
|
518
518
|
full: "full";
|
|
519
519
|
}>>;
|
|
520
520
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
521
|
-
entries: "entries";
|
|
522
521
|
workspace: "workspace";
|
|
523
|
-
|
|
522
|
+
entries: "entries";
|
|
524
523
|
source: "source";
|
|
524
|
+
candidates: "candidates";
|
|
525
525
|
warnings: "warnings";
|
|
526
526
|
registry: "registry";
|
|
527
527
|
preview: "preview";
|
|
@@ -615,10 +615,10 @@ export declare const getClassMembersShape: {
|
|
|
615
615
|
full: "full";
|
|
616
616
|
}>>;
|
|
617
617
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
618
|
-
entries: "entries";
|
|
619
618
|
workspace: "workspace";
|
|
620
|
-
|
|
619
|
+
entries: "entries";
|
|
621
620
|
source: "source";
|
|
621
|
+
candidates: "candidates";
|
|
622
622
|
warnings: "warnings";
|
|
623
623
|
registry: "registry";
|
|
624
624
|
preview: "preview";
|
|
@@ -713,10 +713,10 @@ export declare const getClassMembersSchema: z.ZodObject<{
|
|
|
713
713
|
full: "full";
|
|
714
714
|
}>>;
|
|
715
715
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
716
|
-
entries: "entries";
|
|
717
716
|
workspace: "workspace";
|
|
718
|
-
|
|
717
|
+
entries: "entries";
|
|
719
718
|
source: "source";
|
|
719
|
+
candidates: "candidates";
|
|
720
720
|
warnings: "warnings";
|
|
721
721
|
registry: "registry";
|
|
722
722
|
preview: "preview";
|
|
@@ -935,10 +935,10 @@ export declare const batchClassSourceShape: {
|
|
|
935
935
|
full: "full";
|
|
936
936
|
}>>;
|
|
937
937
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
938
|
-
entries: "entries";
|
|
939
938
|
workspace: "workspace";
|
|
940
|
-
|
|
939
|
+
entries: "entries";
|
|
941
940
|
source: "source";
|
|
941
|
+
candidates: "candidates";
|
|
942
942
|
warnings: "warnings";
|
|
943
943
|
registry: "registry";
|
|
944
944
|
preview: "preview";
|
|
@@ -1027,10 +1027,10 @@ export declare const batchClassSourceSchema: z.ZodObject<{
|
|
|
1027
1027
|
full: "full";
|
|
1028
1028
|
}>>;
|
|
1029
1029
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1030
|
-
entries: "entries";
|
|
1031
1030
|
workspace: "workspace";
|
|
1032
|
-
|
|
1031
|
+
entries: "entries";
|
|
1033
1032
|
source: "source";
|
|
1033
|
+
candidates: "candidates";
|
|
1034
1034
|
warnings: "warnings";
|
|
1035
1035
|
registry: "registry";
|
|
1036
1036
|
preview: "preview";
|
|
@@ -1135,10 +1135,10 @@ export declare const batchClassMembersShape: {
|
|
|
1135
1135
|
signatures: "signatures";
|
|
1136
1136
|
}>>;
|
|
1137
1137
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1138
|
-
entries: "entries";
|
|
1139
1138
|
workspace: "workspace";
|
|
1140
|
-
|
|
1139
|
+
entries: "entries";
|
|
1141
1140
|
source: "source";
|
|
1141
|
+
candidates: "candidates";
|
|
1142
1142
|
warnings: "warnings";
|
|
1143
1143
|
registry: "registry";
|
|
1144
1144
|
preview: "preview";
|
|
@@ -1230,10 +1230,10 @@ export declare const batchClassMembersSchema: z.ZodObject<{
|
|
|
1230
1230
|
signatures: "signatures";
|
|
1231
1231
|
}>>;
|
|
1232
1232
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1233
|
-
entries: "entries";
|
|
1234
1233
|
workspace: "workspace";
|
|
1235
|
-
|
|
1234
|
+
entries: "entries";
|
|
1236
1235
|
source: "source";
|
|
1236
|
+
candidates: "candidates";
|
|
1237
1237
|
warnings: "warnings";
|
|
1238
1238
|
registry: "registry";
|
|
1239
1239
|
preview: "preview";
|
|
@@ -1339,10 +1339,10 @@ export declare const batchSymbolExistsShape: {
|
|
|
1339
1339
|
full: "full";
|
|
1340
1340
|
}>>;
|
|
1341
1341
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1342
|
-
entries: "entries";
|
|
1343
1342
|
workspace: "workspace";
|
|
1344
|
-
|
|
1343
|
+
entries: "entries";
|
|
1345
1344
|
source: "source";
|
|
1345
|
+
candidates: "candidates";
|
|
1346
1346
|
warnings: "warnings";
|
|
1347
1347
|
registry: "registry";
|
|
1348
1348
|
preview: "preview";
|
|
@@ -1425,10 +1425,10 @@ export declare const batchSymbolExistsSchema: z.ZodObject<{
|
|
|
1425
1425
|
full: "full";
|
|
1426
1426
|
}>>;
|
|
1427
1427
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1428
|
-
entries: "entries";
|
|
1429
1428
|
workspace: "workspace";
|
|
1430
|
-
|
|
1429
|
+
entries: "entries";
|
|
1431
1430
|
source: "source";
|
|
1431
|
+
candidates: "candidates";
|
|
1432
1432
|
warnings: "warnings";
|
|
1433
1433
|
registry: "registry";
|
|
1434
1434
|
preview: "preview";
|
|
@@ -1517,10 +1517,10 @@ export declare const batchMappingsShape: {
|
|
|
1517
1517
|
full: "full";
|
|
1518
1518
|
}>>;
|
|
1519
1519
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1520
|
-
entries: "entries";
|
|
1521
1520
|
workspace: "workspace";
|
|
1522
|
-
|
|
1521
|
+
entries: "entries";
|
|
1523
1522
|
source: "source";
|
|
1523
|
+
candidates: "candidates";
|
|
1524
1524
|
warnings: "warnings";
|
|
1525
1525
|
registry: "registry";
|
|
1526
1526
|
preview: "preview";
|
|
@@ -1590,10 +1590,10 @@ export declare const batchMappingsSchema: z.ZodObject<{
|
|
|
1590
1590
|
full: "full";
|
|
1591
1591
|
}>>;
|
|
1592
1592
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1593
|
-
entries: "entries";
|
|
1594
1593
|
workspace: "workspace";
|
|
1595
|
-
|
|
1594
|
+
entries: "entries";
|
|
1596
1595
|
source: "source";
|
|
1596
|
+
candidates: "candidates";
|
|
1597
1597
|
warnings: "warnings";
|
|
1598
1598
|
registry: "registry";
|
|
1599
1599
|
preview: "preview";
|
|
@@ -1789,10 +1789,10 @@ export declare const searchClassSourceShape: {
|
|
|
1789
1789
|
full: "full";
|
|
1790
1790
|
}>>;
|
|
1791
1791
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1792
|
-
entries: "entries";
|
|
1793
1792
|
workspace: "workspace";
|
|
1794
|
-
|
|
1793
|
+
entries: "entries";
|
|
1795
1794
|
source: "source";
|
|
1795
|
+
candidates: "candidates";
|
|
1796
1796
|
warnings: "warnings";
|
|
1797
1797
|
registry: "registry";
|
|
1798
1798
|
preview: "preview";
|
|
@@ -1891,10 +1891,10 @@ export declare const searchClassSourceSchema: z.ZodObject<{
|
|
|
1891
1891
|
full: "full";
|
|
1892
1892
|
}>>;
|
|
1893
1893
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
1894
|
-
entries: "entries";
|
|
1895
1894
|
workspace: "workspace";
|
|
1896
|
-
|
|
1895
|
+
entries: "entries";
|
|
1897
1896
|
source: "source";
|
|
1897
|
+
candidates: "candidates";
|
|
1898
1898
|
warnings: "warnings";
|
|
1899
1899
|
registry: "registry";
|
|
1900
1900
|
preview: "preview";
|
|
@@ -2022,10 +2022,10 @@ export declare const listArtifactFilesShape: {
|
|
|
2022
2022
|
full: "full";
|
|
2023
2023
|
}>>;
|
|
2024
2024
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2025
|
-
entries: "entries";
|
|
2026
2025
|
workspace: "workspace";
|
|
2027
|
-
|
|
2026
|
+
entries: "entries";
|
|
2028
2027
|
source: "source";
|
|
2028
|
+
candidates: "candidates";
|
|
2029
2029
|
warnings: "warnings";
|
|
2030
2030
|
registry: "registry";
|
|
2031
2031
|
preview: "preview";
|
|
@@ -2087,10 +2087,10 @@ export declare const listArtifactFilesSchema: z.ZodObject<{
|
|
|
2087
2087
|
full: "full";
|
|
2088
2088
|
}>>;
|
|
2089
2089
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2090
|
-
entries: "entries";
|
|
2091
2090
|
workspace: "workspace";
|
|
2092
|
-
|
|
2091
|
+
entries: "entries";
|
|
2093
2092
|
source: "source";
|
|
2093
|
+
candidates: "candidates";
|
|
2094
2094
|
warnings: "warnings";
|
|
2095
2095
|
registry: "registry";
|
|
2096
2096
|
preview: "preview";
|
|
@@ -2233,10 +2233,10 @@ export declare const findMappingShape: {
|
|
|
2233
2233
|
full: "full";
|
|
2234
2234
|
}>>;
|
|
2235
2235
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2236
|
-
entries: "entries";
|
|
2237
2236
|
workspace: "workspace";
|
|
2238
|
-
|
|
2237
|
+
entries: "entries";
|
|
2239
2238
|
source: "source";
|
|
2239
|
+
candidates: "candidates";
|
|
2240
2240
|
warnings: "warnings";
|
|
2241
2241
|
registry: "registry";
|
|
2242
2242
|
preview: "preview";
|
|
@@ -2305,10 +2305,10 @@ export declare const findMappingSchema: z.ZodObject<{
|
|
|
2305
2305
|
full: "full";
|
|
2306
2306
|
}>>;
|
|
2307
2307
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2308
|
-
entries: "entries";
|
|
2309
2308
|
workspace: "workspace";
|
|
2310
|
-
|
|
2309
|
+
entries: "entries";
|
|
2311
2310
|
source: "source";
|
|
2311
|
+
candidates: "candidates";
|
|
2312
2312
|
warnings: "warnings";
|
|
2313
2313
|
registry: "registry";
|
|
2314
2314
|
preview: "preview";
|
|
@@ -2360,10 +2360,10 @@ export declare const resolveMethodMappingExactShape: {
|
|
|
2360
2360
|
full: "full";
|
|
2361
2361
|
}>>;
|
|
2362
2362
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2363
|
-
entries: "entries";
|
|
2364
2363
|
workspace: "workspace";
|
|
2365
|
-
|
|
2364
|
+
entries: "entries";
|
|
2366
2365
|
source: "source";
|
|
2366
|
+
candidates: "candidates";
|
|
2367
2367
|
warnings: "warnings";
|
|
2368
2368
|
registry: "registry";
|
|
2369
2369
|
preview: "preview";
|
|
@@ -2415,10 +2415,10 @@ export declare const resolveMethodMappingExactSchema: z.ZodObject<{
|
|
|
2415
2415
|
full: "full";
|
|
2416
2416
|
}>>;
|
|
2417
2417
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2418
|
-
entries: "entries";
|
|
2419
2418
|
workspace: "workspace";
|
|
2420
|
-
|
|
2419
|
+
entries: "entries";
|
|
2421
2420
|
source: "source";
|
|
2421
|
+
candidates: "candidates";
|
|
2422
2422
|
warnings: "warnings";
|
|
2423
2423
|
registry: "registry";
|
|
2424
2424
|
preview: "preview";
|
|
@@ -2507,10 +2507,10 @@ export declare const resolveWorkspaceSymbolShape: {
|
|
|
2507
2507
|
full: "full";
|
|
2508
2508
|
}>>;
|
|
2509
2509
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2510
|
-
entries: "entries";
|
|
2511
2510
|
workspace: "workspace";
|
|
2512
|
-
|
|
2511
|
+
entries: "entries";
|
|
2513
2512
|
source: "source";
|
|
2513
|
+
candidates: "candidates";
|
|
2514
2514
|
warnings: "warnings";
|
|
2515
2515
|
registry: "registry";
|
|
2516
2516
|
preview: "preview";
|
|
@@ -2562,10 +2562,10 @@ export declare const resolveWorkspaceSymbolSchema: z.ZodObject<{
|
|
|
2562
2562
|
full: "full";
|
|
2563
2563
|
}>>;
|
|
2564
2564
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2565
|
-
entries: "entries";
|
|
2566
2565
|
workspace: "workspace";
|
|
2567
|
-
|
|
2566
|
+
entries: "entries";
|
|
2568
2567
|
source: "source";
|
|
2568
|
+
candidates: "candidates";
|
|
2569
2569
|
warnings: "warnings";
|
|
2570
2570
|
registry: "registry";
|
|
2571
2571
|
preview: "preview";
|
|
@@ -2624,10 +2624,10 @@ export declare const checkSymbolExistsShape: {
|
|
|
2624
2624
|
full: "full";
|
|
2625
2625
|
}>>;
|
|
2626
2626
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2627
|
-
entries: "entries";
|
|
2628
2627
|
workspace: "workspace";
|
|
2629
|
-
|
|
2628
|
+
entries: "entries";
|
|
2630
2629
|
source: "source";
|
|
2630
|
+
candidates: "candidates";
|
|
2631
2631
|
warnings: "warnings";
|
|
2632
2632
|
registry: "registry";
|
|
2633
2633
|
preview: "preview";
|
|
@@ -2686,10 +2686,10 @@ export declare const checkSymbolExistsSchema: z.ZodObject<{
|
|
|
2686
2686
|
full: "full";
|
|
2687
2687
|
}>>;
|
|
2688
2688
|
include: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2689
|
-
entries: "entries";
|
|
2690
2689
|
workspace: "workspace";
|
|
2691
|
-
|
|
2690
|
+
entries: "entries";
|
|
2692
2691
|
source: "source";
|
|
2692
|
+
candidates: "candidates";
|
|
2693
2693
|
warnings: "warnings";
|
|
2694
2694
|
registry: "registry";
|
|
2695
2695
|
preview: "preview";
|
|
@@ -3125,8 +3125,8 @@ export declare const modSearchTypeSchema: z.ZodEnum<{
|
|
|
3125
3125
|
class: "class";
|
|
3126
3126
|
field: "field";
|
|
3127
3127
|
method: "method";
|
|
3128
|
-
all: "all";
|
|
3129
3128
|
content: "content";
|
|
3129
|
+
all: "all";
|
|
3130
3130
|
}>;
|
|
3131
3131
|
export declare const searchModSourceShape: {
|
|
3132
3132
|
jarPath: z.ZodString;
|
|
@@ -3135,8 +3135,8 @@ export declare const searchModSourceShape: {
|
|
|
3135
3135
|
class: "class";
|
|
3136
3136
|
field: "field";
|
|
3137
3137
|
method: "method";
|
|
3138
|
-
all: "all";
|
|
3139
3138
|
content: "content";
|
|
3139
|
+
all: "all";
|
|
3140
3140
|
}>>;
|
|
3141
3141
|
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
3142
3142
|
};
|
|
@@ -3147,8 +3147,8 @@ export declare const searchModSourceSchema: z.ZodObject<{
|
|
|
3147
3147
|
class: "class";
|
|
3148
3148
|
field: "field";
|
|
3149
3149
|
method: "method";
|
|
3150
|
-
all: "all";
|
|
3151
3150
|
content: "content";
|
|
3151
|
+
all: "all";
|
|
3152
3152
|
}>>;
|
|
3153
3153
|
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
3154
3154
|
}, z.core.$strip>;
|
package/dist/types.d.ts
CHANGED
|
@@ -182,9 +182,26 @@ export interface Config {
|
|
|
182
182
|
remapMaxMemoryMb: number;
|
|
183
183
|
decompileMaxMemoryMb: number;
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
/**
|
|
186
|
+
* A jar's filesystem stat, stamped. NOT an artifact identity: nothing here is
|
|
187
|
+
* read from the jar's bytes, so a `touch` moves it and a byte-for-byte
|
|
188
|
+
* replacement of the same length at the same mtime does not.
|
|
189
|
+
*
|
|
190
|
+
* Artifact identity lives in `src/artifact-identity.ts`. This shape feeds the
|
|
191
|
+
* `jarSignature` field `get-project-context` publishes, and that field's
|
|
192
|
+
* stat-based value is part of the tool's output contract.
|
|
193
|
+
*/
|
|
194
|
+
export interface JarStatStamp {
|
|
186
195
|
sourcePath: string;
|
|
196
|
+
/**
|
|
197
|
+
* sha256 of `jar|<resolved path>|<mtimeMs>:<size>`.
|
|
198
|
+
*
|
|
199
|
+
* The name is inherited and overstates it: this is not the artifactId of
|
|
200
|
+
* anything. Its only consumer is the `jarSignature` field in
|
|
201
|
+
* `src/minecraft-explorer-service.ts`.
|
|
202
|
+
*/
|
|
187
203
|
sourceArtifactId: string;
|
|
204
|
+
/** The `<truncated mtimeMs>:<size>` stamp itself. */
|
|
188
205
|
signature: string;
|
|
189
206
|
signatureParts: {
|
|
190
207
|
mtimeMs: number;
|
package/docs/tool-reference.md
CHANGED
|
@@ -142,7 +142,7 @@ Artifact-relative file read from a workspace:
|
|
|
142
142
|
| target shape | When to use | Required input | Result |
|
|
143
143
|
|---|---|---|---|
|
|
144
144
|
| `{ 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`. |
|
|
145
|
-
| `{ 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, so a non-obfuscated mapping request is honored only if a source-backed jar can supply it. If a source-backed jar is available, the resolver returns `mappingApplied` equal to the requested mapping with `qualityFlags` including `"source-backed"`, and no warning is added.
|
|
145
|
+
| `{ 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, so a non-obfuscated mapping request is honored only if a source-backed jar can supply it. If a source-backed jar is available, the resolver returns `mappingApplied` equal to the requested mapping with `qualityFlags` including `"source-backed"`, and no warning is added. If none is, that same non-obfuscated request comes back with `mappingApplied: "obfuscated"` and `qualityFlags` including `"dependency-mapping-unverified"`, plus a warning that the caller must validate symbol availability. An explicit `mapping: "obfuscated"` request never takes that branch: it passes through as `mappingApplied: "obfuscated"` with `qualityFlags` including `"source-backed"` (or `"decompiled"`), and never carries `"dependency-mapping-unverified"`. Resolution metadata appears on `provenance.dependencyResolution`. |
|
|
146
146
|
|
|
147
147
|
### Inspecting a Fabric / loader dependency like vanilla
|
|
148
148
|
|
|
@@ -161,11 +161,18 @@ the same way you read vanilla, pass a `dependency` target straight to
|
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
Use an explicit `"version"` instead of `versionFromProject` when you already
|
|
164
|
-
know it. Because dependency JARs are not remapped,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
know it. Because dependency JARs are not binary-remapped, a non-obfuscated
|
|
165
|
+
mapping request is honored only when a source-backed jar can supply it: there
|
|
166
|
+
`mappingApplied` equals the requested mapping and `qualityFlags` includes
|
|
167
|
+
`"source-backed"`. When no source-backed jar can supply it, that same
|
|
168
|
+
non-obfuscated request comes back in the dependency's own namespace with
|
|
169
|
+
`mappingApplied: "obfuscated"` and `qualityFlags` including
|
|
170
|
+
`"dependency-mapping-unverified"`, and the names are the JAR's compiled names.
|
|
171
|
+
A request that asks for `"obfuscated"` outright is a separate branch: it passes
|
|
172
|
+
through as `mappingApplied: "obfuscated"` with `"source-backed"` or
|
|
173
|
+
`"decompiled"`, never with `"dependency-mapping-unverified"`.
|
|
174
|
+
For repeated lookups against the same dependency, call `resolve-artifact` once
|
|
175
|
+
and reuse the returned `artifactId` via `target: { kind: "artifact", artifactId }`.
|
|
169
176
|
|
|
170
177
|
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`.
|
|
171
178
|
|
|
@@ -382,6 +389,7 @@ Because only `issueOrigin` is overridable, the two axes can disagree, and one pa
|
|
|
382
389
|
- `get-class-members` — every `target.kind` except `"jar"`, `{ "kind": "artifact", "artifactId": ... }` included. An `artifactId` is an opaque handle: its holder cannot tell from it whether the artifact has a binary jar, and cannot re-resolve it either, since `resolve-artifact` does not accept an `artifactId`. Only `target: { "kind": "jar", ... }`, where the caller named the exact jar, reports `issueOrigin: "code_issue"`.
|
|
383
390
|
- `batch-class-members` — same rule, applied once to the shared target and repeated on every failed entry. Its target schema has no `"artifact"` kind at all, so only `"jar"` reports `code_issue`.
|
|
384
391
|
- `inspect-minecraft` `task="class-members"` — same rule once more: only a subject whose artifact reference is `target: { "kind": "jar", ... }` reports `code_issue`. A subject naming a resolved artifact (`{ "type": "resolved-id", "artifactId": ... }`) reports `tool_issue`, matching the equivalent `get-class-members` target: it is the same opaque handle from an earlier resolve, and wrapping it in a subject does not give the caller any way to vet the artifact's binary jar.
|
|
392
|
+
- `verify-mixin-target` — the same rule on its own `target`: the tool reads the target's members from bytecode, so every `target.kind` except `"jar"` reports `tool_issue`. Like `batch-class-members`, its target schema has no `"artifact"` kind at all, so only `"jar"` reports `code_issue`.
|
|
385
393
|
|
|
386
394
|
To check whether an artifact carries a binary jar before retrying, call `manage-cache` with `action: "inspect"`, `selector: { "artifactId": ... }` and `include: ["cacheEntries"]`. The `cacheEntries` block reports that artifact's stored `meta.binaryJarPath` — read from the same row the members lookup reads, and absent when the row has none. The `include` is not optional: `manage-cache` defaults to `detail: "summary"`, which drops `cacheEntries` entirely, so without it the reply never shows the field (`detail: "standard"` or `"full"` opts the block back in as well).
|
|
387
395
|
|
|
@@ -443,7 +451,7 @@ These environment variables are read once at worker startup and provide rollback
|
|
|
443
451
|
| `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. |
|
|
444
452
|
| `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. |
|
|
445
453
|
| `loom.cache.found` | A Loom (Fabric / Quilt) cache directory exists under the workspace, `gradleUserHome`, or the process `GRADLE_USER_HOME`. It is 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. |
|
|
446
|
-
| `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`). |
|
|
454
|
+
| `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. It does read the runtime jar's bytes to derive the reported `artifactId`, which is composed from that digest and the jar's symlink-resolved path; repeat probes of the same jar in one process reuse the digest. | `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`). |
|
|
447
455
|
| `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`. |
|
|
448
456
|
| `accessWideners.validated` | At least one Access Widener file was discovered AND every validation completed without throwing. | `counts: { ok, invalid }`. | Same rules as `mixins.validated`. |
|
|
449
457
|
| `accessTransformers.validated` | At least one Access Transformer file was discovered AND every validation completed without throwing. | `counts: { ok, invalid }`. | Same rules as `mixins.validated`. |
|
|
@@ -481,7 +489,7 @@ MCP resources provide URI-based access to Minecraft data for clients that suppor
|
|
|
481
489
|
| `find-mapping` | `mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{name}` | Look up a **class** mapping between two naming namespaces. The URI carries no `owner`, so use `find-member-mapping` (or the `find-mapping` tool) for field/method lookups. |
|
|
482
490
|
| `find-member-mapping` | `mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{owner}/{name}` | Look up a **field or method** mapping, including the `owner` class the member belongs to. For exact method overload resolution use the `find-mapping` tool with a `descriptor`. |
|
|
483
491
|
| `class-members` | `mc://artifact/{artifactId}/members/{className}` | List constructors, methods, and fields for a class |
|
|
484
|
-
| `artifact-metadata` | `mc://artifact/{artifactId}` | Metadata for a previously resolved artifact |
|
|
492
|
+
| `artifact-metadata` | `mc://artifact/{artifactId}` | Metadata for a previously resolved artifact. Its `artifactSignature` field carries the artifact's identity signature: a bare 64-character sha256 hex digest of the identified jar's bytes, or that digest followed by `:decompile`. A client that pattern-matched the older `<mtimeMs>:<size>` shape no longer matches. |
|
|
485
493
|
|
|
486
494
|
`versions-list`, `runtime-metrics`, `find-mapping`, `find-member-mapping`, `class-source-json`, `class-members`, and `artifact-metadata` return structured JSON envelopes on success (`{ result, meta }`) and failure (`{ error, meta }`).
|
|
487
495
|
|
|
@@ -524,7 +532,7 @@ The supervisor caches the completed `initialize` / `notifications/initialized` p
|
|
|
524
532
|
The legacy wire contract is byte-compatible with the pre-migration (SDK v1) server, with these recorded exceptions:
|
|
525
533
|
|
|
526
534
|
- `tools/call` with `arguments` omitted reaches the application validator as `{}`. Three outcome arms: (a) input-free tools succeed (`get-runtime-metrics`); (b) required-field schemas answer per-field `ERR_INVALID_INPUT` (`analyze-mod`); (c) a `{}`-accepting schema whose handler requires input answers that tool's own handler-level ProblemDetails — `json-to-nbt` answers `ERR_NBT_INVALID_TYPED_JSON` (status 400, `isError: true`) instead of the pre-migration validation-layer `ERR_INVALID_INPUT`.
|
|
527
|
-
- Legacy `tools/list` entries omit the v1-only `execution: {"taskSupport":"forbidden"}` field (SDK v2 does not emit it);
|
|
535
|
+
- Legacy `tools/list` entries omit the v1-only `execution: {"taskSupport":"forbidden"}` field (SDK v2 does not emit it); the migration introduced no other drift, and the `inputSchema` bytes are served verbatim from the frozen pre-migration contracts in `tests/fixtures/premigration/tool-contracts/` (through the generated `src/v1-parity-schemas.ts`, which `tools/list` advertises in preference to the zod shape). Those frozen contracts are deliberately extended when a tool genuinely gains a parameter in a later release — 7.0.0-rc.2 added `projectPath` to four of the flat-`artifactId` tools — so "identical to the pre-migration snapshots" describes the migration, not a promise that a tool's schema never changes across releases.
|
|
528
536
|
- An unknown or disabled tool is answered immediately at the supervisor, before queueing: the reply bytes are identical to v1, but the reply consumes no queue slot and no worker round-trip, so reply ordering and queue-overflow outcomes can differ from v1 under concurrent load.
|
|
529
537
|
- The unmatched-resource-URI error keeps the raw JSON-RPC `-32602` code, but its message changed from the pre-migration `MCP error -32602: Resource <uri> not found` to `Resource not found: <uri>`, and the error carries a `data.uri` field (SDK v2 wording).
|
|
530
538
|
- The `initialize` result advertises `resources: { listChanged: false }` and `tools: { listChanged: false }`, where the pre-migration server advertised `true` for both. The suppression is deliberate and is NOT era-gated — both eras read one `getCapabilities()`, so gating it would leave one process advertising two different contracts; the reasoning is under the modern-era capability paragraph below. Every other byte of the `initialize` result is unchanged.
|
|
@@ -616,11 +624,13 @@ Notification variants: a modern-era notification without a valid claim (for exam
|
|
|
616
624
|
|
|
617
625
|
### Synthetic terminal responses and retry semantics
|
|
618
626
|
|
|
619
|
-
Supervisor-synthesized replies (queue overflow, worker restart, `validate-project` timeout, startup failure — shapes in `## Errors` and `## Meta fields`) are FINAL for that request instance: a late worker answer for the same id is discarded, so a client sees exactly one response per id. Retrying with the SAME id after a synthetic terminal reply is legal — the retry re-forwards and clears the finality bookkeeping. Era rejections synthesize no such finality (they answer without forwarding), and dropped notifications receive no response at all. Modern-era synthetic results are decorated like ordinary modern results (`resultType: "complete"` plus the identity `_meta` echo); legacy synthetic results remain byte-compatible with the pre-migration shapes.
|
|
627
|
+
Supervisor-synthesized replies (queue overflow, worker restart, `validate-project` timeout, startup failure — shapes in `## Errors` and `## Meta fields`) are FINAL for that request instance: a late worker answer for the same id is discarded, so a client sees exactly one response per id. A raw JSON-RPC `-32603` whose message begins "MCP supervisor failed to" belongs to the same class: the supervisor emits one when an internal fault stops it from admitting a request, dispatching a queued one, or handing a worker response back to the client, and it is terminal and discards the worker's own later answer in exactly the same way. One case where the supervisor deliberately sends nothing: when its own cleanup after such a fault cannot prove the request was removed, it reports and stands down rather than risk a second reply for one id. Only `validate-project` carries a deadline of its own, so any other request left in that state waits for the worker to exit. Retrying with the SAME id after a synthetic terminal reply is legal — the retry re-forwards and clears the finality bookkeeping. Era rejections synthesize no such finality (they answer without forwarding), and dropped notifications receive no response at all. Modern-era synthetic results are decorated like ordinary modern results (`resultType: "complete"` plus the identity `_meta` echo); legacy synthetic results remain byte-compatible with the pre-migration shapes.
|
|
620
628
|
|
|
621
629
|
### Framing
|
|
622
630
|
|
|
623
|
-
Standard framing is newline-delimited JSON-RPC (the MCP stdio standard). `Content-Length` header framing is a LOCAL, NONSTANDARD compatibility extension — it is not part of MCP. The reader auto-detects both and may switch mid-stream; every response, including synthetic replies and replies released after a worker restart, uses the framing of the request it answers. `MCP_MAX_FRAME_BYTES` bounds accepted frames (see `## Environment Variables`).
|
|
631
|
+
Standard framing is newline-delimited JSON-RPC (the MCP stdio standard). `Content-Length` header framing is a LOCAL, NONSTANDARD compatibility extension — it is not part of MCP. The reader auto-detects both and may switch mid-stream; every response, including synthetic replies and replies released after a worker restart, uses the framing of the request it answers. `MCP_MAX_FRAME_BYTES` bounds accepted frames (see `## Environment Variables`), and a header block is capped at 8 KiB.
|
|
632
|
+
|
|
633
|
+
A `Content-Length` header block ends at its FIRST EMPTY LINE. A header line ends at an LF, and a CR immediately before that LF belongs to the terminator, so all four combinations a peer can write — `\r\n\r\n`, `\n\n`, `\n\r\n` and `\r\n\n` — delimit the block, and no `\r\n\r\n` sequence inside the JSON body can be mistaken for one. An EXTRA empty line after that terminator is body, not header: the peer's declared `Content-Length` does not count it, so the body window opens two or three bytes early and normally runs off the end of the JSON. That is a body-parse failure, which is framing-fatal — the session ends and the frames behind it are lost. Such a frame is malformed, but the outcome is worth knowing: it is not recovered from. It is not certain to fail, either. The window is shifted rather than mis-sized, so a declared length that happens to count trailing whitespace can absorb the shift exactly and the frame is delivered normally; the reader never detects the extra blank line, only where the bytes fall.
|
|
624
634
|
|
|
625
635
|
### Adopted-policy note
|
|
626
636
|
|
|
@@ -708,7 +718,9 @@ Path-based overrides treat blank values and the literal strings `undefined` and
|
|
|
708
718
|
| `MCP_MAPPING_SOURCE_PRIORITY` | `loom-first` | Mapping source priority (`loom-first` or `maven-first`) |
|
|
709
719
|
| `MCP_VERSION_MANIFEST_URL` | Mojang manifest URL | Override the Minecraft version manifest endpoint |
|
|
710
720
|
|
|
711
|
-
Jars downloaded from the repositories in `MCP_SOURCE_REPOS` are cached under `MCP_CACHE_DIR` and identified by a sha256 of their bytes, so the same jar keeps one `artifactId` no matter which repository served it. (Minecraft version jars and mapping archives share that cache directory but
|
|
721
|
+
Jars downloaded from the repositories in `MCP_SOURCE_REPOS` are cached under `MCP_CACHE_DIR` and identified by a sha256 of their bytes, so the same jar keeps one `artifactId` no matter which repository served it. (Minecraft version jars and mapping archives share that cache directory but sit outside this URL-keyed download-cache identity; a Minecraft version jar's own `artifactId` is covered by the jar rule below.) Jars served from the local stores — `MCP_LOCAL_M2` and the Gradle dependency cache — are identified from their bytes the same way whenever they are reached through a Maven coordinate (`target.kind="dependency"` and `target.kind="coordinate"`), so touching one, or restoring byte-identical contents, keeps its `artifactId`. A jar named directly by path (`target.kind="jar"`) is identified from its bytes as well, and so is a Minecraft runtime jar, because `target.kind="version"` and `target.kind="workspace"` both reach one through that same route. The digest is taken over whichever jar the id is actually about: the named jar's own bytes; or, when the named jar carries no Java sources and its same-name `-sources.jar` sibling supplies them, that sibling's bytes; or, when neither carries sources and the jar goes to the decompiler, the binary jar's bytes under a separate `decompile` identity. The jar's symlink-resolved path still enters the id beside the digest, so one file reached through two names is one artifact, while two byte-identical jars at two real paths stay two artifacts. One bound on "identified from its bytes": within a single server process the digest for a path is reused while that file's size, modification time, inode and inode-change time all still match, so on a filesystem that does not advance the inode-change time on a write, an in-place replacement of the same length whose modification time was restored can be answered from the earlier digest until that memo entry is evicted.
|
|
722
|
+
|
|
723
|
+
Whether a cached jar is re-checked depends on the coordinate's **version**, not on which repository serves it. A release version is served from cache with no request. A version ending in `-SNAPSHOT` is treated as mutable, as Maven defines it, and is re-checked against every configured repository — including the defaults: where the cached copy recorded an `ETag` or `Last-Modified` the check is a conditional request and an unchanged answer costs no transfer, otherwise the jar is transferred again. A republished jar replaces the cached one and yields a new `artifactId`. If the check cannot be completed — anything short of a definitive answer, including unreachable, a timeout, 5xx, 429, or an authentication failure — the cached copy is still served; if the repository answers definitively about the artifact itself (404 or 410 gone, 403 refused) it is treated as absent there and resolution moves on to the next repository. A definitive answer is also remembered for about five minutes, so a repeat resolve of the same target inside that window is answered from the record instead of asking that repository again. The record is bounded in every direction: only 403, 404 and 410 are eligible, so a timeout, a 5xx, a 429, an authentication failure and a network error are all retried on the next call; a `-SNAPSHOT` coordinate is never recorded; the records are held per cache directory; and they live in memory only, so restarting the server clears them and an artifact published after its rejection was recorded becomes reachable again as soon as the record expires. Note that `MCP_SOURCE_REPOS` replaces the default list rather than adding to it.
|
|
712
724
|
|
|
713
725
|
### Search, Index, and Cache Tuning
|
|
714
726
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhisang/minecraft-modding-mcp",
|
|
3
|
-
"version": "7.0.0
|
|
3
|
+
"version": "7.0.0",
|
|
4
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
|
"packageManager": "pnpm@10.30.1",
|