@adhisang/minecraft-modding-mcp 1.0.0 → 1.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 +17 -0
- package/README.md +42 -1
- package/dist/cli.js +6 -1
- package/dist/compat-stdio-transport.d.ts +27 -0
- package/dist/compat-stdio-transport.js +217 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +382 -785
- package/dist/logger.js +1 -9
- package/dist/mcp-helpers.d.ts +5 -0
- package/dist/mcp-helpers.js +13 -0
- package/dist/resources.d.ts +2 -2
- package/dist/resources.js +23 -57
- package/dist/source-service.js +58 -8
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { ZodError, z } from "zod";
|
|
4
|
+
import { CompatStdioServerTransport } from "./compat-stdio-transport.js";
|
|
5
|
+
import { objectResult } from "./mcp-helpers.js";
|
|
4
6
|
import { loadConfig } from "./config.js";
|
|
5
7
|
import { ERROR_CODES, isAppError } from "./errors.js";
|
|
6
8
|
import { log } from "./logger.js";
|
|
@@ -63,30 +65,33 @@ function validateTargetPair(value, ctx) {
|
|
|
63
65
|
});
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
|
-
const
|
|
67
|
-
includeSnapshots: z.boolean().optional(),
|
|
68
|
-
limit: optionalPositiveInt
|
|
69
|
-
}
|
|
70
|
-
const
|
|
71
|
-
|
|
68
|
+
const listVersionsShape = {
|
|
69
|
+
includeSnapshots: z.boolean().optional().describe("default false"),
|
|
70
|
+
limit: optionalPositiveInt.describe("default 20, max 200")
|
|
71
|
+
};
|
|
72
|
+
const listVersionsSchema = z.object(listVersionsShape);
|
|
73
|
+
const resolveArtifactShape = {
|
|
74
|
+
targetKind: targetKindSchema.describe("version | jar | coordinate"),
|
|
72
75
|
targetValue: nonEmptyString,
|
|
73
|
-
mapping: sourceMappingSchema.optional(),
|
|
74
|
-
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
75
|
-
allowDecompile: z.boolean().optional()
|
|
76
|
-
}
|
|
77
|
-
const
|
|
78
|
-
|
|
76
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
77
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
78
|
+
allowDecompile: z.boolean().optional().describe("default true")
|
|
79
|
+
};
|
|
80
|
+
const resolveArtifactSchema = z.object(resolveArtifactShape);
|
|
81
|
+
const getClassSourceShape = {
|
|
79
82
|
className: nonEmptyString,
|
|
80
83
|
artifactId: optionalNonEmptyString,
|
|
81
|
-
targetKind: targetKindSchema.optional(),
|
|
84
|
+
targetKind: targetKindSchema.optional().describe("version | jar | coordinate"),
|
|
82
85
|
targetValue: optionalNonEmptyString,
|
|
83
|
-
mapping: sourceMappingSchema.optional(),
|
|
84
|
-
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
85
|
-
allowDecompile: z.boolean().optional(),
|
|
86
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
87
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
88
|
+
allowDecompile: z.boolean().optional().describe("default true"),
|
|
86
89
|
startLine: optionalPositiveInt,
|
|
87
90
|
endLine: optionalPositiveInt,
|
|
88
91
|
maxLines: optionalPositiveInt
|
|
89
|
-
}
|
|
92
|
+
};
|
|
93
|
+
const getClassSourceSchema = z
|
|
94
|
+
.object(getClassSourceShape)
|
|
90
95
|
.superRefine((value, ctx) => {
|
|
91
96
|
validateTargetPair({
|
|
92
97
|
artifactId: value.artifactId,
|
|
@@ -103,21 +108,22 @@ const getClassSourceSchema = z
|
|
|
103
108
|
});
|
|
104
109
|
}
|
|
105
110
|
});
|
|
106
|
-
const
|
|
107
|
-
.object({
|
|
111
|
+
const getClassMembersShape = {
|
|
108
112
|
className: nonEmptyString,
|
|
109
113
|
artifactId: optionalNonEmptyString,
|
|
110
|
-
targetKind: targetKindSchema.optional(),
|
|
114
|
+
targetKind: targetKindSchema.optional().describe("version | jar | coordinate"),
|
|
111
115
|
targetValue: optionalNonEmptyString,
|
|
112
|
-
mapping: sourceMappingSchema.optional(),
|
|
113
|
-
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
114
|
-
allowDecompile: z.boolean().optional(),
|
|
115
|
-
access: memberAccessSchema.optional(),
|
|
116
|
-
includeSynthetic: z.boolean().optional(),
|
|
117
|
-
includeInherited: z.boolean().optional(),
|
|
116
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn (default official)"),
|
|
117
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
118
|
+
allowDecompile: z.boolean().optional().describe("default true"),
|
|
119
|
+
access: memberAccessSchema.optional().describe("public | all (default public)"),
|
|
120
|
+
includeSynthetic: z.boolean().optional().describe("default false"),
|
|
121
|
+
includeInherited: z.boolean().optional().describe("default false"),
|
|
118
122
|
memberPattern: optionalNonEmptyString,
|
|
119
|
-
maxMembers: optionalPositiveInt
|
|
120
|
-
}
|
|
123
|
+
maxMembers: optionalPositiveInt.describe("default 500, max 5000")
|
|
124
|
+
};
|
|
125
|
+
const getClassMembersSchema = z
|
|
126
|
+
.object(getClassMembersShape)
|
|
121
127
|
.superRefine((value, ctx) => {
|
|
122
128
|
validateTargetPair({
|
|
123
129
|
artifactId: value.artifactId,
|
|
@@ -125,59 +131,65 @@ const getClassMembersSchema = z
|
|
|
125
131
|
targetValue: value.targetValue
|
|
126
132
|
}, ctx);
|
|
127
133
|
});
|
|
128
|
-
const
|
|
134
|
+
const searchClassSourceShape = {
|
|
129
135
|
artifactId: nonEmptyString,
|
|
130
136
|
query: nonEmptyString,
|
|
131
|
-
intent: searchIntentSchema.optional(),
|
|
132
|
-
match: searchMatchSchema.optional(),
|
|
137
|
+
intent: searchIntentSchema.optional().describe("symbol | text | path"),
|
|
138
|
+
match: searchMatchSchema.optional().describe("exact | prefix | contains | regex"),
|
|
133
139
|
packagePrefix: optionalNonEmptyString,
|
|
134
140
|
fileGlob: optionalNonEmptyString,
|
|
135
|
-
symbolKind: searchSymbolKindSchema.optional(),
|
|
136
|
-
snippetLines: optionalPositiveInt,
|
|
137
|
-
includeDefinition: z.boolean().optional(),
|
|
138
|
-
includeOneHop: z.boolean().optional(),
|
|
139
|
-
limit: optionalPositiveInt,
|
|
141
|
+
symbolKind: searchSymbolKindSchema.optional().describe("class | interface | enum | record | method | field"),
|
|
142
|
+
snippetLines: optionalPositiveInt.describe("default 8, clamp 1..80"),
|
|
143
|
+
includeDefinition: z.boolean().optional().describe("default false"),
|
|
144
|
+
includeOneHop: z.boolean().optional().describe("default false"),
|
|
145
|
+
limit: optionalPositiveInt.describe("default 20"),
|
|
140
146
|
cursor: optionalNonEmptyString
|
|
141
|
-
}
|
|
142
|
-
const
|
|
147
|
+
};
|
|
148
|
+
const searchClassSourceSchema = z.object(searchClassSourceShape);
|
|
149
|
+
const getArtifactFileShape = {
|
|
143
150
|
artifactId: nonEmptyString,
|
|
144
151
|
filePath: nonEmptyString,
|
|
145
152
|
maxBytes: optionalPositiveInt
|
|
146
|
-
}
|
|
147
|
-
const
|
|
153
|
+
};
|
|
154
|
+
const getArtifactFileSchema = z.object(getArtifactFileShape);
|
|
155
|
+
const listArtifactFilesShape = {
|
|
148
156
|
artifactId: nonEmptyString,
|
|
149
157
|
prefix: optionalNonEmptyString,
|
|
150
158
|
limit: optionalPositiveInt,
|
|
151
159
|
cursor: optionalNonEmptyString
|
|
152
|
-
}
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
};
|
|
161
|
+
const listArtifactFilesSchema = z.object(listArtifactFilesShape);
|
|
162
|
+
const traceSymbolLifecycleShape = {
|
|
163
|
+
symbol: nonEmptyString.describe("fully.qualified.Class.method"),
|
|
164
|
+
descriptor: optionalNonEmptyString.describe('optional JVM descriptor, e.g. "(I)V"'),
|
|
156
165
|
fromVersion: optionalNonEmptyString,
|
|
157
166
|
toVersion: optionalNonEmptyString,
|
|
158
|
-
mapping: sourceMappingSchema.optional(),
|
|
159
|
-
sourcePriority: mappingSourcePrioritySchema.optional(),
|
|
160
|
-
includeSnapshots: z.boolean().optional(),
|
|
161
|
-
maxVersions: optionalPositiveInt,
|
|
162
|
-
includeTimeline: z.boolean().optional()
|
|
163
|
-
}
|
|
164
|
-
const
|
|
167
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn (default official)"),
|
|
168
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first"),
|
|
169
|
+
includeSnapshots: z.boolean().optional().describe("default false"),
|
|
170
|
+
maxVersions: optionalPositiveInt.describe("default 120, max 400"),
|
|
171
|
+
includeTimeline: z.boolean().optional().describe("default false")
|
|
172
|
+
};
|
|
173
|
+
const traceSymbolLifecycleSchema = z.object(traceSymbolLifecycleShape);
|
|
174
|
+
const diffClassSignaturesShape = {
|
|
165
175
|
className: nonEmptyString,
|
|
166
176
|
fromVersion: nonEmptyString,
|
|
167
177
|
toVersion: nonEmptyString,
|
|
168
|
-
mapping: sourceMappingSchema.optional(),
|
|
169
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
170
|
-
}
|
|
171
|
-
const
|
|
178
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn (default official)"),
|
|
179
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
180
|
+
};
|
|
181
|
+
const diffClassSignaturesSchema = z.object(diffClassSignaturesShape);
|
|
182
|
+
const findMappingShape = {
|
|
172
183
|
version: nonEmptyString,
|
|
173
|
-
kind: workspaceSymbolKindSchema,
|
|
184
|
+
kind: workspaceSymbolKindSchema.describe("class | field | method"),
|
|
174
185
|
name: nonEmptyString,
|
|
175
186
|
owner: optionalNonEmptyString,
|
|
176
187
|
descriptor: optionalNonEmptyString,
|
|
177
|
-
sourceMapping: sourceMappingSchema,
|
|
178
|
-
targetMapping: sourceMappingSchema,
|
|
179
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
180
|
-
}
|
|
188
|
+
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
189
|
+
targetMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
190
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
191
|
+
};
|
|
192
|
+
const findMappingSchema = z.object(findMappingShape).superRefine((value, ctx) => {
|
|
181
193
|
if (value.kind === "class") {
|
|
182
194
|
if (value.owner) {
|
|
183
195
|
ctx.addIssue({
|
|
@@ -234,17 +246,18 @@ const findMappingSchema = z.object({
|
|
|
234
246
|
});
|
|
235
247
|
}
|
|
236
248
|
});
|
|
237
|
-
const
|
|
238
|
-
.object({
|
|
249
|
+
const resolveMethodMappingExactShape = {
|
|
239
250
|
version: nonEmptyString,
|
|
240
|
-
kind: workspaceSymbolKindSchema,
|
|
251
|
+
kind: workspaceSymbolKindSchema.describe("class | field | method"),
|
|
241
252
|
name: nonEmptyString,
|
|
242
253
|
owner: optionalNonEmptyString,
|
|
243
|
-
descriptor: optionalNonEmptyString,
|
|
244
|
-
sourceMapping: sourceMappingSchema,
|
|
245
|
-
targetMapping: sourceMappingSchema,
|
|
246
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
247
|
-
}
|
|
254
|
+
descriptor: optionalNonEmptyString.describe("required for kind=method"),
|
|
255
|
+
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
256
|
+
targetMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
257
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
258
|
+
};
|
|
259
|
+
const resolveMethodMappingExactSchema = z
|
|
260
|
+
.object(resolveMethodMappingExactShape)
|
|
248
261
|
.superRefine((value, ctx) => {
|
|
249
262
|
if (value.kind !== "method") {
|
|
250
263
|
ctx.addIssue({
|
|
@@ -295,24 +308,26 @@ const classApiKindsSchema = z.string().superRefine((value, ctx) => {
|
|
|
295
308
|
});
|
|
296
309
|
}
|
|
297
310
|
});
|
|
298
|
-
const
|
|
311
|
+
const getClassApiMatrixShape = {
|
|
299
312
|
version: nonEmptyString,
|
|
300
313
|
className: nonEmptyString,
|
|
301
|
-
classNameMapping: sourceMappingSchema,
|
|
302
|
-
includeKinds: classApiKindsSchema.optional(),
|
|
303
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
304
|
-
}
|
|
305
|
-
const
|
|
306
|
-
|
|
314
|
+
classNameMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
315
|
+
includeKinds: classApiKindsSchema.optional().describe("comma-separated: class,field,method"),
|
|
316
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
317
|
+
};
|
|
318
|
+
const getClassApiMatrixSchema = z.object(getClassApiMatrixShape);
|
|
319
|
+
const resolveWorkspaceSymbolShape = {
|
|
307
320
|
projectPath: nonEmptyString,
|
|
308
321
|
version: nonEmptyString,
|
|
309
|
-
kind: workspaceSymbolKindSchema,
|
|
322
|
+
kind: workspaceSymbolKindSchema.describe("class | field | method"),
|
|
310
323
|
name: nonEmptyString,
|
|
311
324
|
owner: optionalNonEmptyString,
|
|
312
325
|
descriptor: optionalNonEmptyString,
|
|
313
|
-
sourceMapping: sourceMappingSchema,
|
|
314
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
315
|
-
}
|
|
326
|
+
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
327
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
328
|
+
};
|
|
329
|
+
const resolveWorkspaceSymbolSchema = z
|
|
330
|
+
.object(resolveWorkspaceSymbolShape)
|
|
316
331
|
.superRefine((value, ctx) => {
|
|
317
332
|
if (value.kind === "class") {
|
|
318
333
|
if (value.owner) {
|
|
@@ -370,15 +385,16 @@ const resolveWorkspaceSymbolSchema = z
|
|
|
370
385
|
});
|
|
371
386
|
}
|
|
372
387
|
});
|
|
373
|
-
const
|
|
388
|
+
const checkSymbolExistsShape = {
|
|
374
389
|
version: nonEmptyString,
|
|
375
|
-
kind: workspaceSymbolKindSchema,
|
|
390
|
+
kind: workspaceSymbolKindSchema.describe("class | field | method"),
|
|
376
391
|
owner: optionalNonEmptyString,
|
|
377
392
|
name: nonEmptyString,
|
|
378
|
-
descriptor: optionalNonEmptyString,
|
|
379
|
-
sourceMapping: sourceMappingSchema,
|
|
380
|
-
sourcePriority: mappingSourcePrioritySchema.optional()
|
|
381
|
-
}
|
|
393
|
+
descriptor: optionalNonEmptyString.describe("required for kind=method"),
|
|
394
|
+
sourceMapping: sourceMappingSchema.describe("official | mojang | intermediary | yarn"),
|
|
395
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
396
|
+
};
|
|
397
|
+
const checkSymbolExistsSchema = z.object(checkSymbolExistsShape).superRefine((value, ctx) => {
|
|
382
398
|
if (value.kind === "class") {
|
|
383
399
|
if (value.owner) {
|
|
384
400
|
ctx.addIssue({
|
|
@@ -435,10 +451,11 @@ const checkSymbolExistsSchema = z.object({
|
|
|
435
451
|
});
|
|
436
452
|
}
|
|
437
453
|
});
|
|
438
|
-
const
|
|
454
|
+
const nbtToJsonShape = {
|
|
439
455
|
nbtBase64: nonEmptyString,
|
|
440
|
-
compression: decodeCompressionSchema.optional()
|
|
441
|
-
}
|
|
456
|
+
compression: decodeCompressionSchema.optional().describe("none | gzip | auto (default auto)")
|
|
457
|
+
};
|
|
458
|
+
const nbtToJsonSchema = z.object(nbtToJsonShape);
|
|
442
459
|
const nbtPatchOperationSchema = z
|
|
443
460
|
.object({
|
|
444
461
|
op: z.enum(["add", "remove", "replace", "test"]),
|
|
@@ -446,71 +463,83 @@ const nbtPatchOperationSchema = z
|
|
|
446
463
|
value: z.unknown().optional()
|
|
447
464
|
})
|
|
448
465
|
.passthrough();
|
|
449
|
-
const
|
|
466
|
+
const nbtApplyJsonPatchShape = {
|
|
450
467
|
typedJson: z.unknown(),
|
|
451
|
-
patch: z.array(nbtPatchOperationSchema)
|
|
452
|
-
}
|
|
453
|
-
const
|
|
468
|
+
patch: z.array(nbtPatchOperationSchema).describe("RFC6902 operation array (add/remove/replace/test)")
|
|
469
|
+
};
|
|
470
|
+
const nbtApplyJsonPatchSchema = z.object(nbtApplyJsonPatchShape);
|
|
471
|
+
const jsonToNbtShape = {
|
|
454
472
|
typedJson: z.unknown(),
|
|
455
|
-
compression: encodeCompressionSchema.optional()
|
|
456
|
-
}
|
|
457
|
-
const
|
|
473
|
+
compression: encodeCompressionSchema.optional().describe("none | gzip (default none)")
|
|
474
|
+
};
|
|
475
|
+
const jsonToNbtSchema = z.object(jsonToNbtShape);
|
|
476
|
+
const indexArtifactShape = {
|
|
458
477
|
artifactId: nonEmptyString,
|
|
459
|
-
force: z.boolean().optional()
|
|
460
|
-
}
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
478
|
+
force: z.boolean().optional().describe("default false")
|
|
479
|
+
};
|
|
480
|
+
const indexArtifactSchema = z.object(indexArtifactShape);
|
|
481
|
+
const validateMixinShape = {
|
|
482
|
+
source: nonEmptyString.describe("Mixin Java source text"),
|
|
483
|
+
version: nonEmptyString.describe("Minecraft version"),
|
|
484
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
485
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
486
|
+
};
|
|
487
|
+
const validateMixinSchema = z.object(validateMixinShape);
|
|
488
|
+
const validateAccessWidenerShape = {
|
|
489
|
+
content: nonEmptyString.describe("Access Widener file content"),
|
|
490
|
+
version: nonEmptyString.describe("Minecraft version"),
|
|
491
|
+
mapping: sourceMappingSchema.optional().describe("official | mojang | intermediary | yarn"),
|
|
492
|
+
sourcePriority: mappingSourcePrioritySchema.optional().describe("loom-first | maven-first")
|
|
493
|
+
};
|
|
494
|
+
const validateAccessWidenerSchema = z.object(validateAccessWidenerShape);
|
|
495
|
+
const analyzeModJarShape = {
|
|
496
|
+
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
497
|
+
includeClasses: z.boolean().optional().describe("Include full class listing (default false)")
|
|
498
|
+
};
|
|
499
|
+
const analyzeModJarSchema = z.object(analyzeModJarShape);
|
|
500
|
+
const getRegistryDataShape = {
|
|
501
|
+
version: nonEmptyString.describe("Minecraft version (e.g. 1.21)"),
|
|
502
|
+
registry: optionalNonEmptyString.describe('Optional registry name (e.g. "block", "item", "minecraft:biome"). Omit to list all registries.')
|
|
503
|
+
};
|
|
504
|
+
const getRegistryDataSchema = z.object(getRegistryDataShape);
|
|
481
505
|
const COMPARE_VERSIONS_CATEGORIES = ["classes", "registry", "all"];
|
|
482
506
|
const compareVersionsCategorySchema = z.enum(COMPARE_VERSIONS_CATEGORIES);
|
|
483
|
-
const
|
|
484
|
-
fromVersion: nonEmptyString,
|
|
485
|
-
toVersion: nonEmptyString,
|
|
486
|
-
category: compareVersionsCategorySchema.optional(),
|
|
487
|
-
packageFilter: optionalNonEmptyString,
|
|
488
|
-
maxClassResults: optionalPositiveInt
|
|
489
|
-
}
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
507
|
+
const compareVersionsShape = {
|
|
508
|
+
fromVersion: nonEmptyString.describe("Older Minecraft version (e.g. 1.20.4)"),
|
|
509
|
+
toVersion: nonEmptyString.describe("Newer Minecraft version (e.g. 1.21)"),
|
|
510
|
+
category: compareVersionsCategorySchema.optional().describe("classes | registry | all (default all)"),
|
|
511
|
+
packageFilter: optionalNonEmptyString.describe("Filter classes to a package prefix (e.g. net.minecraft.world.item)"),
|
|
512
|
+
maxClassResults: optionalPositiveInt.describe("Max class results per direction (default 500, max 5000)")
|
|
513
|
+
};
|
|
514
|
+
const compareVersionsSchema = z.object(compareVersionsShape);
|
|
515
|
+
const decompileModJarShape = {
|
|
516
|
+
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
517
|
+
className: optionalNonEmptyString.describe("Optional fully-qualified class name to view source. Omit to list all classes.")
|
|
518
|
+
};
|
|
519
|
+
const decompileModJarSchema = z.object(decompileModJarShape);
|
|
520
|
+
const getModClassSourceShape = {
|
|
521
|
+
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
522
|
+
className: nonEmptyString.describe("Fully-qualified class name (e.g. com.example.MyMixin)")
|
|
523
|
+
};
|
|
524
|
+
const getModClassSourceSchema = z.object(getModClassSourceShape);
|
|
498
525
|
const MOD_SEARCH_TYPES = ["class", "method", "field", "content", "all"];
|
|
499
526
|
const modSearchTypeSchema = z.enum(MOD_SEARCH_TYPES);
|
|
500
|
-
const
|
|
501
|
-
jarPath: nonEmptyString,
|
|
502
|
-
query: nonEmptyString,
|
|
503
|
-
searchType: modSearchTypeSchema.optional(),
|
|
504
|
-
limit: optionalPositiveInt
|
|
505
|
-
}
|
|
527
|
+
const searchModSourceShape = {
|
|
528
|
+
jarPath: nonEmptyString.describe("Local path to the mod JAR file"),
|
|
529
|
+
query: nonEmptyString.describe("Search pattern (regex or literal string)"),
|
|
530
|
+
searchType: modSearchTypeSchema.optional().describe("class | method | field | content | all (default all)"),
|
|
531
|
+
limit: optionalPositiveInt.describe("Max results (default 50, max 200)")
|
|
532
|
+
};
|
|
533
|
+
const searchModSourceSchema = z.object(searchModSourceShape);
|
|
506
534
|
const REMAP_TARGETS = ["yarn", "mojang"];
|
|
507
535
|
const remapTargetSchema = z.enum(REMAP_TARGETS);
|
|
508
|
-
const
|
|
509
|
-
inputJar: nonEmptyString,
|
|
510
|
-
outputJar: optionalNonEmptyString,
|
|
511
|
-
mcVersion: optionalNonEmptyString,
|
|
512
|
-
targetMapping: remapTargetSchema
|
|
513
|
-
}
|
|
536
|
+
const remapModJarShape = {
|
|
537
|
+
inputJar: nonEmptyString.describe("Path to the mod JAR file"),
|
|
538
|
+
outputJar: optionalNonEmptyString.describe("Output path for remapped JAR (auto-generated if omitted)"),
|
|
539
|
+
mcVersion: optionalNonEmptyString.describe("Minecraft version (auto-detected from mod metadata if omitted)"),
|
|
540
|
+
targetMapping: remapTargetSchema.describe("yarn | mojang")
|
|
541
|
+
};
|
|
542
|
+
const remapModJarSchema = z.object(remapModJarShape);
|
|
514
543
|
const emptySchema = z.object({}).passthrough();
|
|
515
544
|
function getServerVersionFromPackageJson() {
|
|
516
545
|
try {
|
|
@@ -526,7 +555,7 @@ function getServerVersionFromPackageJson() {
|
|
|
526
555
|
return "0.3.0";
|
|
527
556
|
}
|
|
528
557
|
const SERVER_VERSION = getServerVersionFromPackageJson();
|
|
529
|
-
const server = new
|
|
558
|
+
const server = new McpServer({
|
|
530
559
|
name: "@adhisang/minecraft-modding-mcp",
|
|
531
560
|
version: SERVER_VERSION
|
|
532
561
|
});
|
|
@@ -737,7 +766,7 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
737
766
|
const parsedInput = schema.parse(rawInput);
|
|
738
767
|
const payload = await action(parsedInput);
|
|
739
768
|
const { result, warnings } = splitWarnings(payload);
|
|
740
|
-
return
|
|
769
|
+
return objectResult({
|
|
741
770
|
result,
|
|
742
771
|
meta: {
|
|
743
772
|
requestId,
|
|
@@ -779,7 +808,7 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
779
808
|
reason: caughtError instanceof Error ? caughtError.message : String(caughtError)
|
|
780
809
|
});
|
|
781
810
|
}
|
|
782
|
-
return
|
|
811
|
+
return objectResult({
|
|
783
812
|
error: problem,
|
|
784
813
|
meta: {
|
|
785
814
|
requestId,
|
|
@@ -790,646 +819,211 @@ async function runTool(tool, rawInput, schema, action) {
|
|
|
790
819
|
});
|
|
791
820
|
}
|
|
792
821
|
}
|
|
793
|
-
server.tool({
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
inputs: [
|
|
837
|
-
{ name: "className", type: "string", required: true },
|
|
838
|
-
{ name: "artifactId", type: "string" },
|
|
839
|
-
{ name: "targetKind", type: "string", description: "version | jar | coordinate" },
|
|
840
|
-
{ name: "targetValue", type: "string" },
|
|
841
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn" },
|
|
842
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" },
|
|
843
|
-
{ name: "allowDecompile", type: "boolean", description: "default true" },
|
|
844
|
-
{ name: "startLine", type: "number" },
|
|
845
|
-
{ name: "endLine", type: "number" },
|
|
846
|
-
{ name: "maxLines", type: "number" }
|
|
847
|
-
],
|
|
848
|
-
annotations: {
|
|
849
|
-
readOnlyHint: true
|
|
850
|
-
}
|
|
851
|
-
}, async (rawInput) => {
|
|
852
|
-
return runTool("get-class-source", rawInput, getClassSourceSchema, async (input) => sourceService.getClassSource({
|
|
853
|
-
className: input.className,
|
|
854
|
-
artifactId: input.artifactId,
|
|
855
|
-
target: buildTarget(input.targetKind, input.targetValue),
|
|
856
|
-
mapping: input.mapping,
|
|
857
|
-
sourcePriority: input.sourcePriority,
|
|
858
|
-
allowDecompile: input.allowDecompile,
|
|
859
|
-
startLine: input.startLine,
|
|
860
|
-
endLine: input.endLine,
|
|
861
|
-
maxLines: input.maxLines
|
|
862
|
-
}));
|
|
863
|
-
});
|
|
864
|
-
server.tool({
|
|
865
|
-
name: "get-class-members",
|
|
866
|
-
description: "Get fields/methods/constructors for one class from binary bytecode by artifactId or by resolving target (version/jar/coordinate).",
|
|
867
|
-
inputs: [
|
|
868
|
-
{ name: "className", type: "string", required: true },
|
|
869
|
-
{ name: "artifactId", type: "string" },
|
|
870
|
-
{ name: "targetKind", type: "string", description: "version | jar | coordinate" },
|
|
871
|
-
{ name: "targetValue", type: "string" },
|
|
872
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn (default official)" },
|
|
873
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" },
|
|
874
|
-
{ name: "allowDecompile", type: "boolean", description: "default true" },
|
|
875
|
-
{ name: "access", type: "string", description: "public | all (default public)" },
|
|
876
|
-
{ name: "includeSynthetic", type: "boolean", description: "default false" },
|
|
877
|
-
{ name: "includeInherited", type: "boolean", description: "default false" },
|
|
878
|
-
{ name: "memberPattern", type: "string" },
|
|
879
|
-
{ name: "maxMembers", type: "number", description: "default 500, max 5000" }
|
|
880
|
-
],
|
|
881
|
-
annotations: {
|
|
882
|
-
readOnlyHint: true
|
|
883
|
-
}
|
|
884
|
-
}, async (rawInput) => {
|
|
885
|
-
return runTool("get-class-members", rawInput, getClassMembersSchema, async (input) => sourceService.getClassMembers({
|
|
886
|
-
className: input.className,
|
|
887
|
-
artifactId: input.artifactId,
|
|
888
|
-
target: buildTarget(input.targetKind, input.targetValue),
|
|
889
|
-
mapping: input.mapping,
|
|
890
|
-
sourcePriority: input.sourcePriority,
|
|
891
|
-
allowDecompile: input.allowDecompile,
|
|
892
|
-
access: input.access,
|
|
893
|
-
includeSynthetic: input.includeSynthetic,
|
|
894
|
-
includeInherited: input.includeInherited,
|
|
895
|
-
memberPattern: input.memberPattern,
|
|
896
|
-
maxMembers: input.maxMembers
|
|
897
|
-
}));
|
|
898
|
-
});
|
|
899
|
-
server.tool({
|
|
900
|
-
name: "search-class-source",
|
|
901
|
-
description: "Search indexed class source files for one artifact with symbol/text/path intent and optional one-hop relation expansion.",
|
|
902
|
-
inputs: [
|
|
903
|
-
{ name: "artifactId", type: "string", required: true },
|
|
904
|
-
{ name: "query", type: "string", required: true },
|
|
905
|
-
{ name: "intent", type: "string", description: "symbol | text | path" },
|
|
906
|
-
{ name: "match", type: "string", description: "exact | prefix | contains | regex" },
|
|
907
|
-
{ name: "packagePrefix", type: "string" },
|
|
908
|
-
{ name: "fileGlob", type: "string" },
|
|
909
|
-
{ name: "symbolKind", type: "string", description: "class | interface | enum | record | method | field" },
|
|
910
|
-
{ name: "snippetLines", type: "number", description: "default 8, clamp 1..80" },
|
|
911
|
-
{ name: "includeDefinition", type: "boolean", description: "default false" },
|
|
912
|
-
{ name: "includeOneHop", type: "boolean", description: "default false" },
|
|
913
|
-
{ name: "limit", type: "number", description: "default 20" },
|
|
914
|
-
{ name: "cursor", type: "string" }
|
|
915
|
-
],
|
|
916
|
-
annotations: {
|
|
917
|
-
readOnlyHint: true
|
|
918
|
-
}
|
|
919
|
-
}, async (rawInput) => {
|
|
920
|
-
return runTool("search-class-source", rawInput, searchClassSourceSchema, async (input) => {
|
|
921
|
-
const scope = input.packagePrefix || input.fileGlob || input.symbolKind
|
|
922
|
-
? {
|
|
923
|
-
packagePrefix: input.packagePrefix,
|
|
924
|
-
fileGlob: input.fileGlob,
|
|
925
|
-
symbolKind: input.symbolKind
|
|
926
|
-
}
|
|
927
|
-
: undefined;
|
|
928
|
-
const include = input.snippetLines !== undefined ||
|
|
929
|
-
input.includeDefinition !== undefined ||
|
|
930
|
-
input.includeOneHop !== undefined
|
|
931
|
-
? {
|
|
932
|
-
snippetLines: input.snippetLines,
|
|
933
|
-
includeDefinition: input.includeDefinition,
|
|
934
|
-
includeOneHop: input.includeOneHop
|
|
935
|
-
}
|
|
936
|
-
: undefined;
|
|
937
|
-
return sourceService.searchClassSource({
|
|
938
|
-
artifactId: input.artifactId,
|
|
939
|
-
query: input.query,
|
|
940
|
-
intent: input.intent,
|
|
941
|
-
match: input.match,
|
|
942
|
-
scope: scope,
|
|
943
|
-
include,
|
|
944
|
-
limit: input.limit,
|
|
945
|
-
cursor: input.cursor
|
|
946
|
-
});
|
|
947
|
-
});
|
|
948
|
-
});
|
|
949
|
-
server.tool({
|
|
950
|
-
name: "get-artifact-file",
|
|
951
|
-
description: "Get full source file content by artifactId and file path.",
|
|
952
|
-
inputs: [
|
|
953
|
-
{ name: "artifactId", type: "string", required: true },
|
|
954
|
-
{ name: "filePath", type: "string", required: true },
|
|
955
|
-
{ name: "maxBytes", type: "number" }
|
|
956
|
-
],
|
|
957
|
-
annotations: {
|
|
958
|
-
readOnlyHint: true
|
|
959
|
-
}
|
|
960
|
-
}, async (rawInput) => {
|
|
961
|
-
return runTool("get-artifact-file", rawInput, getArtifactFileSchema, async (input) => sourceService.getArtifactFile({
|
|
962
|
-
artifactId: input.artifactId,
|
|
963
|
-
filePath: input.filePath,
|
|
964
|
-
maxBytes: input.maxBytes
|
|
965
|
-
}));
|
|
966
|
-
});
|
|
967
|
-
server.tool({
|
|
968
|
-
name: "list-artifact-files",
|
|
969
|
-
description: "List source file paths in an artifact with optional prefix filter and cursor-based pagination.",
|
|
970
|
-
inputs: [
|
|
971
|
-
{ name: "artifactId", type: "string", required: true },
|
|
972
|
-
{ name: "prefix", type: "string" },
|
|
973
|
-
{ name: "limit", type: "number" },
|
|
974
|
-
{ name: "cursor", type: "string" }
|
|
975
|
-
],
|
|
976
|
-
annotations: {
|
|
977
|
-
readOnlyHint: true
|
|
978
|
-
}
|
|
979
|
-
}, async (rawInput) => {
|
|
980
|
-
return runTool("list-artifact-files", rawInput, listArtifactFilesSchema, async (input) => sourceService.listArtifactFiles(input));
|
|
981
|
-
});
|
|
982
|
-
server.tool({
|
|
983
|
-
name: "trace-symbol-lifecycle",
|
|
984
|
-
description: "Trace which Minecraft versions contain a specific class method and report first/last seen versions.",
|
|
985
|
-
inputs: [
|
|
986
|
-
{ name: "symbol", type: "string", required: true, description: "fully.qualified.Class.method" },
|
|
987
|
-
{ name: "descriptor", type: "string", description: 'optional JVM descriptor, e.g. "(I)V"' },
|
|
988
|
-
{ name: "fromVersion", type: "string" },
|
|
989
|
-
{ name: "toVersion", type: "string" },
|
|
990
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn (default official)" },
|
|
991
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" },
|
|
992
|
-
{ name: "includeSnapshots", type: "boolean", description: "default false" },
|
|
993
|
-
{ name: "maxVersions", type: "number", description: "default 120, max 400" },
|
|
994
|
-
{ name: "includeTimeline", type: "boolean", description: "default false" }
|
|
995
|
-
],
|
|
996
|
-
annotations: {
|
|
997
|
-
readOnlyHint: true
|
|
998
|
-
}
|
|
999
|
-
}, async (rawInput) => {
|
|
1000
|
-
return runTool("trace-symbol-lifecycle", rawInput, traceSymbolLifecycleSchema, async (input) => sourceService.traceSymbolLifecycle({
|
|
1001
|
-
symbol: input.symbol,
|
|
1002
|
-
descriptor: input.descriptor,
|
|
1003
|
-
fromVersion: input.fromVersion,
|
|
1004
|
-
toVersion: input.toVersion,
|
|
1005
|
-
mapping: input.mapping,
|
|
1006
|
-
sourcePriority: input.sourcePriority,
|
|
1007
|
-
includeSnapshots: input.includeSnapshots,
|
|
1008
|
-
maxVersions: input.maxVersions,
|
|
1009
|
-
includeTimeline: input.includeTimeline
|
|
1010
|
-
}));
|
|
1011
|
-
});
|
|
1012
|
-
server.tool({
|
|
1013
|
-
name: "diff-class-signatures",
|
|
1014
|
-
description: "Compare one class signature between two Minecraft versions and report added/removed/modified constructors, methods, and fields.",
|
|
1015
|
-
inputs: [
|
|
1016
|
-
{ name: "className", type: "string", required: true },
|
|
1017
|
-
{ name: "fromVersion", type: "string", required: true },
|
|
1018
|
-
{ name: "toVersion", type: "string", required: true },
|
|
1019
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn (default official)" },
|
|
1020
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1021
|
-
],
|
|
1022
|
-
annotations: {
|
|
1023
|
-
readOnlyHint: true
|
|
1024
|
-
}
|
|
1025
|
-
}, async (rawInput) => {
|
|
1026
|
-
return runTool("diff-class-signatures", rawInput, diffClassSignaturesSchema, async (input) => sourceService.diffClassSignatures({
|
|
1027
|
-
className: input.className,
|
|
1028
|
-
fromVersion: input.fromVersion,
|
|
1029
|
-
toVersion: input.toVersion,
|
|
1030
|
-
mapping: input.mapping,
|
|
1031
|
-
sourcePriority: input.sourcePriority
|
|
1032
|
-
}));
|
|
1033
|
-
});
|
|
1034
|
-
server.tool({
|
|
1035
|
-
name: "find-mapping",
|
|
1036
|
-
description: "Find symbol mapping candidates between namespaces using structured symbol inputs for a specific Minecraft version.",
|
|
1037
|
-
inputs: [
|
|
1038
|
-
{ name: "version", type: "string", required: true },
|
|
1039
|
-
{ name: "kind", type: "string", required: true, description: "class | field | method" },
|
|
1040
|
-
{ name: "name", type: "string", required: true },
|
|
1041
|
-
{ name: "owner", type: "string" },
|
|
1042
|
-
{ name: "descriptor", type: "string" },
|
|
1043
|
-
{ name: "sourceMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1044
|
-
{ name: "targetMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1045
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1046
|
-
],
|
|
1047
|
-
annotations: {
|
|
1048
|
-
readOnlyHint: true
|
|
1049
|
-
}
|
|
1050
|
-
}, async (rawInput) => {
|
|
1051
|
-
return runTool("find-mapping", rawInput, findMappingSchema, async (input) => sourceService.findMapping({
|
|
1052
|
-
version: input.version,
|
|
1053
|
-
kind: input.kind,
|
|
1054
|
-
name: input.name,
|
|
1055
|
-
owner: input.owner,
|
|
1056
|
-
descriptor: input.descriptor,
|
|
1057
|
-
sourceMapping: input.sourceMapping,
|
|
1058
|
-
targetMapping: input.targetMapping,
|
|
1059
|
-
sourcePriority: input.sourcePriority
|
|
1060
|
-
}));
|
|
1061
|
-
});
|
|
1062
|
-
server.tool({
|
|
1063
|
-
name: "resolve-method-mapping-exact",
|
|
1064
|
-
description: "Resolve one method mapping exactly by owner+name+descriptor between namespaces and report resolved/not_found/ambiguous.",
|
|
1065
|
-
inputs: [
|
|
1066
|
-
{ name: "version", type: "string", required: true },
|
|
1067
|
-
{ name: "kind", type: "string", required: true, description: "class | field | method" },
|
|
1068
|
-
{ name: "name", type: "string", required: true },
|
|
1069
|
-
{ name: "owner", type: "string" },
|
|
1070
|
-
{ name: "descriptor", type: "string", description: "required for kind=method" },
|
|
1071
|
-
{ name: "sourceMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1072
|
-
{ name: "targetMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1073
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1074
|
-
],
|
|
1075
|
-
annotations: {
|
|
1076
|
-
readOnlyHint: true
|
|
1077
|
-
}
|
|
1078
|
-
}, async (rawInput) => {
|
|
1079
|
-
return runTool("resolve-method-mapping-exact", rawInput, resolveMethodMappingExactSchema, async (input) => sourceService.resolveMethodMappingExact({
|
|
1080
|
-
version: input.version,
|
|
1081
|
-
kind: input.kind,
|
|
1082
|
-
name: input.name,
|
|
1083
|
-
owner: input.owner,
|
|
1084
|
-
descriptor: input.descriptor,
|
|
1085
|
-
sourceMapping: input.sourceMapping,
|
|
1086
|
-
targetMapping: input.targetMapping,
|
|
1087
|
-
sourcePriority: input.sourcePriority
|
|
1088
|
-
}));
|
|
1089
|
-
});
|
|
1090
|
-
server.tool({
|
|
1091
|
-
name: "get-class-api-matrix",
|
|
1092
|
-
description: "List class/member API rows across official/mojang/intermediary/yarn mappings for one class and Minecraft version.",
|
|
1093
|
-
inputs: [
|
|
1094
|
-
{ name: "version", type: "string", required: true },
|
|
1095
|
-
{ name: "className", type: "string", required: true },
|
|
1096
|
-
{ name: "classNameMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1097
|
-
{ name: "includeKinds", type: "string", description: "comma-separated: class,field,method" },
|
|
1098
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1099
|
-
],
|
|
1100
|
-
annotations: {
|
|
1101
|
-
readOnlyHint: true
|
|
1102
|
-
}
|
|
1103
|
-
}, async (rawInput) => {
|
|
1104
|
-
return runTool("get-class-api-matrix", rawInput, getClassApiMatrixSchema, async (input) => sourceService.getClassApiMatrix({
|
|
1105
|
-
version: input.version,
|
|
1106
|
-
className: input.className,
|
|
1107
|
-
classNameMapping: input.classNameMapping,
|
|
1108
|
-
includeKinds: parseClassApiKinds(input.includeKinds),
|
|
1109
|
-
sourcePriority: input.sourcePriority
|
|
1110
|
-
}));
|
|
1111
|
-
});
|
|
1112
|
-
server.tool({
|
|
1113
|
-
name: "resolve-workspace-symbol",
|
|
1114
|
-
description: "Resolve class/field/method names as seen at compile time for a workspace by reading Gradle Loom mapping settings.",
|
|
1115
|
-
inputs: [
|
|
1116
|
-
{ name: "projectPath", type: "string", required: true },
|
|
1117
|
-
{ name: "version", type: "string", required: true },
|
|
1118
|
-
{ name: "kind", type: "string", required: true, description: "class | field | method" },
|
|
1119
|
-
{ name: "name", type: "string", required: true },
|
|
1120
|
-
{ name: "owner", type: "string" },
|
|
1121
|
-
{ name: "descriptor", type: "string" },
|
|
1122
|
-
{ name: "sourceMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1123
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1124
|
-
],
|
|
1125
|
-
annotations: {
|
|
1126
|
-
readOnlyHint: true
|
|
1127
|
-
}
|
|
1128
|
-
}, async (rawInput) => {
|
|
1129
|
-
return runTool("resolve-workspace-symbol", rawInput, resolveWorkspaceSymbolSchema, async (input) => sourceService.resolveWorkspaceSymbol({
|
|
1130
|
-
projectPath: input.projectPath,
|
|
1131
|
-
version: input.version,
|
|
1132
|
-
kind: input.kind,
|
|
1133
|
-
name: input.name,
|
|
1134
|
-
owner: input.owner,
|
|
1135
|
-
descriptor: input.descriptor,
|
|
1136
|
-
sourceMapping: input.sourceMapping,
|
|
1137
|
-
sourcePriority: input.sourcePriority
|
|
1138
|
-
}));
|
|
1139
|
-
});
|
|
1140
|
-
server.tool({
|
|
1141
|
-
name: "check-symbol-exists",
|
|
1142
|
-
description: "Check whether a class/field/method symbol exists in a specific mapping namespace for one Minecraft version.",
|
|
1143
|
-
inputs: [
|
|
1144
|
-
{ name: "version", type: "string", required: true },
|
|
1145
|
-
{ name: "kind", type: "string", required: true, description: "class | field | method" },
|
|
1146
|
-
{ name: "owner", type: "string" },
|
|
1147
|
-
{ name: "name", type: "string", required: true },
|
|
1148
|
-
{ name: "descriptor", type: "string", description: "required for kind=method" },
|
|
1149
|
-
{ name: "sourceMapping", type: "string", required: true, description: "official | mojang | intermediary | yarn" },
|
|
1150
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1151
|
-
],
|
|
1152
|
-
annotations: {
|
|
1153
|
-
readOnlyHint: true
|
|
1154
|
-
}
|
|
1155
|
-
}, async (rawInput) => {
|
|
1156
|
-
return runTool("check-symbol-exists", rawInput, checkSymbolExistsSchema, async (input) => sourceService.checkSymbolExists({
|
|
1157
|
-
version: input.version,
|
|
1158
|
-
kind: input.kind,
|
|
1159
|
-
owner: input.owner,
|
|
1160
|
-
name: input.name,
|
|
1161
|
-
descriptor: input.descriptor,
|
|
1162
|
-
sourceMapping: input.sourceMapping,
|
|
1163
|
-
sourcePriority: input.sourcePriority
|
|
1164
|
-
}));
|
|
1165
|
-
});
|
|
1166
|
-
server.tool({
|
|
1167
|
-
name: "nbt-to-json",
|
|
1168
|
-
description: "Decode Java Edition NBT binary payload (base64) into typed JSON.",
|
|
1169
|
-
inputs: [
|
|
1170
|
-
{ name: "nbtBase64", type: "string", required: true },
|
|
1171
|
-
{ name: "compression", type: "string", description: "none | gzip | auto (default auto)" }
|
|
1172
|
-
],
|
|
1173
|
-
annotations: {
|
|
1174
|
-
readOnlyHint: true
|
|
1175
|
-
}
|
|
1176
|
-
}, async (rawInput) => {
|
|
1177
|
-
return runTool("nbt-to-json", rawInput, nbtToJsonSchema, async (input) => Promise.resolve(nbtBase64ToTypedJson({
|
|
1178
|
-
nbtBase64: input.nbtBase64,
|
|
1179
|
-
compression: input.compression
|
|
1180
|
-
}, nbtLimits)));
|
|
1181
|
-
});
|
|
1182
|
-
server.tool({
|
|
1183
|
-
name: "nbt-apply-json-patch",
|
|
1184
|
-
description: "Apply RFC6902 add/remove/replace/test operations to typed NBT JSON.",
|
|
1185
|
-
inputs: [
|
|
1186
|
-
{ name: "typedJson", type: "object", required: true },
|
|
1187
|
-
{
|
|
1188
|
-
name: "patch",
|
|
1189
|
-
type: "array",
|
|
1190
|
-
required: true,
|
|
1191
|
-
description: "RFC6902 operation array (add/remove/replace/test)"
|
|
1192
|
-
}
|
|
1193
|
-
],
|
|
1194
|
-
annotations: {
|
|
1195
|
-
readOnlyHint: true
|
|
1196
|
-
}
|
|
1197
|
-
}, async (rawInput) => {
|
|
1198
|
-
return runTool("nbt-apply-json-patch", rawInput, nbtApplyJsonPatchSchema, async (input) => Promise.resolve(applyNbtJsonPatch({
|
|
1199
|
-
typedJson: input.typedJson,
|
|
1200
|
-
patch: input.patch
|
|
1201
|
-
}, nbtLimits)));
|
|
1202
|
-
});
|
|
1203
|
-
server.tool({
|
|
1204
|
-
name: "json-to-nbt",
|
|
1205
|
-
description: "Encode typed NBT JSON to Java Edition NBT binary payload (base64).",
|
|
1206
|
-
inputs: [
|
|
1207
|
-
{ name: "typedJson", type: "object", required: true },
|
|
1208
|
-
{ name: "compression", type: "string", description: "none | gzip (default none)" }
|
|
1209
|
-
],
|
|
1210
|
-
annotations: {
|
|
1211
|
-
readOnlyHint: true
|
|
1212
|
-
}
|
|
1213
|
-
}, async (rawInput) => {
|
|
1214
|
-
return runTool("json-to-nbt", rawInput, jsonToNbtSchema, async (input) => Promise.resolve(typedJsonToNbtBase64({
|
|
1215
|
-
typedJson: input.typedJson,
|
|
1216
|
-
compression: input.compression
|
|
1217
|
-
}, nbtLimits)));
|
|
1218
|
-
});
|
|
1219
|
-
server.tool({
|
|
1220
|
-
name: "index-artifact",
|
|
1221
|
-
description: "Rebuild indexed files/symbols metadata for an existing artifactId. Does not resolve new artifacts.",
|
|
1222
|
-
inputs: [
|
|
1223
|
-
{ name: "artifactId", type: "string", required: true },
|
|
1224
|
-
{ name: "force", type: "boolean", description: "default false" }
|
|
1225
|
-
]
|
|
1226
|
-
}, async (rawInput) => {
|
|
1227
|
-
return runTool("index-artifact", rawInput, indexArtifactSchema, async (input) => sourceService.indexArtifact({
|
|
1228
|
-
artifactId: input.artifactId,
|
|
1229
|
-
force: input.force
|
|
1230
|
-
}));
|
|
1231
|
-
});
|
|
1232
|
-
server.tool({
|
|
1233
|
-
name: "get-runtime-metrics",
|
|
1234
|
-
description: "Get runtime service counters and latency snapshots for cache/search/index diagnostics.",
|
|
1235
|
-
annotations: {
|
|
1236
|
-
readOnlyHint: true
|
|
1237
|
-
}
|
|
1238
|
-
}, async (rawInput) => {
|
|
1239
|
-
return runTool("get-runtime-metrics", rawInput, emptySchema, async () => Promise.resolve(sourceService.getRuntimeMetrics()));
|
|
1240
|
-
});
|
|
1241
|
-
server.tool({
|
|
1242
|
-
name: "validate-mixin",
|
|
1243
|
-
description: "Validate Mixin source against Minecraft bytecode signatures for a given version.",
|
|
1244
|
-
inputs: [
|
|
1245
|
-
{ name: "source", type: "string", required: true, description: "Mixin Java source text" },
|
|
1246
|
-
{ name: "version", type: "string", required: true, description: "Minecraft version" },
|
|
1247
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn" },
|
|
1248
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1249
|
-
],
|
|
1250
|
-
annotations: {
|
|
1251
|
-
readOnlyHint: true
|
|
1252
|
-
}
|
|
1253
|
-
}, async (rawInput) => {
|
|
1254
|
-
return runTool("validate-mixin", rawInput, validateMixinSchema, async (input) => sourceService.validateMixin({
|
|
1255
|
-
source: input.source,
|
|
1256
|
-
version: input.version,
|
|
1257
|
-
mapping: input.mapping,
|
|
1258
|
-
sourcePriority: input.sourcePriority
|
|
1259
|
-
}));
|
|
1260
|
-
});
|
|
1261
|
-
server.tool({
|
|
1262
|
-
name: "validate-access-widener",
|
|
1263
|
-
description: "Validate Access Widener file entries against Minecraft bytecode signatures for a given version.",
|
|
1264
|
-
inputs: [
|
|
1265
|
-
{ name: "content", type: "string", required: true, description: "Access Widener file content" },
|
|
1266
|
-
{ name: "version", type: "string", required: true, description: "Minecraft version" },
|
|
1267
|
-
{ name: "mapping", type: "string", description: "official | mojang | intermediary | yarn" },
|
|
1268
|
-
{ name: "sourcePriority", type: "string", description: "loom-first | maven-first" }
|
|
1269
|
-
],
|
|
1270
|
-
annotations: {
|
|
1271
|
-
readOnlyHint: true
|
|
1272
|
-
}
|
|
1273
|
-
}, async (rawInput) => {
|
|
1274
|
-
return runTool("validate-access-widener", rawInput, validateAccessWidenerSchema, async (input) => sourceService.validateAccessWidener({
|
|
1275
|
-
content: input.content,
|
|
1276
|
-
version: input.version,
|
|
1277
|
-
mapping: input.mapping,
|
|
1278
|
-
sourcePriority: input.sourcePriority
|
|
1279
|
-
}));
|
|
1280
|
-
});
|
|
1281
|
-
server.tool({
|
|
1282
|
-
name: "analyze-mod-jar",
|
|
1283
|
-
description: "Analyze a Minecraft mod JAR to extract loader type, metadata, entrypoints, mixins, and dependencies.",
|
|
1284
|
-
inputs: [
|
|
1285
|
-
{ name: "jarPath", type: "string", required: true, description: "Local path to the mod JAR file" },
|
|
1286
|
-
{ name: "includeClasses", type: "boolean", description: "Include full class listing (default false)" }
|
|
1287
|
-
],
|
|
1288
|
-
annotations: {
|
|
1289
|
-
readOnlyHint: true
|
|
1290
|
-
}
|
|
1291
|
-
}, async (rawInput) => {
|
|
1292
|
-
return runTool("analyze-mod-jar", rawInput, analyzeModJarSchema, async (input) => {
|
|
1293
|
-
const result = await analyzeModJar(input.jarPath, {
|
|
1294
|
-
includeClasses: input.includeClasses ?? false
|
|
1295
|
-
});
|
|
1296
|
-
return result;
|
|
1297
|
-
});
|
|
1298
|
-
});
|
|
1299
|
-
server.tool({
|
|
1300
|
-
name: "get-registry-data",
|
|
1301
|
-
description: "Get Minecraft registry data (blocks, items, biomes, etc.) for a specific version by running the server data generator.",
|
|
1302
|
-
inputs: [
|
|
1303
|
-
{ name: "version", type: "string", required: true, description: "Minecraft version (e.g. 1.21)" },
|
|
1304
|
-
{
|
|
1305
|
-
name: "registry",
|
|
1306
|
-
type: "string",
|
|
1307
|
-
description: 'Optional registry name (e.g. "block", "item", "minecraft:biome"). Omit to list all registries.'
|
|
822
|
+
server.tool("list-versions", "List available Minecraft versions from Mojang manifest and locally cached version jars.", listVersionsShape, { readOnlyHint: true }, async (args) => runTool("list-versions", args, listVersionsSchema, async (input) => sourceService.listVersions({
|
|
823
|
+
includeSnapshots: input.includeSnapshots,
|
|
824
|
+
limit: input.limit
|
|
825
|
+
})));
|
|
826
|
+
server.tool("resolve-artifact", "Resolve source artifact from version, jar path, or Maven coordinate and return artifact metadata. For targetKind=jar, only <basename>-sources.jar is auto-adopted; other adjacent *-sources.jar files are informational.", resolveArtifactShape, { readOnlyHint: true }, async (args) => runTool("resolve-artifact", args, resolveArtifactSchema, async (input) => sourceService.resolveArtifact({
|
|
827
|
+
target: {
|
|
828
|
+
kind: input.targetKind,
|
|
829
|
+
value: input.targetValue
|
|
830
|
+
},
|
|
831
|
+
mapping: input.mapping,
|
|
832
|
+
sourcePriority: input.sourcePriority,
|
|
833
|
+
allowDecompile: input.allowDecompile
|
|
834
|
+
})));
|
|
835
|
+
server.tool("get-class-source", "Get Java source for a class by artifactId or by resolving target (version/jar/coordinate), with optional line-range filtering.", getClassSourceShape, { readOnlyHint: true }, async (args) => runTool("get-class-source", args, getClassSourceSchema, async (input) => sourceService.getClassSource({
|
|
836
|
+
className: input.className,
|
|
837
|
+
artifactId: input.artifactId,
|
|
838
|
+
target: buildTarget(input.targetKind, input.targetValue),
|
|
839
|
+
mapping: input.mapping,
|
|
840
|
+
sourcePriority: input.sourcePriority,
|
|
841
|
+
allowDecompile: input.allowDecompile,
|
|
842
|
+
startLine: input.startLine,
|
|
843
|
+
endLine: input.endLine,
|
|
844
|
+
maxLines: input.maxLines
|
|
845
|
+
})));
|
|
846
|
+
server.tool("get-class-members", "Get fields/methods/constructors for one class from binary bytecode by artifactId or by resolving target (version/jar/coordinate).", getClassMembersShape, { readOnlyHint: true }, async (args) => runTool("get-class-members", args, getClassMembersSchema, async (input) => sourceService.getClassMembers({
|
|
847
|
+
className: input.className,
|
|
848
|
+
artifactId: input.artifactId,
|
|
849
|
+
target: buildTarget(input.targetKind, input.targetValue),
|
|
850
|
+
mapping: input.mapping,
|
|
851
|
+
sourcePriority: input.sourcePriority,
|
|
852
|
+
allowDecompile: input.allowDecompile,
|
|
853
|
+
access: input.access,
|
|
854
|
+
includeSynthetic: input.includeSynthetic,
|
|
855
|
+
includeInherited: input.includeInherited,
|
|
856
|
+
memberPattern: input.memberPattern,
|
|
857
|
+
maxMembers: input.maxMembers
|
|
858
|
+
})));
|
|
859
|
+
server.tool("search-class-source", "Search indexed class source files for one artifact with symbol/text/path intent and optional one-hop relation expansion.", searchClassSourceShape, { readOnlyHint: true }, async (args) => runTool("search-class-source", args, searchClassSourceSchema, async (input) => {
|
|
860
|
+
const scope = input.packagePrefix || input.fileGlob || input.symbolKind
|
|
861
|
+
? {
|
|
862
|
+
packagePrefix: input.packagePrefix,
|
|
863
|
+
fileGlob: input.fileGlob,
|
|
864
|
+
symbolKind: input.symbolKind
|
|
1308
865
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
}));
|
|
1318
|
-
});
|
|
1319
|
-
server.tool({
|
|
1320
|
-
name: "compare-versions",
|
|
1321
|
-
description: "Compare two Minecraft versions to find added/removed classes and registry entry changes. Useful for understanding what changed between versions during mod migration.",
|
|
1322
|
-
inputs: [
|
|
1323
|
-
{ name: "fromVersion", type: "string", required: true, description: "Older Minecraft version (e.g. 1.20.4)" },
|
|
1324
|
-
{ name: "toVersion", type: "string", required: true, description: "Newer Minecraft version (e.g. 1.21)" },
|
|
1325
|
-
{
|
|
1326
|
-
name: "category",
|
|
1327
|
-
type: "string",
|
|
1328
|
-
description: "classes | registry | all (default all)"
|
|
1329
|
-
},
|
|
1330
|
-
{ name: "packageFilter", type: "string", description: "Filter classes to a package prefix (e.g. net.minecraft.world.item)" },
|
|
1331
|
-
{ name: "maxClassResults", type: "number", description: "Max class results per direction (default 500, max 5000)" }
|
|
1332
|
-
],
|
|
1333
|
-
annotations: {
|
|
1334
|
-
readOnlyHint: true
|
|
1335
|
-
}
|
|
1336
|
-
}, async (rawInput) => {
|
|
1337
|
-
return runTool("compare-versions", rawInput, compareVersionsSchema, async (input) => sourceService.compareVersions({
|
|
1338
|
-
fromVersion: input.fromVersion,
|
|
1339
|
-
toVersion: input.toVersion,
|
|
1340
|
-
category: input.category,
|
|
1341
|
-
packageFilter: input.packageFilter,
|
|
1342
|
-
maxClassResults: input.maxClassResults
|
|
1343
|
-
}));
|
|
1344
|
-
});
|
|
1345
|
-
server.tool({
|
|
1346
|
-
name: "decompile-mod-jar",
|
|
1347
|
-
description: "Decompile a Minecraft mod JAR using Vineflower and list available classes, or view a specific class source. Builds on analyze-mod-jar by exposing the actual source code.",
|
|
1348
|
-
inputs: [
|
|
1349
|
-
{ name: "jarPath", type: "string", required: true, description: "Local path to the mod JAR file" },
|
|
1350
|
-
{
|
|
1351
|
-
name: "className",
|
|
1352
|
-
type: "string",
|
|
1353
|
-
description: "Optional fully-qualified class name to view source. Omit to list all classes."
|
|
866
|
+
: undefined;
|
|
867
|
+
const include = input.snippetLines !== undefined ||
|
|
868
|
+
input.includeDefinition !== undefined ||
|
|
869
|
+
input.includeOneHop !== undefined
|
|
870
|
+
? {
|
|
871
|
+
snippetLines: input.snippetLines,
|
|
872
|
+
includeDefinition: input.includeDefinition,
|
|
873
|
+
includeOneHop: input.includeOneHop
|
|
1354
874
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
}
|
|
1359
|
-
}, async (rawInput) => {
|
|
1360
|
-
return runTool("decompile-mod-jar", rawInput, decompileModJarSchema, async (input) => sourceService.decompileModJar({
|
|
1361
|
-
jarPath: input.jarPath,
|
|
1362
|
-
className: input.className
|
|
1363
|
-
}));
|
|
1364
|
-
});
|
|
1365
|
-
server.tool({
|
|
1366
|
-
name: "get-mod-class-source",
|
|
1367
|
-
description: "Get decompiled source code for a specific class in a mod JAR. The mod JAR will be decompiled if not already cached.",
|
|
1368
|
-
inputs: [
|
|
1369
|
-
{ name: "jarPath", type: "string", required: true, description: "Local path to the mod JAR file" },
|
|
1370
|
-
{ name: "className", type: "string", required: true, description: "Fully-qualified class name (e.g. com.example.MyMixin)" }
|
|
1371
|
-
],
|
|
1372
|
-
annotations: {
|
|
1373
|
-
readOnlyHint: true
|
|
1374
|
-
}
|
|
1375
|
-
}, async (rawInput) => {
|
|
1376
|
-
return runTool("get-mod-class-source", rawInput, getModClassSourceSchema, async (input) => sourceService.getModClassSource({
|
|
1377
|
-
jarPath: input.jarPath,
|
|
1378
|
-
className: input.className
|
|
1379
|
-
}));
|
|
1380
|
-
});
|
|
1381
|
-
server.tool({
|
|
1382
|
-
name: "search-mod-source",
|
|
1383
|
-
description: "Search through decompiled mod JAR source code by class name, method, field, or content pattern. The mod JAR will be decompiled automatically if not already cached.",
|
|
1384
|
-
inputs: [
|
|
1385
|
-
{ name: "jarPath", type: "string", required: true, description: "Local path to the mod JAR file" },
|
|
1386
|
-
{ name: "query", type: "string", required: true, description: "Search pattern (regex or literal string)" },
|
|
1387
|
-
{
|
|
1388
|
-
name: "searchType",
|
|
1389
|
-
type: "string",
|
|
1390
|
-
description: "class | method | field | content | all (default all)"
|
|
1391
|
-
},
|
|
1392
|
-
{ name: "limit", type: "number", description: "Max results (default 50, max 200)" }
|
|
1393
|
-
],
|
|
1394
|
-
annotations: {
|
|
1395
|
-
readOnlyHint: true
|
|
1396
|
-
}
|
|
1397
|
-
}, async (rawInput) => {
|
|
1398
|
-
return runTool("search-mod-source", rawInput, searchModSourceSchema, async (input) => sourceService.searchModSource({
|
|
1399
|
-
jarPath: input.jarPath,
|
|
875
|
+
: undefined;
|
|
876
|
+
return sourceService.searchClassSource({
|
|
877
|
+
artifactId: input.artifactId,
|
|
1400
878
|
query: input.query,
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
description: "Remap a Fabric mod JAR from intermediary to yarn/mojang names. Requires Java to be installed.",
|
|
1408
|
-
inputs: [
|
|
1409
|
-
{ name: "inputJar", type: "string", required: true, description: "Path to the mod JAR file" },
|
|
1410
|
-
{ name: "outputJar", type: "string", description: "Output path for remapped JAR (auto-generated if omitted)" },
|
|
1411
|
-
{
|
|
1412
|
-
name: "mcVersion",
|
|
1413
|
-
type: "string",
|
|
1414
|
-
description: "Minecraft version (auto-detected from mod metadata if omitted)"
|
|
1415
|
-
},
|
|
1416
|
-
{ name: "targetMapping", type: "string", required: true, description: "yarn | mojang" }
|
|
1417
|
-
],
|
|
1418
|
-
annotations: {
|
|
1419
|
-
readOnlyHint: false
|
|
1420
|
-
}
|
|
1421
|
-
}, async (rawInput) => {
|
|
1422
|
-
return runTool("remap-mod-jar", rawInput, remapModJarSchema, async (input) => {
|
|
1423
|
-
const result = await remapModJar({
|
|
1424
|
-
inputJar: input.inputJar,
|
|
1425
|
-
outputJar: input.outputJar,
|
|
1426
|
-
mcVersion: input.mcVersion,
|
|
1427
|
-
targetMapping: input.targetMapping
|
|
1428
|
-
}, config);
|
|
1429
|
-
return result;
|
|
879
|
+
intent: input.intent,
|
|
880
|
+
match: input.match,
|
|
881
|
+
scope: scope,
|
|
882
|
+
include,
|
|
883
|
+
limit: input.limit,
|
|
884
|
+
cursor: input.cursor
|
|
1430
885
|
});
|
|
1431
|
-
});
|
|
1432
|
-
|
|
886
|
+
}));
|
|
887
|
+
server.tool("get-artifact-file", "Get full source file content by artifactId and file path.", getArtifactFileShape, { readOnlyHint: true }, async (args) => runTool("get-artifact-file", args, getArtifactFileSchema, async (input) => sourceService.getArtifactFile({
|
|
888
|
+
artifactId: input.artifactId,
|
|
889
|
+
filePath: input.filePath,
|
|
890
|
+
maxBytes: input.maxBytes
|
|
891
|
+
})));
|
|
892
|
+
server.tool("list-artifact-files", "List source file paths in an artifact with optional prefix filter and cursor-based pagination.", listArtifactFilesShape, { readOnlyHint: true }, async (args) => runTool("list-artifact-files", args, listArtifactFilesSchema, async (input) => sourceService.listArtifactFiles(input)));
|
|
893
|
+
server.tool("trace-symbol-lifecycle", "Trace which Minecraft versions contain a specific class method and report first/last seen versions.", traceSymbolLifecycleShape, { readOnlyHint: true }, async (args) => runTool("trace-symbol-lifecycle", args, traceSymbolLifecycleSchema, async (input) => sourceService.traceSymbolLifecycle({
|
|
894
|
+
symbol: input.symbol,
|
|
895
|
+
descriptor: input.descriptor,
|
|
896
|
+
fromVersion: input.fromVersion,
|
|
897
|
+
toVersion: input.toVersion,
|
|
898
|
+
mapping: input.mapping,
|
|
899
|
+
sourcePriority: input.sourcePriority,
|
|
900
|
+
includeSnapshots: input.includeSnapshots,
|
|
901
|
+
maxVersions: input.maxVersions,
|
|
902
|
+
includeTimeline: input.includeTimeline
|
|
903
|
+
})));
|
|
904
|
+
server.tool("diff-class-signatures", "Compare one class signature between two Minecraft versions and report added/removed/modified constructors, methods, and fields.", diffClassSignaturesShape, { readOnlyHint: true }, async (args) => runTool("diff-class-signatures", args, diffClassSignaturesSchema, async (input) => sourceService.diffClassSignatures({
|
|
905
|
+
className: input.className,
|
|
906
|
+
fromVersion: input.fromVersion,
|
|
907
|
+
toVersion: input.toVersion,
|
|
908
|
+
mapping: input.mapping,
|
|
909
|
+
sourcePriority: input.sourcePriority
|
|
910
|
+
})));
|
|
911
|
+
server.tool("find-mapping", "Find symbol mapping candidates between namespaces using structured symbol inputs for a specific Minecraft version.", findMappingShape, { readOnlyHint: true }, async (args) => runTool("find-mapping", args, findMappingSchema, async (input) => sourceService.findMapping({
|
|
912
|
+
version: input.version,
|
|
913
|
+
kind: input.kind,
|
|
914
|
+
name: input.name,
|
|
915
|
+
owner: input.owner,
|
|
916
|
+
descriptor: input.descriptor,
|
|
917
|
+
sourceMapping: input.sourceMapping,
|
|
918
|
+
targetMapping: input.targetMapping,
|
|
919
|
+
sourcePriority: input.sourcePriority
|
|
920
|
+
})));
|
|
921
|
+
server.tool("resolve-method-mapping-exact", "Resolve one method mapping exactly by owner+name+descriptor between namespaces and report resolved/not_found/ambiguous.", resolveMethodMappingExactShape, { readOnlyHint: true }, async (args) => runTool("resolve-method-mapping-exact", args, resolveMethodMappingExactSchema, async (input) => sourceService.resolveMethodMappingExact({
|
|
922
|
+
version: input.version,
|
|
923
|
+
kind: input.kind,
|
|
924
|
+
name: input.name,
|
|
925
|
+
owner: input.owner,
|
|
926
|
+
descriptor: input.descriptor,
|
|
927
|
+
sourceMapping: input.sourceMapping,
|
|
928
|
+
targetMapping: input.targetMapping,
|
|
929
|
+
sourcePriority: input.sourcePriority
|
|
930
|
+
})));
|
|
931
|
+
server.tool("get-class-api-matrix", "List class/member API rows across official/mojang/intermediary/yarn mappings for one class and Minecraft version.", getClassApiMatrixShape, { readOnlyHint: true }, async (args) => runTool("get-class-api-matrix", args, getClassApiMatrixSchema, async (input) => sourceService.getClassApiMatrix({
|
|
932
|
+
version: input.version,
|
|
933
|
+
className: input.className,
|
|
934
|
+
classNameMapping: input.classNameMapping,
|
|
935
|
+
includeKinds: parseClassApiKinds(input.includeKinds),
|
|
936
|
+
sourcePriority: input.sourcePriority
|
|
937
|
+
})));
|
|
938
|
+
server.tool("resolve-workspace-symbol", "Resolve class/field/method names as seen at compile time for a workspace by reading Gradle Loom mapping settings.", resolveWorkspaceSymbolShape, { readOnlyHint: true }, async (args) => runTool("resolve-workspace-symbol", args, resolveWorkspaceSymbolSchema, async (input) => sourceService.resolveWorkspaceSymbol({
|
|
939
|
+
projectPath: input.projectPath,
|
|
940
|
+
version: input.version,
|
|
941
|
+
kind: input.kind,
|
|
942
|
+
name: input.name,
|
|
943
|
+
owner: input.owner,
|
|
944
|
+
descriptor: input.descriptor,
|
|
945
|
+
sourceMapping: input.sourceMapping,
|
|
946
|
+
sourcePriority: input.sourcePriority
|
|
947
|
+
})));
|
|
948
|
+
server.tool("check-symbol-exists", "Check whether a class/field/method symbol exists in a specific mapping namespace for one Minecraft version.", checkSymbolExistsShape, { readOnlyHint: true }, async (args) => runTool("check-symbol-exists", args, checkSymbolExistsSchema, async (input) => sourceService.checkSymbolExists({
|
|
949
|
+
version: input.version,
|
|
950
|
+
kind: input.kind,
|
|
951
|
+
owner: input.owner,
|
|
952
|
+
name: input.name,
|
|
953
|
+
descriptor: input.descriptor,
|
|
954
|
+
sourceMapping: input.sourceMapping,
|
|
955
|
+
sourcePriority: input.sourcePriority
|
|
956
|
+
})));
|
|
957
|
+
server.tool("nbt-to-json", "Decode Java Edition NBT binary payload (base64) into typed JSON.", nbtToJsonShape, { readOnlyHint: true }, async (args) => runTool("nbt-to-json", args, nbtToJsonSchema, async (input) => Promise.resolve(nbtBase64ToTypedJson({
|
|
958
|
+
nbtBase64: input.nbtBase64,
|
|
959
|
+
compression: input.compression
|
|
960
|
+
}, nbtLimits))));
|
|
961
|
+
server.tool("nbt-apply-json-patch", "Apply RFC6902 add/remove/replace/test operations to typed NBT JSON.", nbtApplyJsonPatchShape, { readOnlyHint: true }, async (args) => runTool("nbt-apply-json-patch", args, nbtApplyJsonPatchSchema, async (input) => Promise.resolve(applyNbtJsonPatch({
|
|
962
|
+
typedJson: input.typedJson,
|
|
963
|
+
patch: input.patch
|
|
964
|
+
}, nbtLimits))));
|
|
965
|
+
server.tool("json-to-nbt", "Encode typed NBT JSON to Java Edition NBT binary payload (base64).", jsonToNbtShape, { readOnlyHint: true }, async (args) => runTool("json-to-nbt", args, jsonToNbtSchema, async (input) => Promise.resolve(typedJsonToNbtBase64({
|
|
966
|
+
typedJson: input.typedJson,
|
|
967
|
+
compression: input.compression
|
|
968
|
+
}, nbtLimits))));
|
|
969
|
+
server.tool("index-artifact", "Rebuild indexed files/symbols metadata for an existing artifactId. Does not resolve new artifacts.", indexArtifactShape, async (args) => runTool("index-artifact", args, indexArtifactSchema, async (input) => sourceService.indexArtifact({
|
|
970
|
+
artifactId: input.artifactId,
|
|
971
|
+
force: input.force
|
|
972
|
+
})));
|
|
973
|
+
server.tool("get-runtime-metrics", "Get runtime service counters and latency snapshots for cache/search/index diagnostics.", { readOnlyHint: true }, async (args) => runTool("get-runtime-metrics", args, emptySchema, async () => Promise.resolve(sourceService.getRuntimeMetrics())));
|
|
974
|
+
server.tool("validate-mixin", "Validate Mixin source against Minecraft bytecode signatures for a given version.", validateMixinShape, { readOnlyHint: true }, async (args) => runTool("validate-mixin", args, validateMixinSchema, async (input) => sourceService.validateMixin({
|
|
975
|
+
source: input.source,
|
|
976
|
+
version: input.version,
|
|
977
|
+
mapping: input.mapping,
|
|
978
|
+
sourcePriority: input.sourcePriority
|
|
979
|
+
})));
|
|
980
|
+
server.tool("validate-access-widener", "Validate Access Widener file entries against Minecraft bytecode signatures for a given version.", validateAccessWidenerShape, { readOnlyHint: true }, async (args) => runTool("validate-access-widener", args, validateAccessWidenerSchema, async (input) => sourceService.validateAccessWidener({
|
|
981
|
+
content: input.content,
|
|
982
|
+
version: input.version,
|
|
983
|
+
mapping: input.mapping,
|
|
984
|
+
sourcePriority: input.sourcePriority
|
|
985
|
+
})));
|
|
986
|
+
server.tool("analyze-mod-jar", "Analyze a Minecraft mod JAR to extract loader type, metadata, entrypoints, mixins, and dependencies.", analyzeModJarShape, { readOnlyHint: true }, async (args) => runTool("analyze-mod-jar", args, analyzeModJarSchema, async (input) => {
|
|
987
|
+
const result = await analyzeModJar(input.jarPath, {
|
|
988
|
+
includeClasses: input.includeClasses ?? false
|
|
989
|
+
});
|
|
990
|
+
return result;
|
|
991
|
+
}));
|
|
992
|
+
server.tool("get-registry-data", "Get Minecraft registry data (blocks, items, biomes, etc.) for a specific version by running the server data generator.", getRegistryDataShape, { readOnlyHint: true }, async (args) => runTool("get-registry-data", args, getRegistryDataSchema, async (input) => sourceService.getRegistryData({
|
|
993
|
+
version: input.version,
|
|
994
|
+
registry: input.registry
|
|
995
|
+
})));
|
|
996
|
+
server.tool("compare-versions", "Compare two Minecraft versions to find added/removed classes and registry entry changes. Useful for understanding what changed between versions during mod migration.", compareVersionsShape, { readOnlyHint: true }, async (args) => runTool("compare-versions", args, compareVersionsSchema, async (input) => sourceService.compareVersions({
|
|
997
|
+
fromVersion: input.fromVersion,
|
|
998
|
+
toVersion: input.toVersion,
|
|
999
|
+
category: input.category,
|
|
1000
|
+
packageFilter: input.packageFilter,
|
|
1001
|
+
maxClassResults: input.maxClassResults
|
|
1002
|
+
})));
|
|
1003
|
+
server.tool("decompile-mod-jar", "Decompile a Minecraft mod JAR using Vineflower and list available classes, or view a specific class source. Builds on analyze-mod-jar by exposing the actual source code.", decompileModJarShape, { readOnlyHint: true }, async (args) => runTool("decompile-mod-jar", args, decompileModJarSchema, async (input) => sourceService.decompileModJar({
|
|
1004
|
+
jarPath: input.jarPath,
|
|
1005
|
+
className: input.className
|
|
1006
|
+
})));
|
|
1007
|
+
server.tool("get-mod-class-source", "Get decompiled source code for a specific class in a mod JAR. The mod JAR will be decompiled if not already cached.", getModClassSourceShape, { readOnlyHint: true }, async (args) => runTool("get-mod-class-source", args, getModClassSourceSchema, async (input) => sourceService.getModClassSource({
|
|
1008
|
+
jarPath: input.jarPath,
|
|
1009
|
+
className: input.className
|
|
1010
|
+
})));
|
|
1011
|
+
server.tool("search-mod-source", "Search through decompiled mod JAR source code by class name, method, field, or content pattern. The mod JAR will be decompiled automatically if not already cached.", searchModSourceShape, { readOnlyHint: true }, async (args) => runTool("search-mod-source", args, searchModSourceSchema, async (input) => sourceService.searchModSource({
|
|
1012
|
+
jarPath: input.jarPath,
|
|
1013
|
+
query: input.query,
|
|
1014
|
+
searchType: input.searchType,
|
|
1015
|
+
limit: input.limit
|
|
1016
|
+
})));
|
|
1017
|
+
server.tool("remap-mod-jar", "Remap a Fabric mod JAR from intermediary to yarn/mojang names. Requires Java to be installed.", remapModJarShape, { readOnlyHint: false }, async (args) => runTool("remap-mod-jar", args, remapModJarSchema, async (input) => {
|
|
1018
|
+
const result = await remapModJar({
|
|
1019
|
+
inputJar: input.inputJar,
|
|
1020
|
+
outputJar: input.outputJar,
|
|
1021
|
+
mcVersion: input.mcVersion,
|
|
1022
|
+
targetMapping: input.targetMapping
|
|
1023
|
+
}, config);
|
|
1024
|
+
return result;
|
|
1025
|
+
}));
|
|
1026
|
+
export async function startServer() {
|
|
1433
1027
|
if (serverStarted) {
|
|
1434
1028
|
return;
|
|
1435
1029
|
}
|
|
@@ -1440,7 +1034,10 @@ export function startServer() {
|
|
|
1440
1034
|
sqlitePath: config.sqlitePath,
|
|
1441
1035
|
sourceRepos: config.sourceRepos.length
|
|
1442
1036
|
});
|
|
1443
|
-
|
|
1037
|
+
const transport = new CompatStdioServerTransport();
|
|
1038
|
+
await server.connect(transport);
|
|
1039
|
+
// In stdio mode, explicitly resume stdin so JSON-RPC lines are consumed.
|
|
1040
|
+
process.stdin.resume();
|
|
1444
1041
|
serverStarted = true;
|
|
1445
1042
|
}
|
|
1446
1043
|
export { server, sourceService, config, SERVER_VERSION };
|