@bkm016/calcite 0.3.0 → 0.5.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 +35 -0
- package/README.md +103 -20
- package/dist/accounts.js +4 -2
- package/dist/accounts.js.map +1 -1
- package/dist/cli.js +12 -141
- package/dist/cli.js.map +1 -1
- package/dist/client-core.d.ts +22 -13
- package/dist/client-core.js +217 -260
- package/dist/client-core.js.map +1 -1
- package/dist/client.d.ts +44 -15
- package/dist/client.js +58 -21
- package/dist/client.js.map +1 -1
- package/dist/display.d.ts +0 -6
- package/dist/display.js +31 -44
- package/dist/display.js.map +1 -1
- package/dist/feed.d.ts +17 -0
- package/dist/feed.js +47 -0
- package/dist/feed.js.map +1 -0
- package/dist/game-run.d.ts +30 -0
- package/dist/game-run.js +51 -0
- package/dist/game-run.js.map +1 -0
- package/dist/hmc.d.ts +7 -0
- package/dist/hmc.js +42 -31
- package/dist/hmc.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +6 -0
- package/dist/install.js +26 -3
- package/dist/install.js.map +1 -1
- package/dist/java.js +11 -2
- package/dist/java.js.map +1 -1
- package/dist/launch.d.ts +79 -0
- package/dist/launch.js +142 -0
- package/dist/launch.js.map +1 -0
- package/dist/lock.js +18 -18
- package/dist/lock.js.map +1 -1
- package/dist/mcp/accounts.d.ts +3 -0
- package/dist/mcp/accounts.js +45 -0
- package/dist/mcp/accounts.js.map +1 -0
- package/dist/mcp/act.d.ts +3 -0
- package/dist/mcp/act.js +129 -0
- package/dist/mcp/act.js.map +1 -0
- package/dist/mcp/extensions.d.ts +3 -0
- package/dist/mcp/extensions.js +21 -0
- package/dist/mcp/extensions.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +58 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/items.d.ts +3 -0
- package/dist/mcp/items.js +71 -0
- package/dist/mcp/items.js.map +1 -0
- package/dist/mcp/lifecycle.d.ts +3 -0
- package/dist/mcp/lifecycle.js +120 -0
- package/dist/mcp/lifecycle.js.map +1 -0
- package/dist/mcp/observe.d.ts +3 -0
- package/dist/mcp/observe.js +110 -0
- package/dist/mcp/observe.js.map +1 -0
- package/dist/mcp/shared.d.ts +49 -0
- package/dist/mcp/shared.js +56 -0
- package/dist/mcp/shared.js.map +1 -0
- package/dist/mcp/tasks.d.ts +15 -0
- package/dist/mcp/tasks.js +46 -0
- package/dist/mcp/tasks.js.map +1 -0
- package/dist/mods.js +6 -4
- package/dist/mods.js.map +1 -1
- package/dist/mojang.d.ts +5 -1
- package/dist/mojang.js.map +1 -1
- package/dist/names.js +30 -8
- package/dist/names.js.map +1 -1
- package/dist/net.js +25 -19
- package/dist/net.js.map +1 -1
- package/dist/paper.d.ts +46 -0
- package/dist/paper.js +200 -0
- package/dist/paper.js.map +1 -0
- package/dist/probe-server.d.ts +14 -4
- package/dist/probe-server.js +11 -10
- package/dist/probe-server.js.map +1 -1
- package/dist/repl.d.ts +6 -0
- package/dist/repl.js +207 -0
- package/dist/repl.js.map +1 -0
- package/dist/stage.d.ts +6 -0
- package/dist/stage.js +19 -0
- package/dist/stage.js.map +1 -0
- package/dist/types.d.ts +139 -5
- package/dist/types.js +12 -1
- package/dist/types.js.map +1 -1
- package/dist/zip.js.map +1 -1
- package/package.json +11 -3
- package/vendor/calcite-probe.jar +0 -0
package/dist/launch.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Socket } from 'node:net';
|
|
2
|
+
import { hmcJavaHome, hmcListEntry, hmcQuote, hmcVersionArgs, UTF8_CONSOLE_PROPS } from './hmc.js';
|
|
3
|
+
import { javaProxyProps } from './net.js';
|
|
4
|
+
import { CalciteError } from './types.js';
|
|
5
|
+
/** Escapes a value for a java.util.Properties file. */
|
|
6
|
+
export function propValue(value) {
|
|
7
|
+
return value.replace(/\\/g, '\\\\').replace(/[:=]/g, (c) => `\\${c}`);
|
|
8
|
+
}
|
|
9
|
+
/** The probe's settings file: the agent argument only names it, since its paths may contain spaces. */
|
|
10
|
+
export function probeConfig(s) {
|
|
11
|
+
return [
|
|
12
|
+
`port=${s.port}`,
|
|
13
|
+
`token=${s.token}`,
|
|
14
|
+
...s.mappings.map((m, i) => `mappings.${i + 1}=${propValue(m)}`),
|
|
15
|
+
`version=${propValue(s.version)}`,
|
|
16
|
+
...s.extensions.map((jar, i) => `extensions.${i + 1}=${propValue(jar)}`),
|
|
17
|
+
`headless=${s.headless}`,
|
|
18
|
+
`render=${s.render === 'always' ? 'on' : 'off'}`,
|
|
19
|
+
'exitOnDisconnect=true',
|
|
20
|
+
'',
|
|
21
|
+
].join('\n');
|
|
22
|
+
}
|
|
23
|
+
/** HeadlessMC's command line for launching the game. */
|
|
24
|
+
export function hmcLaunchCommand(l) {
|
|
25
|
+
return [
|
|
26
|
+
'launch',
|
|
27
|
+
...hmcVersionArgs(l.versionId, l.loader),
|
|
28
|
+
...(l.offline ? ['--offline'] : []),
|
|
29
|
+
...(l.headless ? ['--headless'] : []),
|
|
30
|
+
`--jvm=${l.jvmArgs.map(hmcQuote).join(' ')}`,
|
|
31
|
+
...(l.gameArgs.length ? [`--game=${l.gameArgs.map(hmcQuote).join(' ')}`] : []),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
/** JVM arguments for the game: the probe agent, heap size, UTF-8 console, proxy settings and the caller's own arguments. */
|
|
35
|
+
export function gameJvmArgs(s) {
|
|
36
|
+
return [
|
|
37
|
+
// HeadlessMC's stubbed LWJGL buffers have no native address; JOML's Unsafe path writes to it and crashes the JVM
|
|
38
|
+
...(s.headless ? ['-Djoml.nounsafe=true'] : []),
|
|
39
|
+
...(s.agent ? [`-javaagent:${s.agent}`] : []),
|
|
40
|
+
`-Xmx${s.memory ?? '2G'}`,
|
|
41
|
+
...Object.entries({ ...UTF8_CONSOLE_PROPS, ...javaProxyProps() }).map(([k, v]) => `-D${k}=${v}`),
|
|
42
|
+
...(s.extra ?? []),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
/** HeadlessMC system properties for one client. */
|
|
46
|
+
export function hmcProperties(s) {
|
|
47
|
+
return {
|
|
48
|
+
'hmc.files.mc': s.minecraftDir,
|
|
49
|
+
'hmc.files.game': s.gameDir,
|
|
50
|
+
'hmc.java.versions': hmcListEntry(hmcJavaHome(s.javaPath)),
|
|
51
|
+
'hmc.java.download': 'false',
|
|
52
|
+
// HeadlessMC only lets offline accounts render when it sees Xvfb running
|
|
53
|
+
'hmc.xvfb.check': String(s.virtualDisplay),
|
|
54
|
+
// "dummy" assets skip the hashing of existing asset files; a missing one would become a placeholder, so this is
|
|
55
|
+
// only set once a launch got through the full download and verification
|
|
56
|
+
'hmc.assets.dummy': String(s.assetsVerified),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Game arguments that join {@code server} right after startup (Quick Play from 1.20, --server before). */
|
|
60
|
+
export function joinArgs(server, quickPlay) {
|
|
61
|
+
return quickPlay ? ['--quickPlayMultiplayer', `${server.host}:${server.port}`] : ['--server', server.host, '--port', String(server.port)];
|
|
62
|
+
}
|
|
63
|
+
export async function tcpReachable(host, port, timeoutMs = 3000) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
const socket = new Socket();
|
|
66
|
+
const done = (ok) => {
|
|
67
|
+
socket.destroy();
|
|
68
|
+
resolve(ok);
|
|
69
|
+
};
|
|
70
|
+
socket.setTimeout(timeoutMs, () => done(false));
|
|
71
|
+
socket.once('error', () => done(false));
|
|
72
|
+
socket.connect(port, host, () => done(true));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** What to do when no graphics backend could be created. */
|
|
76
|
+
export function noBackendHint(platform) {
|
|
77
|
+
return platform === 'linux'
|
|
78
|
+
? 'On Linux without a GPU install Mesa EGL (apt install libegl1 libegl-mesa0) or Vulkan (apt install mesa-vulkan-drivers), or use render "off".'
|
|
79
|
+
: 'Update the graphics drivers, or use render "off".';
|
|
80
|
+
}
|
|
81
|
+
/** Resolves once {@code server} accepts TCP connections; fails after {@code timeoutMs}. */
|
|
82
|
+
export async function waitForServer(server, w) {
|
|
83
|
+
const { retryMs = 2000, reportMs = 10_000 } = w;
|
|
84
|
+
const since = Date.now();
|
|
85
|
+
let reported = since;
|
|
86
|
+
while (!(await tcpReachable(server.host, server.port))) {
|
|
87
|
+
if (w.stopped())
|
|
88
|
+
throw new CalciteError('stopped', 'Stopped while waiting for the server');
|
|
89
|
+
const waited = Date.now() - since;
|
|
90
|
+
if (waited > w.timeoutMs) {
|
|
91
|
+
throw new CalciteError('server_unreachable', `Server ${server.host}:${server.port} is not reachable (waited ${Math.round(waited / 1000)}s)`);
|
|
92
|
+
}
|
|
93
|
+
if (Date.now() - reported >= reportMs) {
|
|
94
|
+
reported = Date.now();
|
|
95
|
+
w.onWaiting(`still waiting for ${server.host}:${server.port} (${Math.round(waited / 1000)}s of ${Math.round(w.timeoutMs / 1000)}s)`);
|
|
96
|
+
}
|
|
97
|
+
await new Promise((r) => setTimeout(r, retryMs));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** How many reconnects the {@code reconnect} option allows in a row. */
|
|
101
|
+
export function reconnectLimit(option) {
|
|
102
|
+
if (option === false)
|
|
103
|
+
return 0;
|
|
104
|
+
if (typeof option === 'object')
|
|
105
|
+
return option.maxAttempts ?? 10;
|
|
106
|
+
return 10;
|
|
107
|
+
}
|
|
108
|
+
/** Delay before reconnect attempt {@code attempt} (from 1): 5 s, doubling, at most a minute. */
|
|
109
|
+
export function reconnectDelay(attempt) {
|
|
110
|
+
return Math.min(5000 * 2 ** (attempt - 1), 60_000);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Minecraft 26.x opens a modal error box and blocks forever when no graphics backend can be created. Watches the
|
|
114
|
+
* game output and reports the backend errors when none came up within {@code graceMs} of the last failure.
|
|
115
|
+
*/
|
|
116
|
+
export class BackendWatch {
|
|
117
|
+
onStuck;
|
|
118
|
+
graceMs;
|
|
119
|
+
errors = [];
|
|
120
|
+
timer;
|
|
121
|
+
constructor(onStuck, graceMs = 20_000) {
|
|
122
|
+
this.onStuck = onStuck;
|
|
123
|
+
this.graceMs = graceMs;
|
|
124
|
+
}
|
|
125
|
+
line(line) {
|
|
126
|
+
const failure = /BackendCreationException: (.*)/.exec(line);
|
|
127
|
+
if (failure) {
|
|
128
|
+
this.errors.push(failure[1].trim());
|
|
129
|
+
clearTimeout(this.timer);
|
|
130
|
+
this.timer = setTimeout(() => {
|
|
131
|
+
this.onStuck(this.errors);
|
|
132
|
+
}, this.graceMs);
|
|
133
|
+
}
|
|
134
|
+
else if (line.includes('Using graphics backend')) {
|
|
135
|
+
clearTimeout(this.timer);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
dispose() {
|
|
139
|
+
clearTimeout(this.timer);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../src/launch.ts"],"names":[],"mappings":"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"}
|
package/dist/lock.js
CHANGED
|
@@ -9,6 +9,21 @@ function alive(pid) {
|
|
|
9
9
|
return err.code === 'EPERM';
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
/** Whether the lock in {@code dir} was left behind; undefined when it vanished meanwhile. */
|
|
13
|
+
async function staleLock(dir, staleMs) {
|
|
14
|
+
let modified;
|
|
15
|
+
try {
|
|
16
|
+
modified = (await stat(dir)).mtimeMs;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const owner = Number(await readFile(join(dir, 'owner'), 'utf8').catch(() => ''));
|
|
22
|
+
// a lock without an owner is still being created, unless that never finished
|
|
23
|
+
if (!(owner > 0))
|
|
24
|
+
return Date.now() - modified > 10_000;
|
|
25
|
+
return !alive(owner) || Date.now() - modified > staleMs;
|
|
26
|
+
}
|
|
12
27
|
/**
|
|
13
28
|
* Cross-process lock based on an atomic mkdir. A lock whose owner process is gone (or that is older than
|
|
14
29
|
* {@code staleMs}) is taken over. Returns the release function.
|
|
@@ -37,24 +52,9 @@ export async function acquireLock(dir, { timeoutMs = 10 * 60_000, staleMs = Infi
|
|
|
37
52
|
if (code !== 'EEXIST')
|
|
38
53
|
throw err;
|
|
39
54
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let owner = 0;
|
|
44
|
-
try {
|
|
45
|
-
owner = Number(await readFile(join(dir, 'owner'), 'utf8'));
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
// owner not written yet
|
|
49
|
-
}
|
|
50
|
-
if (owner > 0)
|
|
51
|
-
stale = !alive(owner) || Date.now() - info.mtimeMs > staleMs;
|
|
52
|
-
else
|
|
53
|
-
stale = Date.now() - info.mtimeMs > 10_000;
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
continue; // lock vanished meanwhile
|
|
57
|
-
}
|
|
55
|
+
const stale = await staleLock(dir, staleMs);
|
|
56
|
+
if (stale === undefined)
|
|
57
|
+
continue; // vanished meanwhile
|
|
58
58
|
if (stale) {
|
|
59
59
|
await rm(dir, { recursive: true, force: true });
|
|
60
60
|
continue;
|
package/dist/lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,SAAS,KAAK,CAAC,GAAW;IACxB,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAQ,GAA6B,CAAC,IAAI,KAAK,OAAO,CAAC;IACzD,CAAC;AACH,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listAccounts, removeAccount, startLogin } from '../accounts.js';
|
|
3
|
+
import { CalciteError } from '../client.js';
|
|
4
|
+
import { tool } from './shared.js';
|
|
5
|
+
/** Microsoft accounts: device-code login, listing and removal. */
|
|
6
|
+
export function registerAccountTools({ server, paths }) {
|
|
7
|
+
const logins = new Map();
|
|
8
|
+
let loginSeq = 0;
|
|
9
|
+
tool(server, 'account_list', { title: 'Stored Microsoft accounts', description: 'Microsoft accounts whose login is saved.', inputSchema: {} }, async () => listAccounts(paths));
|
|
10
|
+
tool(server, 'account_login_start', {
|
|
11
|
+
title: 'Start Microsoft login',
|
|
12
|
+
description: 'Starts a Microsoft device login. Returns a URL the user must open in a browser and approve; then poll account_login_status. The session is saved and refreshed automatically.',
|
|
13
|
+
inputSchema: {},
|
|
14
|
+
}, async () => {
|
|
15
|
+
const id = ++loginSeq;
|
|
16
|
+
const login = { handle: await startLogin(paths) };
|
|
17
|
+
logins.set(id, login);
|
|
18
|
+
login.handle.done.then((name) => (login.account = name), (e) => (login.error = e.message));
|
|
19
|
+
login.url = await login.handle.url;
|
|
20
|
+
return { loginId: id, url: login.url, next: 'Ask the user to open the URL and sign in, then call account_login_status' };
|
|
21
|
+
});
|
|
22
|
+
tool(server, 'account_login_status', {
|
|
23
|
+
title: 'Microsoft login status',
|
|
24
|
+
description: 'Waits up to waitSeconds for a pending login started with account_login_start.',
|
|
25
|
+
inputSchema: { loginId: z.number().int(), waitSeconds: z.number().min(0).max(120).default(30) },
|
|
26
|
+
}, async ({ loginId, waitSeconds }) => {
|
|
27
|
+
const login = logins.get(loginId);
|
|
28
|
+
if (!login)
|
|
29
|
+
throw new CalciteError('unknown_login', `No login with id ${loginId}`);
|
|
30
|
+
if (!login.account && !login.error) {
|
|
31
|
+
await Promise.race([login.handle.done.catch(() => undefined), new Promise((r) => setTimeout(r, waitSeconds * 1000))]);
|
|
32
|
+
}
|
|
33
|
+
if (login.account)
|
|
34
|
+
return { status: 'done', account: login.account };
|
|
35
|
+
if (login.error)
|
|
36
|
+
return { status: 'failed', error: login.error };
|
|
37
|
+
return { status: 'pending', url: login.url };
|
|
38
|
+
});
|
|
39
|
+
tool(server, 'account_remove', { title: 'Remove a stored account', description: 'Deletes a saved Microsoft login.', inputSchema: { account: z.string() } }, async ({ account }) => {
|
|
40
|
+
if (!(await removeAccount(paths, account)))
|
|
41
|
+
throw new CalciteError('unknown_account', `No stored account named "${account}"`);
|
|
42
|
+
return `Removed ${account}`;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/mcp/accounts.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/act.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { background, clientName, coord, face, optionalPoint, stopOnDamage, timeoutSeconds, tool } from './shared.js';
|
|
3
|
+
/** Acting as the player: chat, commands, looking, moving, fighting, using and mining. */
|
|
4
|
+
export function registerActTools({ server, manager, tasks }) {
|
|
5
|
+
tool(server, 'send_chat', {
|
|
6
|
+
title: 'Send chat',
|
|
7
|
+
description: 'Sends a chat message as the player.',
|
|
8
|
+
inputSchema: { client: clientName, message: z.string().min(1).max(256) },
|
|
9
|
+
}, async ({ client, message }) => {
|
|
10
|
+
await manager.resolve(client).chat(message);
|
|
11
|
+
return 'sent';
|
|
12
|
+
});
|
|
13
|
+
tool(server, 'run_command', {
|
|
14
|
+
title: 'Run command',
|
|
15
|
+
description: 'Runs a command as the player (leading "/" optional) and returns the chat lines that arrived within 750 ms; use wait_for for slower replies.',
|
|
16
|
+
inputSchema: { client: clientName, command: z.string().min(1).max(32_000) },
|
|
17
|
+
}, async ({ client, command }) => {
|
|
18
|
+
const target = manager.resolve(client);
|
|
19
|
+
const before = target.lastSeq;
|
|
20
|
+
await target.command(command.replace(/^\//, ''));
|
|
21
|
+
await new Promise((r) => setTimeout(r, 750));
|
|
22
|
+
return { sent: true, chatSince: target.chatSince(before) };
|
|
23
|
+
});
|
|
24
|
+
tool(server, 'respawn', { title: 'Respawn', description: 'Respawns the player after death.', inputSchema: { client: clientName } }, async ({ client }) => {
|
|
25
|
+
await manager.resolve(client).respawn();
|
|
26
|
+
return 'respawned';
|
|
27
|
+
});
|
|
28
|
+
tool(server, 'look', {
|
|
29
|
+
title: 'Look',
|
|
30
|
+
description: 'Turns the player: either to yaw/pitch in degrees (yaw 0 = south, 90 = west, 180 = north, -90 = east; pitch -90 = up, 90 = down) or towards the point x/y/z.',
|
|
31
|
+
inputSchema: {
|
|
32
|
+
client: clientName,
|
|
33
|
+
yaw: z.number().optional(),
|
|
34
|
+
pitch: z.number().min(-90).max(90).optional(),
|
|
35
|
+
x: z.number().optional(),
|
|
36
|
+
y: z.number().optional(),
|
|
37
|
+
z: z.number().optional(),
|
|
38
|
+
},
|
|
39
|
+
}, async ({ client, yaw, pitch, x, y, z: zz }) => manager.resolve(client).look(optionalPoint(x, y, zz) ?? { yaw, pitch }));
|
|
40
|
+
tool(server, 'walk_to', {
|
|
41
|
+
title: 'Walk to a position',
|
|
42
|
+
description: 'Finds a path through the loaded terrain and walks it: around walls, up steps, down drops of up to 3 blocks, across water, never into lava. Re-plans when pushed off the path. Returns arrived=false with a reason (no_path, stuck, off_path, timeout, damaged) when it cannot get there; with no_path it still gets as close as it can.',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
client: clientName,
|
|
45
|
+
x: z.number(),
|
|
46
|
+
y: z.number().optional().describe('Target height; omit to accept any height at x/z'),
|
|
47
|
+
z: z.number(),
|
|
48
|
+
range: z.number().positive().max(16).default(0.5).describe('Stop within this many blocks'),
|
|
49
|
+
sprint: z.boolean().default(true),
|
|
50
|
+
direct: z.boolean().default(false).describe('Walk in a straight line without planning a path'),
|
|
51
|
+
stopOnDamage,
|
|
52
|
+
background,
|
|
53
|
+
timeoutSeconds: timeoutSeconds(60),
|
|
54
|
+
},
|
|
55
|
+
}, async ({ client, x, z: zz, timeoutSeconds: seconds, background: bg, ...opts }) => {
|
|
56
|
+
const target = manager.resolve(client);
|
|
57
|
+
return tasks.run(target, 'walk_to', bg, () => target.walkTo(x, zz, { ...opts, timeoutMs: seconds * 1000 }));
|
|
58
|
+
});
|
|
59
|
+
tool(server, 'move', {
|
|
60
|
+
title: 'Hold movement keys',
|
|
61
|
+
description: 'Presses (true) or releases (false) movement keys; omitted keys keep their state. With ticks (20 per second) they are released automatically, otherwise they stay held until changed or stop_actions.',
|
|
62
|
+
inputSchema: {
|
|
63
|
+
client: clientName,
|
|
64
|
+
forward: z.boolean().optional(),
|
|
65
|
+
back: z.boolean().optional(),
|
|
66
|
+
left: z.boolean().optional(),
|
|
67
|
+
right: z.boolean().optional(),
|
|
68
|
+
jump: z.boolean().optional(),
|
|
69
|
+
sneak: z.boolean().optional(),
|
|
70
|
+
sprint: z.boolean().optional(),
|
|
71
|
+
ticks: z.number().int().positive().max(12_000).optional(),
|
|
72
|
+
},
|
|
73
|
+
}, async ({ client, ticks, ...controls }) => manager.resolve(client).move(controls, { ticks }));
|
|
74
|
+
tool(server, 'stop_actions', {
|
|
75
|
+
title: 'Stop actions',
|
|
76
|
+
description: 'Releases all keys and cancels the running walk_to, dig, craft or held use.',
|
|
77
|
+
inputSchema: { client: clientName },
|
|
78
|
+
}, async ({ client }) => {
|
|
79
|
+
await manager.resolve(client).stopActions();
|
|
80
|
+
return 'stopped';
|
|
81
|
+
});
|
|
82
|
+
tool(server, 'get_task', {
|
|
83
|
+
title: 'Running action',
|
|
84
|
+
description: 'Progress of the running walk_to, dig or craft (waypoint, distance, crafted count...) and the outcome of the last one started with background: true.',
|
|
85
|
+
inputSchema: {
|
|
86
|
+
client: clientName,
|
|
87
|
+
waitSeconds: z.number().min(0).max(120).default(0).describe('Wait up to this long for the background action to end'),
|
|
88
|
+
},
|
|
89
|
+
}, async ({ client, waitSeconds }) => tasks.status(manager.resolve(client), waitSeconds * 1000));
|
|
90
|
+
tool(server, 'attack', {
|
|
91
|
+
title: 'Attack (left click)',
|
|
92
|
+
description: 'Attacks the entity with this id (from get_entities; the player turns to it, must be within reach) or, without an id, whatever the crosshair points at.',
|
|
93
|
+
inputSchema: { client: clientName, entityId: z.number().int().optional() },
|
|
94
|
+
}, async ({ client, entityId }) => manager.resolve(client).attack(entityId));
|
|
95
|
+
tool(server, 'use', {
|
|
96
|
+
title: 'Use / interact (right click)',
|
|
97
|
+
description: 'Right click on an entity (entityId: trade, ride, feed...), on a block (x/y/z: open chests and doors, press buttons, place the held block against that face) or, with neither, on whatever the crosshair points at / the held item in the air. holdTicks keeps the button held (eat, drink, draw a bow).',
|
|
98
|
+
inputSchema: {
|
|
99
|
+
client: clientName,
|
|
100
|
+
entityId: z.number().int().optional(),
|
|
101
|
+
x: coord.optional(),
|
|
102
|
+
y: coord.optional(),
|
|
103
|
+
z: coord.optional(),
|
|
104
|
+
face,
|
|
105
|
+
holdTicks: z.number().int().positive().max(1200).optional(),
|
|
106
|
+
},
|
|
107
|
+
}, async ({ client, entityId, x, y, z: zz, face: f, holdTicks }) => {
|
|
108
|
+
const point = optionalPoint(x, y, zz);
|
|
109
|
+
return manager.resolve(client).use({ entityId, block: point && { ...point, face: f }, holdTicks });
|
|
110
|
+
});
|
|
111
|
+
tool(server, 'dig', {
|
|
112
|
+
title: 'Mine a block',
|
|
113
|
+
description: 'Mines the block at x/y/z like a player holding left click (real break time in survival, instant in creative). The block must be within reach.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
client: clientName,
|
|
116
|
+
x: coord,
|
|
117
|
+
y: coord,
|
|
118
|
+
z: coord,
|
|
119
|
+
face,
|
|
120
|
+
stopOnDamage,
|
|
121
|
+
background,
|
|
122
|
+
timeoutSeconds: timeoutSeconds(30, 300),
|
|
123
|
+
},
|
|
124
|
+
}, async ({ client, timeoutSeconds: seconds, face: f, stopOnDamage: stop, background: bg, ...pos }) => {
|
|
125
|
+
const target = manager.resolve(client);
|
|
126
|
+
return tasks.run(target, 'dig', bg, () => target.dig({ ...pos, face: f }, { stopOnDamage: stop, timeoutMs: seconds * 1000 }));
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=act.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"act.js","sourceRoot":"","sources":["../../src/mcp/act.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { clientName, timeoutSeconds, tool } from './shared.js';
|
|
3
|
+
/** Commands added by probe extensions and mods. */
|
|
4
|
+
export function registerExtensionTools({ server, manager }) {
|
|
5
|
+
tool(server, 'list_extensions', {
|
|
6
|
+
title: 'Extension commands',
|
|
7
|
+
description: 'Commands added by probe extensions and mods (name, description, JSON schema of the arguments) and the extension jars that were loaded (with load errors).',
|
|
8
|
+
inputSchema: { client: clientName },
|
|
9
|
+
}, async ({ client }) => manager.resolve(client).extensions());
|
|
10
|
+
tool(server, 'call_extension', {
|
|
11
|
+
title: 'Call an extension command',
|
|
12
|
+
description: 'Runs a command from list_extensions with JSON arguments matching its schema and returns its result.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
client: clientName,
|
|
15
|
+
name: z.string().min(1).describe('Command name from list_extensions, e.g. "hud.bossbars"'),
|
|
16
|
+
args: z.record(z.string(), z.unknown()).optional().describe('Arguments object'),
|
|
17
|
+
timeoutSeconds: timeoutSeconds(30),
|
|
18
|
+
},
|
|
19
|
+
}, async ({ client, name, args, timeoutSeconds: seconds }) => manager.resolve(client).call(name, args ?? {}, { timeoutMs: seconds * 1000 }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/mcp/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAoB,MAAM,aAAa,CAAC;AAEjF,mDAAmD;AACnD,MAAM,UAAU,sBAAsB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAe;IACrE,IAAI,CACF,MAAM,EACN,iBAAiB,EACjB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,2JAA2J;QAC7J,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAC3D,CAAC;IAEF,IAAI,CACF,MAAM,EACN,gBAAgB,EAChB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE,qGAAqG;QAClH,WAAW,EAAE;YACX,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wDAAwD,CAAC;YAC1F,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAC/E,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC;SACnC;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,EAAE,CACxD,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,EAAE,CAAC,CAChF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ClientOptions } from '../client.js';
|
|
3
|
+
import { ClientManager } from '../manager.js';
|
|
4
|
+
export interface McpOptions {
|
|
5
|
+
/** Defaults applied to launch_client calls. */
|
|
6
|
+
defaults?: Partial<ClientOptions>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createMcpServer(opts?: McpOptions): {
|
|
9
|
+
server: McpServer;
|
|
10
|
+
manager: ClientManager;
|
|
11
|
+
};
|
|
12
|
+
/** Runs the MCP server over stdio until the client disconnects. stdout carries only protocol messages. */
|
|
13
|
+
export declare function runMcpStdio(opts?: McpOptions): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ClientManager } from '../manager.js';
|
|
4
|
+
import { resolvePaths } from '../paths.js';
|
|
5
|
+
import { VERSION } from '../version.js';
|
|
6
|
+
import { registerAccountTools } from './accounts.js';
|
|
7
|
+
import { registerActTools } from './act.js';
|
|
8
|
+
import { registerExtensionTools } from './extensions.js';
|
|
9
|
+
import { registerItemTools } from './items.js';
|
|
10
|
+
import { registerLifecycleTools } from './lifecycle.js';
|
|
11
|
+
import { registerObserveTools } from './observe.js';
|
|
12
|
+
import { BackgroundTasks } from './tasks.js';
|
|
13
|
+
const INSTRUCTIONS = `Calcite drives real Minecraft Java Edition clients (1.14.4+ fully; older versions launch without probe features).
|
|
14
|
+
|
|
15
|
+
Flow: launch_client (the first launch of a version downloads ~0.5-1 GB and can take minutes) → observe and act → stop_client.
|
|
16
|
+
|
|
17
|
+
Observe: surroundings gives a map of the area with nearby blocks and entities — start there. find_blocks locates resources, get_entities lists entities with ids, get_state shows health, food and position, screenshot shows the view.
|
|
18
|
+
|
|
19
|
+
Act: walk_to finds a path to a point; dig mines, attack and use (right click: chests, doors, placing blocks, eating) take entity ids or block coordinates. get_inventory, craft and select_slot handle items; get_container, transfer and click_slot work with chests and furnaces.
|
|
20
|
+
|
|
21
|
+
Long actions (walk_to, dig, craft) accept background: true — follow them with get_task, cancel with stop_actions, and pass stopOnDamage to stop when attacked. One action runs at a time; starting another cancels the running one.
|
|
22
|
+
|
|
23
|
+
Events: get_events and wait_for {event} report world.join, player.hurt, player.death, inventory.change, container.open and more, plus events from extensions.
|
|
24
|
+
|
|
25
|
+
Accounts: offline accounts need no login. For premium servers call account_login_start, show the URL to the user, then poll account_login_status.
|
|
26
|
+
|
|
27
|
+
Screenshots need render "on-demand" (default) or "always". Mods: launch_client with loader "fabric", "forge" or "neoforge" and mods such as "modrinth:fabric-api". Extensions (probe jars) add commands: list_extensions, call_extension.`;
|
|
28
|
+
export function createMcpServer(opts = {}) {
|
|
29
|
+
const server = new McpServer({ name: 'calcite', version: VERSION }, { instructions: INSTRUCTIONS });
|
|
30
|
+
const manager = new ClientManager();
|
|
31
|
+
const ctx = { server, manager, paths: resolvePaths(), tasks: new BackgroundTasks(), defaults: opts.defaults ?? {} };
|
|
32
|
+
registerLifecycleTools(ctx);
|
|
33
|
+
registerObserveTools(ctx);
|
|
34
|
+
registerActTools(ctx);
|
|
35
|
+
registerItemTools(ctx);
|
|
36
|
+
registerExtensionTools(ctx);
|
|
37
|
+
registerAccountTools(ctx);
|
|
38
|
+
return { server, manager };
|
|
39
|
+
}
|
|
40
|
+
/** Runs the MCP server over stdio until the client disconnects. stdout carries only protocol messages. */
|
|
41
|
+
export async function runMcpStdio(opts = {}) {
|
|
42
|
+
const { server, manager } = createMcpServer(opts);
|
|
43
|
+
const transport = new StdioServerTransport();
|
|
44
|
+
let closing = false;
|
|
45
|
+
const close = async () => {
|
|
46
|
+
if (closing)
|
|
47
|
+
return;
|
|
48
|
+
closing = true;
|
|
49
|
+
await manager.stopAll();
|
|
50
|
+
process.exit(0);
|
|
51
|
+
};
|
|
52
|
+
transport.onclose = () => void close();
|
|
53
|
+
process.stdin.once('end', () => void close());
|
|
54
|
+
process.once('SIGINT', () => void close());
|
|
55
|
+
process.once('SIGTERM', () => void close());
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAO7C,MAAM,YAAY,GAAG;;;;;;;;;;;;;;0OAcqN,CAAC;AAE3O,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,CAAC;IACpG,MAAM,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;IACpC,MAAM,GAAG,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,eAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;IACjI,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5B,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC1B,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACtB,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACvB,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5B,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAmB,EAAE;IACrD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;QACvB,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC;IACvC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { background, clientName, timeoutSeconds, tool } from './shared.js';
|
|
3
|
+
/** The inventory, containers and crafting. */
|
|
4
|
+
export function registerItemTools({ server, manager, tasks }) {
|
|
5
|
+
tool(server, 'get_inventory', {
|
|
6
|
+
title: 'Inventory',
|
|
7
|
+
description: 'Non-empty inventory slots (0-8 hotbar, 9-35 main, 36-39 armor, 40 offhand) and the selected hotbar slot.',
|
|
8
|
+
inputSchema: { client: clientName },
|
|
9
|
+
}, async ({ client }) => manager.resolve(client).inventory());
|
|
10
|
+
tool(server, 'select_slot', {
|
|
11
|
+
title: 'Select hotbar slot',
|
|
12
|
+
description: 'Selects hotbar slot 0-8 (the held item).',
|
|
13
|
+
inputSchema: { client: clientName, slot: z.number().int().min(0).max(8) },
|
|
14
|
+
}, async ({ client, slot }) => manager.resolve(client).selectSlot(slot));
|
|
15
|
+
tool(server, 'craft', {
|
|
16
|
+
title: 'Craft an item',
|
|
17
|
+
description: 'Crafts an item from ingredients in the inventory through the recipe book. 2×2 recipes use the inventory grid; bigger ones need a crafting table within reach (opened and closed automatically). Only recipes the player has unlocked are known — they unlock on first picking up an ingredient.',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
client: clientName,
|
|
20
|
+
item: z.string().min(1).describe('Item id, e.g. "oak_planks" or "minecraft:stick"'),
|
|
21
|
+
count: z
|
|
22
|
+
.number()
|
|
23
|
+
.int()
|
|
24
|
+
.positive()
|
|
25
|
+
.max(64 * 36)
|
|
26
|
+
.default(1)
|
|
27
|
+
.describe('How many items to make (recipes making several may give a few more)'),
|
|
28
|
+
background,
|
|
29
|
+
timeoutSeconds: timeoutSeconds(30),
|
|
30
|
+
},
|
|
31
|
+
}, async ({ client, item, count, background: bg, timeoutSeconds: seconds }) => {
|
|
32
|
+
const target = manager.resolve(client);
|
|
33
|
+
return tasks.run(target, 'craft', bg, () => target.craft(item, { count, timeoutMs: seconds * 1000 }));
|
|
34
|
+
});
|
|
35
|
+
tool(server, 'get_container', {
|
|
36
|
+
title: 'Open container',
|
|
37
|
+
description: 'The open container (chest, barrel, furnace, villager trades...) with its non-empty slots; slots 0..containerSlots-1 are the container, the rest the player inventory. Furnaces also report lit, progress and fuel. waitSeconds waits for one to open, e.g. right after use on a chest.',
|
|
38
|
+
inputSchema: { client: clientName, waitSeconds: z.number().min(0).max(30).default(0) },
|
|
39
|
+
}, async ({ client, waitSeconds }) => manager.resolve(client).container({ waitMs: waitSeconds * 1000 }));
|
|
40
|
+
tool(server, 'transfer', {
|
|
41
|
+
title: 'Move items',
|
|
42
|
+
description: 'Moves items of one kind between the open container and the inventory. Without count and slot whole stacks are shift-clicked and the game picks the slots (a furnace takes fuel into its fuel slot and ores into its input); otherwise up to count items go into slot (or the first slots that take them). For a furnace: slot 0 input, 1 fuel, 2 output.',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
client: clientName,
|
|
45
|
+
item: z.string().min(1).describe('Item id, e.g. "coal"'),
|
|
46
|
+
to: z.enum(['container', 'inventory']).default('container'),
|
|
47
|
+
count: z.number().int().positive().optional(),
|
|
48
|
+
slot: z.number().int().nonnegative().optional().describe('Target menu slot'),
|
|
49
|
+
},
|
|
50
|
+
}, async ({ client, item, ...opts }) => manager.resolve(client).transfer(item, opts));
|
|
51
|
+
tool(server, 'click_slot', {
|
|
52
|
+
title: 'Click a container slot',
|
|
53
|
+
description: 'Clicks a slot of the open container (or of the inventory when none is open) and returns the new contents. mode: pickup (button 0 left / 1 right), quick_move (shift click: move the stack between container and inventory), swap (button = hotbar slot 0-8, 40 offhand), throw (button 1 = whole stack), clone, quick_craft, pickup_all. Slot -999 clicks outside (drops the carried stack).',
|
|
54
|
+
inputSchema: {
|
|
55
|
+
client: clientName,
|
|
56
|
+
slot: z.number().int().min(-999),
|
|
57
|
+
button: z.number().int().min(0).max(40).default(0),
|
|
58
|
+
mode: z.enum(['pickup', 'quick_move', 'swap', 'clone', 'throw', 'quick_craft', 'pickup_all']).default('pickup'),
|
|
59
|
+
},
|
|
60
|
+
}, async ({ client, slot, button, mode }) => manager.resolve(client).click(slot, { button, mode }));
|
|
61
|
+
tool(server, 'close_container', { title: 'Close container', description: 'Closes the open container or screen.', inputSchema: { client: clientName } }, async ({ client }) => {
|
|
62
|
+
await manager.resolve(client).closeContainer();
|
|
63
|
+
return 'closed';
|
|
64
|
+
});
|
|
65
|
+
tool(server, 'drop_item', {
|
|
66
|
+
title: 'Drop item',
|
|
67
|
+
description: 'Drops one item, or the whole stack, from the selected hotbar slot.',
|
|
68
|
+
inputSchema: { client: clientName, all: z.boolean().default(false) },
|
|
69
|
+
}, async ({ client, all }) => manager.resolve(client).drop({ all }));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items.js","sourceRoot":"","sources":["../../src/mcp/items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAoB,MAAM,aAAa,CAAC;AAE7F,8CAA8C;AAC9C,MAAM,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAe;IACvE,IAAI,CACF,MAAM,EACN,eAAe,EACf;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,0GAA0G;QACvH,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAC1D,CAAC;IAEF,IAAI,CACF,MAAM,EACN,aAAa,EACb;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,0CAA0C;QACvD,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;KAC1E,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CACrE,CAAC;IAEF,IAAI,CACF,MAAM,EACN,OAAO,EACP;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,iSAAiS;QACnS,WAAW,EAAE;YACX,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iDAAiD,CAAC;YACnF,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;iBACZ,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,qEAAqE,CAAC;YAClF,UAAU;YACV,cAAc,EAAE,cAAc,CAAC,EAAE,CAAC;SACnC;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,EAAE;QACzE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IACxG,CAAC,CACF,CAAC;IAEF,IAAI,CACF,MAAM,EACN,eAAe,EACf;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,wRAAwR;QAC1R,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;KACvF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,CAAC,CACrG,CAAC;IAEF,IAAI,CACF,MAAM,EACN,UAAU,EACV;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,0VAA0V;QAC5V,WAAW,EAAE;YACX,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YACxD,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;YAC3D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;SAC7E;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAClF,CAAC;IAEF,IAAI,CACF,MAAM,EACN,YAAY,EACZ;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,8XAA8X;QAChY,WAAW,EAAE;YACX,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;YAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAClD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;SAChH;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAChG,CAAC;IAEF,IAAI,CACF,MAAM,EACN,iBAAiB,EACjB,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,sCAAsC,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EACtH,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC,CACF,CAAC;IAEF,IAAI,CACF,MAAM,EACN,WAAW,EACX;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;KACrE,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CACjE,CAAC;AACJ,CAAC"}
|