@adhisang/minecraft-modding-mcp 1.0.0 → 1.1.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 +8 -0
- package/README.md +37 -0
- package/dist/cli.js +21 -1
- 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/package.json +3 -3
package/dist/logger.js
CHANGED
|
@@ -8,14 +8,6 @@ function serializeLog(level, event, details) {
|
|
|
8
8
|
}
|
|
9
9
|
export function log(level, event, details) {
|
|
10
10
|
const line = serializeLog(level, event, details);
|
|
11
|
-
|
|
12
|
-
console.error(line);
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
if (level === "warn") {
|
|
16
|
-
console.warn(line);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
console.info(line);
|
|
11
|
+
process.stderr.write(line + "\n");
|
|
20
12
|
}
|
|
21
13
|
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare function objectResult<T extends Record<string, unknown>>(data: T): CallToolResult;
|
|
3
|
+
export declare function textResource(uri: string, value: string): ReadResourceResult;
|
|
4
|
+
export declare function objectResource(uri: string, data: Record<string, unknown>): ReadResourceResult;
|
|
5
|
+
export declare function errorResource(uri: string, message: string): ReadResourceResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function objectResult(data) {
|
|
2
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
3
|
+
}
|
|
4
|
+
export function textResource(uri, value) {
|
|
5
|
+
return { contents: [{ uri, text: value }] };
|
|
6
|
+
}
|
|
7
|
+
export function objectResource(uri, data) {
|
|
8
|
+
return { contents: [{ uri, text: JSON.stringify(data) }] };
|
|
9
|
+
}
|
|
10
|
+
export function errorResource(uri, message) {
|
|
11
|
+
return { contents: [{ uri, text: JSON.stringify({ error: message }) }] };
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=mcp-helpers.js.map
|
package/dist/resources.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { SourceService } from "./source-service.js";
|
|
3
|
-
export declare function registerResources(server:
|
|
3
|
+
export declare function registerResources(server: McpServer, sourceService: SourceService): void;
|
package/dist/resources.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { createError, ERROR_CODES, isAppError } from "./errors.js";
|
|
3
|
+
import { textResource, objectResource, errorResource } from "./mcp-helpers.js";
|
|
3
4
|
function decodeTemplateParam(params, key) {
|
|
4
5
|
const value = params[key];
|
|
5
6
|
if (typeof value !== "string" || value.length === 0) {
|
|
@@ -22,83 +23,58 @@ function decodeTemplateParam(params, key) {
|
|
|
22
23
|
}
|
|
23
24
|
export function registerResources(server, sourceService) {
|
|
24
25
|
// ── Fixed resources ──────────────────────────────────────────────
|
|
25
|
-
server.resource({
|
|
26
|
-
name: "versions-list",
|
|
27
|
-
uri: "mc://versions/list",
|
|
28
|
-
description: "List all available Minecraft versions with their metadata.",
|
|
29
|
-
mimeType: "application/json"
|
|
30
|
-
}, async () => {
|
|
26
|
+
server.resource("versions-list", "mc://versions/list", { description: "List all available Minecraft versions with their metadata.", mimeType: "application/json" }, async (uri) => {
|
|
31
27
|
try {
|
|
32
28
|
const result = await sourceService.listVersions();
|
|
33
|
-
return
|
|
29
|
+
return objectResource(uri.href, result);
|
|
34
30
|
}
|
|
35
31
|
catch (e) {
|
|
36
32
|
if (isAppError(e))
|
|
37
|
-
return
|
|
33
|
+
return errorResource(uri.href, e.message);
|
|
38
34
|
throw e;
|
|
39
35
|
}
|
|
40
36
|
});
|
|
41
|
-
server.resource({
|
|
42
|
-
name: "runtime-metrics",
|
|
43
|
-
uri: "mc://metrics",
|
|
44
|
-
description: "Runtime metrics and performance counters for the MCP server.",
|
|
45
|
-
mimeType: "application/json"
|
|
46
|
-
}, async () => {
|
|
37
|
+
server.resource("runtime-metrics", "mc://metrics", { description: "Runtime metrics and performance counters for the MCP server.", mimeType: "application/json" }, async (uri) => {
|
|
47
38
|
try {
|
|
48
39
|
const result = sourceService.getRuntimeMetrics();
|
|
49
|
-
return
|
|
40
|
+
return objectResource(uri.href, result);
|
|
50
41
|
}
|
|
51
42
|
catch (e) {
|
|
52
43
|
if (isAppError(e))
|
|
53
|
-
return
|
|
44
|
+
return errorResource(uri.href, e.message);
|
|
54
45
|
throw e;
|
|
55
46
|
}
|
|
56
47
|
});
|
|
57
48
|
// ── Template resources ───────────────────────────────────────────
|
|
58
|
-
server.
|
|
59
|
-
name: "class-source",
|
|
60
|
-
uriTemplate: "mc://source/{artifactId}/{className}",
|
|
61
|
-
description: "Java source code for a class within a resolved artifact. className may use dot or slash separators.",
|
|
62
|
-
mimeType: "text/x-java"
|
|
63
|
-
}, async (_uri, params) => {
|
|
49
|
+
server.resource("class-source", new ResourceTemplate("mc://source/{artifactId}/{className}", { list: undefined }), { description: "Java source code for a class within a resolved artifact. className may use dot or slash separators.", mimeType: "text/x-java" }, async (uri, params) => {
|
|
64
50
|
try {
|
|
65
51
|
const result = await sourceService.getClassSource({
|
|
66
52
|
artifactId: params.artifactId,
|
|
67
53
|
className: decodeTemplateParam(params, "className")
|
|
68
54
|
});
|
|
69
|
-
return
|
|
55
|
+
return textResource(uri.href, result.sourceText);
|
|
70
56
|
}
|
|
71
57
|
catch (e) {
|
|
72
58
|
if (isAppError(e))
|
|
73
|
-
return
|
|
59
|
+
return errorResource(uri.href, e.message);
|
|
74
60
|
throw e;
|
|
75
61
|
}
|
|
76
62
|
});
|
|
77
|
-
server.
|
|
78
|
-
name: "artifact-file",
|
|
79
|
-
uriTemplate: "mc://artifact/{artifactId}/files/{filePath}",
|
|
80
|
-
description: "Raw content of a file within a resolved artifact. filePath is the archive-relative path.",
|
|
81
|
-
mimeType: "text/plain"
|
|
82
|
-
}, async (_uri, params) => {
|
|
63
|
+
server.resource("artifact-file", new ResourceTemplate("mc://artifact/{artifactId}/files/{filePath}", { list: undefined }), { description: "Raw content of a file within a resolved artifact. filePath is the archive-relative path.", mimeType: "text/plain" }, async (uri, params) => {
|
|
83
64
|
try {
|
|
84
65
|
const result = await sourceService.getArtifactFile({
|
|
85
66
|
artifactId: params.artifactId,
|
|
86
67
|
filePath: decodeTemplateParam(params, "filePath")
|
|
87
68
|
});
|
|
88
|
-
return
|
|
69
|
+
return textResource(uri.href, result.content);
|
|
89
70
|
}
|
|
90
71
|
catch (e) {
|
|
91
72
|
if (isAppError(e))
|
|
92
|
-
return
|
|
73
|
+
return errorResource(uri.href, e.message);
|
|
93
74
|
throw e;
|
|
94
75
|
}
|
|
95
76
|
});
|
|
96
|
-
server.
|
|
97
|
-
name: "find-mapping",
|
|
98
|
-
uriTemplate: "mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{name}",
|
|
99
|
-
description: "Look up a mapping for a class, field, or method between two naming namespaces.",
|
|
100
|
-
mimeType: "application/json"
|
|
101
|
-
}, async (_uri, params) => {
|
|
77
|
+
server.resource("find-mapping", new ResourceTemplate("mc://mappings/{version}/{sourceMapping}/{targetMapping}/{kind}/{name}", { list: undefined }), { description: "Look up a mapping for a class, field, or method between two naming namespaces.", mimeType: "application/json" }, async (uri, params) => {
|
|
102
78
|
try {
|
|
103
79
|
const result = await sourceService.findMapping({
|
|
104
80
|
version: params.version,
|
|
@@ -107,46 +83,36 @@ export function registerResources(server, sourceService) {
|
|
|
107
83
|
sourceMapping: params.sourceMapping,
|
|
108
84
|
targetMapping: params.targetMapping
|
|
109
85
|
});
|
|
110
|
-
return
|
|
86
|
+
return objectResource(uri.href, result);
|
|
111
87
|
}
|
|
112
88
|
catch (e) {
|
|
113
89
|
if (isAppError(e))
|
|
114
|
-
return
|
|
90
|
+
return errorResource(uri.href, e.message);
|
|
115
91
|
throw e;
|
|
116
92
|
}
|
|
117
93
|
});
|
|
118
|
-
server.
|
|
119
|
-
name: "class-members",
|
|
120
|
-
uriTemplate: "mc://artifact/{artifactId}/members/{className}",
|
|
121
|
-
description: "List constructors, methods, and fields for a class within a resolved artifact.",
|
|
122
|
-
mimeType: "application/json"
|
|
123
|
-
}, async (_uri, params) => {
|
|
94
|
+
server.resource("class-members", new ResourceTemplate("mc://artifact/{artifactId}/members/{className}", { list: undefined }), { description: "List constructors, methods, and fields for a class within a resolved artifact.", mimeType: "application/json" }, async (uri, params) => {
|
|
124
95
|
try {
|
|
125
96
|
const result = await sourceService.getClassMembers({
|
|
126
97
|
artifactId: params.artifactId,
|
|
127
98
|
className: decodeTemplateParam(params, "className")
|
|
128
99
|
});
|
|
129
|
-
return
|
|
100
|
+
return objectResource(uri.href, result);
|
|
130
101
|
}
|
|
131
102
|
catch (e) {
|
|
132
103
|
if (isAppError(e))
|
|
133
|
-
return
|
|
104
|
+
return errorResource(uri.href, e.message);
|
|
134
105
|
throw e;
|
|
135
106
|
}
|
|
136
107
|
});
|
|
137
|
-
server.
|
|
138
|
-
name: "artifact-metadata",
|
|
139
|
-
uriTemplate: "mc://artifact/{artifactId}",
|
|
140
|
-
description: "Metadata for a previously resolved artifact (origin, coordinate, mapping, provenance).",
|
|
141
|
-
mimeType: "application/json"
|
|
142
|
-
}, async (_uri, params) => {
|
|
108
|
+
server.resource("artifact-metadata", new ResourceTemplate("mc://artifact/{artifactId}", { list: undefined }), { description: "Metadata for a previously resolved artifact (origin, coordinate, mapping, provenance).", mimeType: "application/json" }, async (uri, params) => {
|
|
143
109
|
try {
|
|
144
110
|
const artifact = sourceService.getArtifact(params.artifactId);
|
|
145
|
-
return
|
|
111
|
+
return objectResource(uri.href, artifact);
|
|
146
112
|
}
|
|
147
113
|
catch (e) {
|
|
148
114
|
if (isAppError(e))
|
|
149
|
-
return
|
|
115
|
+
return errorResource(uri.href, e.message);
|
|
150
116
|
throw e;
|
|
151
117
|
}
|
|
152
118
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhisang/minecraft-modding-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP server with utilities for Minecraft modding workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"test:perf": "node --test --test-concurrency=1 --import tsx tests/perf/*.perf.ts",
|
|
29
29
|
"test:perf:update-baseline": "UPDATE_PERF_BASELINE=1 node --test --test-concurrency=1 --import tsx tests/perf/*.perf.ts",
|
|
30
30
|
"test:perf:strict": "STRICT_PERF=1 node --test --test-concurrency=1 --import tsx tests/perf/*.perf.ts",
|
|
31
|
-
"test:manual:
|
|
31
|
+
"test:manual:stdio-smoke": "node --import tsx tests/manual/stdio-client-smoke.manual.ts",
|
|
32
32
|
"test:manual:package-smoke": "node --import tsx tests/manual/package-distribution-smoke.manual.ts",
|
|
33
33
|
"validate": "npm run check && npm test && npm run test:coverage && npm run test:perf"
|
|
34
34
|
},
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"node": ">=22"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
50
50
|
"fast-glob": "^3.3.3",
|
|
51
51
|
"smol-toml": "^1.3.0",
|
|
52
52
|
"yauzl": "^3.2.0",
|