vitaminmcp 3.2.0 → 3.2.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/checksums.json +7 -7
- package/package.json +1 -1
- package/runner/runner.mjs +25 -3
- package/runner/src/version.mjs +36 -0
package/checksums.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.2.
|
|
2
|
+
"version": "3.2.1",
|
|
3
3
|
"jars": {
|
|
4
|
-
"mcp-server.jar": "
|
|
4
|
+
"mcp-server.jar": "b9af85303677bfe1e792259c5efab2763bd0fbafa12c1d468f7b034c563ba021"
|
|
5
5
|
},
|
|
6
6
|
"assets": {
|
|
7
|
-
"bot-runner-win-x64.exe": "
|
|
8
|
-
"bot-runner-linux-x64": "
|
|
9
|
-
"bot-runner-linux-arm64": "
|
|
10
|
-
"bot-runner-darwin-x64": "
|
|
11
|
-
"bot-runner-darwin-arm64": "
|
|
7
|
+
"bot-runner-win-x64.exe": "0932bb6677cf9ff8657905a193e8f36f2943a4bba2b1597817f7ac192b575524",
|
|
8
|
+
"bot-runner-linux-x64": "a488c2f97c8c63f46bfb40e192af6939d3f49af1c61426974eb36cc3688a4db4",
|
|
9
|
+
"bot-runner-linux-arm64": "492fb73d79fd8db5d391567eb5b093c8f48bbd39b9bd669061c30c10dafc829f",
|
|
10
|
+
"bot-runner-darwin-x64": "b5fa212b25d001938384015fb22d5168977974d38105746b2c3a7a2b73aabd09",
|
|
11
|
+
"bot-runner-darwin-arm64": "e426feeac28baea547f5010ac47a33f50c401419bce258c4492408a87eec83bd",
|
|
12
12
|
"bot-runner-viewer-win-x64.tgz": "e39a36cdf92b9223aa7c9610f8231afc7a577e8ed007bc3571895bd945baf3e1"
|
|
13
13
|
}
|
|
14
14
|
}
|
package/package.json
CHANGED
package/runner/runner.mjs
CHANGED
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
*
|
|
7
7
|
* node runner.mjs <host> <port> [protocol]
|
|
8
8
|
*
|
|
9
|
+
* Without a protocol it pings the server. VITAMINMCP_SERVER_VERSION, when set, is the Minecraft
|
|
10
|
+
* version the agent reports, and it wins over a ping that disagrees (see `selectProtocol`). It is
|
|
11
|
+
* an environment variable rather than an argument so a runner and an MCP server of different
|
|
12
|
+
* releases still understand each other's command line.
|
|
13
|
+
*
|
|
9
14
|
* Everything it prints on stdout is protocol. Diagnostics go to stderr, which the MCP server
|
|
10
15
|
* inherits — a stray `console.log` here is a desynchronised session, not a stray log line.
|
|
11
16
|
*/
|
|
@@ -14,7 +19,7 @@ import { createInterface } from 'node:readline';
|
|
|
14
19
|
import { BotRegistry } from './src/bots.mjs';
|
|
15
20
|
import { Dispatch } from './src/dispatch.mjs';
|
|
16
21
|
import * as protocol from './src/protocol.mjs';
|
|
17
|
-
import { pingProtocol, versionForProtocol } from './src/version.mjs';
|
|
22
|
+
import { pingProtocol, selectProtocol, versionForProtocol } from './src/version.mjs';
|
|
18
23
|
|
|
19
24
|
// stdout is the protocol channel; a dependency's console.log (mineflayer did this on 26.1, with a
|
|
20
25
|
// stack trace) desynchronises every later reply. `write` below is the only path to stdout.
|
|
@@ -32,10 +37,24 @@ async function main() {
|
|
|
32
37
|
const host = argv[0];
|
|
33
38
|
const port = Number(argv[1]);
|
|
34
39
|
|
|
40
|
+
const serverVersion = process.env.VITAMINMCP_SERVER_VERSION || undefined;
|
|
41
|
+
|
|
35
42
|
let bots;
|
|
36
43
|
let negotiated;
|
|
44
|
+
let pinged;
|
|
37
45
|
try {
|
|
38
|
-
|
|
46
|
+
if (argv.length > 2) {
|
|
47
|
+
negotiated = Number(argv[2]);
|
|
48
|
+
} else {
|
|
49
|
+
({ protocol: negotiated, pinged } = selectProtocol(await pingProtocol(host, port), serverVersion));
|
|
50
|
+
}
|
|
51
|
+
if (pinged !== undefined) {
|
|
52
|
+
process.stderr.write(
|
|
53
|
+
`The server-list ping answered protocol ${pinged}, but the agent reports Minecraft `
|
|
54
|
+
+ `${serverVersion} (protocol ${negotiated}). Something in front of the server answered `
|
|
55
|
+
+ `the ping, a proxy or ViaVersion; using ${negotiated}.\n`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
39
58
|
bots = new BotRegistry(host, port, versionForProtocol(negotiated));
|
|
40
59
|
} catch (error) {
|
|
41
60
|
// The Java side reads this line and reports it as the reason the runner did not start, so it
|
|
@@ -45,7 +64,10 @@ async function main() {
|
|
|
45
64
|
process.exit(1);
|
|
46
65
|
}
|
|
47
66
|
|
|
48
|
-
|
|
67
|
+
// A third field only when the ping disagreed, so the line a caller already parses is unchanged.
|
|
68
|
+
write(pinged === undefined
|
|
69
|
+
? protocol.encode(protocol.READY, String(negotiated))
|
|
70
|
+
: protocol.encode(protocol.READY, String(negotiated), String(pinged)));
|
|
49
71
|
|
|
50
72
|
const dispatch = new Dispatch(bots);
|
|
51
73
|
const lines = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
package/runner/src/version.mjs
CHANGED
|
@@ -76,3 +76,39 @@ export function versionForProtocol(protocol) {
|
|
|
76
76
|
.join(', ')}). It supports ${mc.supportedVersions.join(', ')}.`,
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The protocol a Minecraft version speaks, from minecraft-data's table of every release it has
|
|
82
|
+
* heard of. That table is wider than the versions it carries data for, so a release the runner
|
|
83
|
+
* cannot speak yet still has a number here.
|
|
84
|
+
*/
|
|
85
|
+
export function protocolForVersion(minecraftVersion) {
|
|
86
|
+
return minecraftData.versionsByMinecraftVersion?.pc?.[minecraftVersion]?.version;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Which protocol to speak: the one the agent says its server runs, over the one the ping answered.
|
|
91
|
+
*
|
|
92
|
+
* A ping is answered by whatever holds the port, and two common things answer it with the
|
|
93
|
+
* protocol the ping was written in rather than the server's own: a proxy that echoes it, and
|
|
94
|
+
* ViaVersion with ViaBackwards, which rewrites the status reply to the client's protocol whenever
|
|
95
|
+
* it can translate. The ping is written in PING_VERSION, so either one made the runner join as
|
|
96
|
+
* 1.21.1 — on a 26.x server, through a chain of translations, without a word. The agent runs inside
|
|
97
|
+
* the server, and nothing answers for it.
|
|
98
|
+
*
|
|
99
|
+
* Without a version from the agent the ping decides, as it always did. `pinged` is returned only
|
|
100
|
+
* when the two disagree, so the caller can say so.
|
|
101
|
+
*/
|
|
102
|
+
export function selectProtocol(pinged, serverVersion) {
|
|
103
|
+
if (!serverVersion) {
|
|
104
|
+
return { protocol: pinged };
|
|
105
|
+
}
|
|
106
|
+
const declared = protocolForVersion(serverVersion);
|
|
107
|
+
if (declared === undefined) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`The agent reports Minecraft ${serverVersion}, which this runner's minecraft-data does not `
|
|
110
|
+
+ 'know: the dependency is older than the server.',
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return declared === pinged ? { protocol: declared } : { protocol: declared, pinged };
|
|
114
|
+
}
|