awesome-mineflayer-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/bot/action-locks.d.ts +33 -0
  4. package/dist/bot/action-locks.d.ts.map +1 -0
  5. package/dist/bot/action-locks.js +63 -0
  6. package/dist/bot/action-locks.js.map +1 -0
  7. package/dist/bot/events.d.ts +51 -0
  8. package/dist/bot/events.d.ts.map +1 -0
  9. package/dist/bot/events.js +67 -0
  10. package/dist/bot/events.js.map +1 -0
  11. package/dist/bot/manager.d.ts +72 -0
  12. package/dist/bot/manager.d.ts.map +1 -0
  13. package/dist/bot/manager.js +358 -0
  14. package/dist/bot/manager.js.map +1 -0
  15. package/dist/bot/plugins.d.ts +9 -0
  16. package/dist/bot/plugins.d.ts.map +1 -0
  17. package/dist/bot/plugins.js +45 -0
  18. package/dist/bot/plugins.js.map +1 -0
  19. package/dist/bot/state.d.ts +19 -0
  20. package/dist/bot/state.d.ts.map +1 -0
  21. package/dist/bot/state.js +120 -0
  22. package/dist/bot/state.js.map +1 -0
  23. package/dist/bot/windows.d.ts +30 -0
  24. package/dist/bot/windows.d.ts.map +1 -0
  25. package/dist/bot/windows.js +68 -0
  26. package/dist/bot/windows.js.map +1 -0
  27. package/dist/bot/wire-events.d.ts +13 -0
  28. package/dist/bot/wire-events.d.ts.map +1 -0
  29. package/dist/bot/wire-events.js +168 -0
  30. package/dist/bot/wire-events.js.map +1 -0
  31. package/dist/config.d.ts +22 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +41 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/context.d.ts +14 -0
  36. package/dist/context.d.ts.map +1 -0
  37. package/dist/context.js +3 -0
  38. package/dist/context.js.map +1 -0
  39. package/dist/index.d.ts +9 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +41 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/resources/register.d.ts +12 -0
  44. package/dist/resources/register.d.ts.map +1 -0
  45. package/dist/resources/register.js +162 -0
  46. package/dist/resources/register.js.map +1 -0
  47. package/dist/schemas/common.d.ts +39 -0
  48. package/dist/schemas/common.d.ts.map +1 -0
  49. package/dist/schemas/common.js +35 -0
  50. package/dist/schemas/common.js.map +1 -0
  51. package/dist/server.d.ts +8 -0
  52. package/dist/server.d.ts.map +1 -0
  53. package/dist/server.js +76 -0
  54. package/dist/server.js.map +1 -0
  55. package/dist/tools/beds.d.ts +4 -0
  56. package/dist/tools/beds.d.ts.map +1 -0
  57. package/dist/tools/beds.js +49 -0
  58. package/dist/tools/beds.js.map +1 -0
  59. package/dist/tools/chat.d.ts +4 -0
  60. package/dist/tools/chat.d.ts.map +1 -0
  61. package/dist/tools/chat.js +148 -0
  62. package/dist/tools/chat.js.map +1 -0
  63. package/dist/tools/combat.d.ts +4 -0
  64. package/dist/tools/combat.d.ts.map +1 -0
  65. package/dist/tools/combat.js +166 -0
  66. package/dist/tools/combat.js.map +1 -0
  67. package/dist/tools/containers.d.ts +4 -0
  68. package/dist/tools/containers.d.ts.map +1 -0
  69. package/dist/tools/containers.js +140 -0
  70. package/dist/tools/containers.js.map +1 -0
  71. package/dist/tools/crafting.d.ts +4 -0
  72. package/dist/tools/crafting.d.ts.map +1 -0
  73. package/dist/tools/crafting.js +114 -0
  74. package/dist/tools/crafting.js.map +1 -0
  75. package/dist/tools/creative.d.ts +4 -0
  76. package/dist/tools/creative.d.ts.map +1 -0
  77. package/dist/tools/creative.js +90 -0
  78. package/dist/tools/creative.js.map +1 -0
  79. package/dist/tools/digging.d.ts +4 -0
  80. package/dist/tools/digging.d.ts.map +1 -0
  81. package/dist/tools/digging.js +177 -0
  82. package/dist/tools/digging.js.map +1 -0
  83. package/dist/tools/enchant-anvil.d.ts +4 -0
  84. package/dist/tools/enchant-anvil.d.ts.map +1 -0
  85. package/dist/tools/enchant-anvil.js +210 -0
  86. package/dist/tools/enchant-anvil.js.map +1 -0
  87. package/dist/tools/events.d.ts +4 -0
  88. package/dist/tools/events.d.ts.map +1 -0
  89. package/dist/tools/events.js +43 -0
  90. package/dist/tools/events.js.map +1 -0
  91. package/dist/tools/fishing-books-signs.d.ts +4 -0
  92. package/dist/tools/fishing-books-signs.d.ts.map +1 -0
  93. package/dist/tools/fishing-books-signs.js +97 -0
  94. package/dist/tools/fishing-books-signs.js.map +1 -0
  95. package/dist/tools/furnace.d.ts +4 -0
  96. package/dist/tools/furnace.d.ts.map +1 -0
  97. package/dist/tools/furnace.js +220 -0
  98. package/dist/tools/furnace.js.map +1 -0
  99. package/dist/tools/gathering.d.ts +4 -0
  100. package/dist/tools/gathering.d.ts.map +1 -0
  101. package/dist/tools/gathering.js +153 -0
  102. package/dist/tools/gathering.js.map +1 -0
  103. package/dist/tools/inventory.d.ts +4 -0
  104. package/dist/tools/inventory.d.ts.map +1 -0
  105. package/dist/tools/inventory.js +185 -0
  106. package/dist/tools/inventory.js.map +1 -0
  107. package/dist/tools/lifecycle.d.ts +4 -0
  108. package/dist/tools/lifecycle.d.ts.map +1 -0
  109. package/dist/tools/lifecycle.js +80 -0
  110. package/dist/tools/lifecycle.js.map +1 -0
  111. package/dist/tools/look.d.ts +4 -0
  112. package/dist/tools/look.d.ts.map +1 -0
  113. package/dist/tools/look.js +58 -0
  114. package/dist/tools/look.js.map +1 -0
  115. package/dist/tools/movement.d.ts +4 -0
  116. package/dist/tools/movement.d.ts.map +1 -0
  117. package/dist/tools/movement.js +433 -0
  118. package/dist/tools/movement.js.map +1 -0
  119. package/dist/tools/registry.d.ts +32 -0
  120. package/dist/tools/registry.d.ts.map +1 -0
  121. package/dist/tools/registry.js +36 -0
  122. package/dist/tools/registry.js.map +1 -0
  123. package/dist/tools/settings.d.ts +4 -0
  124. package/dist/tools/settings.d.ts.map +1 -0
  125. package/dist/tools/settings.js +49 -0
  126. package/dist/tools/settings.js.map +1 -0
  127. package/dist/tools/state-inspect.d.ts +4 -0
  128. package/dist/tools/state-inspect.d.ts.map +1 -0
  129. package/dist/tools/state-inspect.js +371 -0
  130. package/dist/tools/state-inspect.js.map +1 -0
  131. package/dist/tools/survival.d.ts +4 -0
  132. package/dist/tools/survival.d.ts.map +1 -0
  133. package/dist/tools/survival.js +140 -0
  134. package/dist/tools/survival.js.map +1 -0
  135. package/dist/tools/tool-select.d.ts +4 -0
  136. package/dist/tools/tool-select.d.ts.map +1 -0
  137. package/dist/tools/tool-select.js +91 -0
  138. package/dist/tools/tool-select.js.map +1 -0
  139. package/dist/tools/vehicles.d.ts +4 -0
  140. package/dist/tools/vehicles.d.ts.map +1 -0
  141. package/dist/tools/vehicles.js +49 -0
  142. package/dist/tools/vehicles.js.map +1 -0
  143. package/dist/tools/villager.d.ts +4 -0
  144. package/dist/tools/villager.d.ts.map +1 -0
  145. package/dist/tools/villager.js +77 -0
  146. package/dist/tools/villager.js.map +1 -0
  147. package/dist/tools/world.d.ts +4 -0
  148. package/dist/tools/world.d.ts.map +1 -0
  149. package/dist/tools/world.js +177 -0
  150. package/dist/tools/world.js.map +1 -0
  151. package/dist/util/errors.d.ts +29 -0
  152. package/dist/util/errors.d.ts.map +1 -0
  153. package/dist/util/errors.js +38 -0
  154. package/dist/util/errors.js.map +1 -0
  155. package/dist/util/format.d.ts +8 -0
  156. package/dist/util/format.d.ts.map +1 -0
  157. package/dist/util/format.js +34 -0
  158. package/dist/util/format.js.map +1 -0
  159. package/dist/util/resolve.d.ts +35 -0
  160. package/dist/util/resolve.d.ts.map +1 -0
  161. package/dist/util/resolve.js +88 -0
  162. package/dist/util/resolve.js.map +1 -0
  163. package/dist/util/result.d.ts +7 -0
  164. package/dist/util/result.d.ts.map +1 -0
  165. package/dist/util/result.js +17 -0
  166. package/dist/util/result.js.map +1 -0
  167. package/dist/util/serialize.d.ts +75 -0
  168. package/dist/util/serialize.d.ts.map +1 -0
  169. package/dist/util/serialize.js +97 -0
  170. package/dist/util/serialize.js.map +1 -0
  171. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ryker Geesaman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # awesome-mineflayer-mcp
2
+
3
+ [![npm version](https://img.shields.io/npm/v/awesome-mineflayer-mcp.svg)](https://www.npmjs.com/package/awesome-mineflayer-mcp)
4
+ [![node](https://img.shields.io/node/v/awesome-mineflayer-mcp.svg)](https://nodejs.org)
5
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
6
+
7
+ A production-ready [Model Context Protocol](https://modelcontextprotocol.io) server that gives an LLM agent **standalone-equivalent control** over a [Mineflayer](https://github.com/PrismarineJS/mineflayer) Minecraft bot — movement, mining, crafting, inventory, combat, containers, chat, and much more — exposed as **110 strongly-typed tools** across 23 groups, with full bot lifecycle management and dual (poll + push) event streaming.
8
+
9
+ Backed by the Mineflayer ecosystem: `mineflayer-pathfinder` (A\* navigation), `mineflayer-pvp` (combat), `mineflayer-collectblock` (gathering), `mineflayer-tool` (auto tool-select), `mineflayer-auto-eat`, and `mineflayer-armor-manager`.
10
+
11
+ ---
12
+
13
+ ## Requirements
14
+
15
+ - **Node.js ≥ 20** (developed on 22.16)
16
+ - A Minecraft server to connect to (Java Edition). The bot auto-detects the server version.
17
+ - For online-mode servers: a Microsoft account (`auth: "microsoft"`).
18
+
19
+ ## Installation
20
+
21
+ Run it on demand with **npx** (no install needed):
22
+
23
+ ```bash
24
+ npx awesome-mineflayer-mcp
25
+ ```
26
+
27
+ …or install it globally:
28
+
29
+ ```bash
30
+ npm install -g awesome-mineflayer-mcp
31
+ awesome-mineflayer-mcp
32
+ ```
33
+
34
+ The server speaks MCP over **stdio**, so it is normally launched by your MCP client rather than run by hand.
35
+
36
+ ## Use with an MCP client
37
+
38
+ Add it to your client's MCP server configuration. The recommended form uses `npx` so you always get the latest published build:
39
+
40
+ **Claude Desktop** (`claude_desktop_config.json`), **Claude Code**, **Cursor**, or any stdio MCP client:
41
+
42
+ ```json
43
+ {
44
+ "mcpServers": {
45
+ "mineflayer": {
46
+ "command": "npx",
47
+ "args": ["-y", "awesome-mineflayer-mcp"],
48
+ "env": {
49
+ "MCP_DISABLE_GROUPS": ""
50
+ }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ If you installed it globally, use `"command": "awesome-mineflayer-mcp"` with `"args": []` instead.
57
+
58
+ ## Configuration (environment variables)
59
+
60
+ | Variable | Default | Purpose |
61
+ |---|---|---|
62
+ | `MCP_DISABLE_GROUPS` | _(none)_ | Comma-separated tool-group keys to disable (see catalog). Trim the surface for clients that struggle with 110 tools. |
63
+ | `MCP_CHARACTER_LIMIT` | `25000` | Max characters returned by any single tool call (truncated with a marker). |
64
+ | `MCP_EVENT_BUFFER` | `1000` | Size of the in-memory event ring buffer. |
65
+ | `MCP_THROTTLE_MS` | `250` | Minimum spacing between pushed resource-update / log notifications. |
66
+ | `MCP_PROXIMITY_RADIUS` | `32` | Radius (blocks) for proximity-filtered events (entity spawns, sounds). |
67
+ | `MCP_ACTION_TIMEOUT_MS` | `60000` | Default timeout for long actions when the caller omits one. |
68
+
69
+ Example — disable rarely-used groups:
70
+
71
+ ```
72
+ MCP_DISABLE_GROUPS=creative,villager,enchanting,settings
73
+ ```
74
+
75
+ ## Quick start (tool flow)
76
+
77
+ 1. **`connect_bot`** `{ host, username, auth }` — required first; resolves once the bot spawns.
78
+ 2. Act: **`goto`**, **`dig`**, **`collect_block`**, **`craft_item`**, **`pvp_attack`**, **`chat`**, …
79
+ 3. Observe: poll **`get_events`** (pass the returned `nextSince` each time) and **`get_state`**; or subscribe to the `bot://*` resources.
80
+ 4. **`disconnect_bot`** when done.
81
+
82
+ Block / item / entity arguments accept **human names** (`"iron_ore"`, `"diamond_pickaxe"`, `"zombie"`); unknown names return fuzzy suggestions.
83
+
84
+ ## Authentication
85
+
86
+ - `auth: "offline"` (default) — offline-mode servers; `username` is the in-game name.
87
+ - `auth: "microsoft"` — `username` is the account email. A device-code prompt is emitted as an `msa_code` event / log notification. Set **`profilesFolder`** to cache the token so subsequent runs skip the prompt, or pass a cached `accessToken`.
88
+
89
+ ---
90
+
91
+ ## Tool catalog (110 tools, 23 groups)
92
+
93
+ Group keys (for `MCP_DISABLE_GROUPS`) are shown in brackets.
94
+
95
+ - **Lifecycle** `[lifecycle]` — `connect_bot`, `disconnect_bot`, `reconnect_bot`, `respawn`, `get_connection_status`
96
+ - **State & inspection** `[state]` (read-only) — `get_state`, `get_inventory`, `list_players`, `list_entities`, `find_nearest_entity`, `get_entity_details`, `get_scoreboards`, `get_teams`, `get_boss_bars`, `get_control_states`, `get_chat_patterns`, `support_feature`, `pathfinder_status`, `get_settings`, `get_physics`, `get_loaded_plugins`
97
+ - **World queries** `[world]` (read-only) — `get_block_at`, `find_blocks`, `get_cursor_target`, `get_blocks_in_region`, `wait_for_chunks_to_load`
98
+ - **Movement & pathfinding** `[movement]` — `goto`, `set_goal`, `flee_from`, `follow_entity`, `stop_pathfinding`, `get_path_to`, `configure_movements`, `configure_pathfinder`, `set_control_state`, `clear_control_states`, `elytra_fly`, `wait_for_ticks`, `set_physics_enabled`
99
+ - **Look** `[look]` — `look_at`, `look`, `look_at_entity`
100
+ - **Digging & building** `[digging]` — `dig`, `place_block`, `activate_block`, `activate_entity`, `swing_arm`
101
+ - **Combat** `[combat]` — `pvp_attack`, `attack_entity`, `pvp_stop`, `pvp_configure`
102
+ - **Inventory & items** `[inventory]` — `equip_item`, `unequip_item`, `toss_item`, `set_quickbar_slot`, `consume`, `activate_item`, `click_window`, `move_slot_item`, `transfer_items`
103
+ - **Containers** `[containers]` — `open_container`, `read_open_container`, `container_deposit`, `container_withdraw`, `close_window`
104
+ - **Furnace / smelting** `[furnace]` — `open_furnace`, `furnace_action`, `furnace_status`, `smelt_item`
105
+ - **Enchanting & anvil** `[enchanting]` — `enchant_item`, `anvil_combine`
106
+ - **Villager trading** `[villager]` — `open_villager`, `trade_with_villager`
107
+ - **Crafting** `[crafting]` — `list_recipes`, `craft_item`
108
+ - **Block gathering** `[gathering]` — `collect_block`, `cancel_collect`, `set_collect_config`
109
+ - **Tool auto-select** `[tool]` — `equip_tool_for_block`, `set_tool_chest_locations`, `get_best_tool`
110
+ - **Survival automation** `[survival]` — `autoeat_set_enabled`, `autoeat_configure`, `autoeat_eat`, `autoeat_cancel`, `autoeat_preview`, `armor_equip_all`
111
+ - **Beds & sleep** `[beds]` — `sleep`, `wake`
112
+ - **Vehicles** `[vehicles]` — `mount_entity`, `dismount`, `steer_vehicle`
113
+ - **Fishing, books & signs** `[fishing]` — `fish`, `cancel_fish`, `write_book`, `update_sign`
114
+ - **Chat & communication** `[chat]` — `chat`, `whisper`, `run_command`, `tab_complete`, `register_chat_pattern`, `remove_chat_pattern`, `wait_for_message`
115
+ - **Settings** `[settings]` — `set_settings`
116
+ - **Creative mode** `[creative]` — `creative_set_inventory_slot`, `creative_clear_inventory`, `creative_fly`, `creative_fly_to`
117
+ - **Events & telemetry** `[events]` — `get_events`, `cancel_task`
118
+
119
+ Long-running actions (`goto`, `dig`, `collect_block`, `pvp_attack`, `fish`, `smelt_item`, `craft_item`) are mutually exclusive and cancellable — start a new movement/combat action to supersede the prior one, or call `stop_pathfinding` / `pvp_stop` / `cancel_collect` / `cancel_fish` / `cancel_task`.
120
+
121
+ ## Resources
122
+
123
+ Subscribe-capable JSON resources for clients that support resource subscriptions:
124
+
125
+ - `bot://state` — live self snapshot (position, vitals, gamemode, time, weather, held item, control states)
126
+ - `bot://inventory` — items, armor, off-hand, held slot
127
+ - `world://entities` — up to 50 nearest tracked entities
128
+ - `world://players` — server roster
129
+ - `bot://events` — tail of recent events
130
+
131
+ ## Events
132
+
133
+ Game events are delivered two ways:
134
+
135
+ - **Pull:** `get_events({ since, types, limit })` drains a ring buffer; pass the returned `nextSince` to read only new events. `dropped: true` signals the buffer overflowed since your `since`.
136
+ - **Push:** subscribed resources emit throttled `notifications/resources/updated`; notable lines (chat, death, kick, error, msa_code) are forwarded via `sendLoggingMessage`.
137
+
138
+ High-frequency observations (movement, per-tick updates, block/entity updates, time) are intentionally **not** buffered — read them on demand via `get_state` and the read-only tools.
139
+
140
+ ## Development (from source)
141
+
142
+ ```bash
143
+ git clone https://github.com/G0Osey99/awesome-mineflayer-mcp.git
144
+ cd awesome-mineflayer-mcp
145
+ npm install
146
+ npm run build # tsc -> dist/
147
+ npm run typecheck # tsc --noEmit
148
+ npm test # vitest (unit tests for the pure logic)
149
+ npm run dev # tsx src/index.ts (run from source, no build step)
150
+ ```
151
+
152
+ Architecture and the full design rationale: [`docs/superpowers/specs/2026-06-28-mineflayer-mcp-server-design.md`](docs/superpowers/specs/2026-06-28-mineflayer-mcp-server-design.md).
153
+
154
+ ```
155
+ src/
156
+ index.ts entry (stdio transport, graceful shutdown)
157
+ server.ts builds the McpServer, registers tool groups + resources
158
+ config.ts env + constants
159
+ bot/ manager (lifecycle FSM), plugins, events, wire-events, state, windows, action-locks
160
+ tools/ one module per tool group (+ registry.ts)
161
+ resources/ MCP resources + push notifications
162
+ util/ errors, format, result, resolve (name→id + fuzzy), serialize
163
+ schemas/ shared Zod fragments
164
+ ```
165
+
166
+ ## Publishing (maintainers)
167
+
168
+ ```bash
169
+ npm version patch # or minor / major — bumps package.json + tags
170
+ npm publish # the `prepare` script builds dist/ first; publishes to npm
171
+ git push --follow-tags
172
+ ```
173
+
174
+ The published package ships only `dist/`, `README.md`, and `LICENSE` (see the `files` field).
175
+
176
+ ## Limitations
177
+
178
+ - **One bot per server process** (single-session by design).
179
+ - **Evaluations require a seeded world.** A live Minecraft world is not deterministic, so the evaluation set in `eval/` targets a documented seeded fixture (see `eval/fixture.md`); it cannot be verified against an arbitrary live server.
180
+ - `cancel_fish` is best-effort (Mineflayer exposes no first-class fishing abort).
181
+ - Microsoft auth's first run needs an interactive device code (surfaced as an `msa_code` event); use `profilesFolder` to cache it.
182
+
183
+ ## License
184
+
185
+ MIT
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Mutual exclusion + cancellation for long-running, conflicting bot actions
3
+ * (goto, dig, collect_block, pvp_attack, fish, smelt_item, craft_item).
4
+ *
5
+ * Starting a new exclusive action cancels the previous one cleanly: the prior
6
+ * action's `onCancel` runs (e.g. `bot.pathfinder.stop()`) and its AbortSignal
7
+ * fires so any in-flight `await` can bail out.
8
+ */
9
+ export type CancelReason = "superseded" | "manual" | "shutdown";
10
+ export declare class CancelledError extends Error {
11
+ readonly reason: CancelReason;
12
+ constructor(reason: CancelReason);
13
+ }
14
+ export interface ActionHandle {
15
+ /** Aborts when this action is superseded/cancelled. */
16
+ signal: AbortSignal;
17
+ /** Call when the action finishes (success or failure) to release the lock. */
18
+ release: () => void;
19
+ }
20
+ export declare class ActionLocks {
21
+ private active;
22
+ get current(): string | null;
23
+ isBusy(): boolean;
24
+ /**
25
+ * Acquire the exclusive action lock, cancelling any prior holder.
26
+ * @param name Human label for diagnostics / errors.
27
+ * @param onCancel Best-effort cleanup invoked if this action is cancelled.
28
+ */
29
+ begin(name: string, onCancel?: (reason: CancelReason) => void): ActionHandle;
30
+ /** Cancel the current exclusive action, if any. Returns true if one was cancelled. */
31
+ cancelAll(reason?: CancelReason): boolean;
32
+ }
33
+ //# sourceMappingURL=action-locks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-locks.d.ts","sourceRoot":"","sources":["../../src/bot/action-locks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEhE,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;gBAClB,MAAM,EAAE,YAAY;CAKjC;AAOD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,MAAM,EAAE,WAAW,CAAC;IACpB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAA6B;IAE3C,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED,MAAM,IAAI,OAAO;IAIjB;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,YAAY;IAsB5E,sFAAsF;IACtF,SAAS,CAAC,MAAM,GAAE,YAAuB,GAAG,OAAO;CAOpD"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Mutual exclusion + cancellation for long-running, conflicting bot actions
3
+ * (goto, dig, collect_block, pvp_attack, fish, smelt_item, craft_item).
4
+ *
5
+ * Starting a new exclusive action cancels the previous one cleanly: the prior
6
+ * action's `onCancel` runs (e.g. `bot.pathfinder.stop()`) and its AbortSignal
7
+ * fires so any in-flight `await` can bail out.
8
+ */
9
+ export class CancelledError extends Error {
10
+ reason;
11
+ constructor(reason) {
12
+ super(`Action cancelled (${reason})`);
13
+ this.name = "CancelledError";
14
+ this.reason = reason;
15
+ }
16
+ }
17
+ export class ActionLocks {
18
+ active = null;
19
+ get current() {
20
+ return this.active?.name ?? null;
21
+ }
22
+ isBusy() {
23
+ return this.active !== null;
24
+ }
25
+ /**
26
+ * Acquire the exclusive action lock, cancelling any prior holder.
27
+ * @param name Human label for diagnostics / errors.
28
+ * @param onCancel Best-effort cleanup invoked if this action is cancelled.
29
+ */
30
+ begin(name, onCancel) {
31
+ this.cancelAll("superseded");
32
+ const controller = new AbortController();
33
+ const entry = {
34
+ name,
35
+ cancel: (reason) => {
36
+ try {
37
+ onCancel?.(reason);
38
+ }
39
+ finally {
40
+ controller.abort(new CancelledError(reason));
41
+ }
42
+ },
43
+ };
44
+ this.active = entry;
45
+ return {
46
+ signal: controller.signal,
47
+ release: () => {
48
+ if (this.active === entry)
49
+ this.active = null;
50
+ },
51
+ };
52
+ }
53
+ /** Cancel the current exclusive action, if any. Returns true if one was cancelled. */
54
+ cancelAll(reason = "manual") {
55
+ const a = this.active;
56
+ if (!a)
57
+ return false;
58
+ this.active = null;
59
+ a.cancel(reason);
60
+ return true;
61
+ }
62
+ }
63
+ //# sourceMappingURL=action-locks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-locks.js","sourceRoot":"","sources":["../../src/bot/action-locks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAe;IAC9B,YAAY,MAAoB;QAC9B,KAAK,CAAC,qBAAqB,MAAM,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAcD,MAAM,OAAO,WAAW;IACd,MAAM,GAAwB,IAAI,CAAC;IAE3C,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;IACnC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAY,EAAE,QAAyC;QAC3D,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAiB;YAC1B,IAAI;YACJ,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBACjB,IAAI,CAAC;oBACH,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;gBACrB,CAAC;wBAAS,CAAC;oBACT,UAAU,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;SACF,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK;oBAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YAChD,CAAC;SACF,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,SAAS,CAAC,SAAuB,QAAQ;QACvC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * In-memory event ring buffer.
3
+ *
4
+ * Discrete, agent-actionable game events are pushed here and drained via the
5
+ * `get_events` tool. Push listeners (registered by the resource layer) fan each
6
+ * event out to MCP logging / resource-update notifications, throttled elsewhere.
7
+ */
8
+ export interface GameEvent {
9
+ /** Monotonic sequence number (1-based). */
10
+ seq: number;
11
+ /** Unix epoch ms when captured. */
12
+ ts: number;
13
+ /** Event type, e.g. "chat", "death", "goal_reached". */
14
+ type: string;
15
+ /** Serialisable payload (already reduced to plain JSON). */
16
+ data: unknown;
17
+ }
18
+ export type EventPushListener = (event: GameEvent) => void;
19
+ export interface DrainOptions {
20
+ /** Return only events with seq strictly greater than this. */
21
+ since?: number;
22
+ /** Restrict to these event types. */
23
+ types?: string[];
24
+ /** Return at most this many (most recent kept). */
25
+ limit?: number;
26
+ }
27
+ export interface DrainResult {
28
+ events: GameEvent[];
29
+ /** Pass as `since` on the next call to continue without gaps. */
30
+ nextSince: number;
31
+ /** True if `since` pointed before the oldest retained event (some were lost). */
32
+ dropped: boolean;
33
+ }
34
+ export declare class EventBus {
35
+ private buffer;
36
+ private seqCounter;
37
+ private readonly listeners;
38
+ private readonly capacity;
39
+ constructor(capacity?: number);
40
+ /** Append an event and notify push listeners. Never throws. */
41
+ push(type: string, data?: unknown): GameEvent;
42
+ /** Drain events after `since`, optionally filtered by type and capped. */
43
+ drain(opts?: DrainOptions): DrainResult;
44
+ /** Most recent `n` events (used to seed the events resource). */
45
+ recent(n: number): GameEvent[];
46
+ get lastSeq(): number;
47
+ /** Register a push listener; returns an unsubscribe function. */
48
+ onPush(listener: EventPushListener): () => void;
49
+ clear(): void;
50
+ }
51
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/bot/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,SAAoB;IAIxC,+DAA+D;IAC/D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAc,GAAG,SAAS;IAenD,0EAA0E;IAC1E,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,WAAW;IAgB3C,iEAAiE;IACjE,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE;IAI9B,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,iEAAiE;IACjE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO/C,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * In-memory event ring buffer.
3
+ *
4
+ * Discrete, agent-actionable game events are pushed here and drained via the
5
+ * `get_events` tool. Push listeners (registered by the resource layer) fan each
6
+ * event out to MCP logging / resource-update notifications, throttled elsewhere.
7
+ */
8
+ import { EVENT_BUFFER_SIZE } from "../config.js";
9
+ export class EventBus {
10
+ buffer = [];
11
+ seqCounter = 0;
12
+ listeners = new Set();
13
+ capacity;
14
+ constructor(capacity = EVENT_BUFFER_SIZE) {
15
+ this.capacity = Math.max(1, capacity);
16
+ }
17
+ /** Append an event and notify push listeners. Never throws. */
18
+ push(type, data = null) {
19
+ const event = { seq: ++this.seqCounter, ts: Date.now(), type, data };
20
+ this.buffer.push(event);
21
+ const overflow = this.buffer.length - this.capacity;
22
+ if (overflow > 0)
23
+ this.buffer.splice(0, overflow);
24
+ for (const listener of this.listeners) {
25
+ try {
26
+ listener(event);
27
+ }
28
+ catch {
29
+ // A misbehaving listener must never break event capture.
30
+ }
31
+ }
32
+ return event;
33
+ }
34
+ /** Drain events after `since`, optionally filtered by type and capped. */
35
+ drain(opts = {}) {
36
+ const { since, types, limit } = opts;
37
+ const oldestSeq = this.buffer.length > 0 ? this.buffer[0].seq : this.seqCounter;
38
+ const dropped = since !== undefined && since + 1 < oldestSeq;
39
+ let out = since !== undefined ? this.buffer.filter((e) => e.seq > since) : this.buffer.slice();
40
+ if (types && types.length > 0) {
41
+ const set = new Set(types);
42
+ out = out.filter((e) => set.has(e.type));
43
+ }
44
+ if (limit !== undefined && limit >= 0 && out.length > limit) {
45
+ out = out.slice(out.length - limit);
46
+ }
47
+ return { events: out, nextSince: this.seqCounter, dropped };
48
+ }
49
+ /** Most recent `n` events (used to seed the events resource). */
50
+ recent(n) {
51
+ return this.buffer.slice(Math.max(0, this.buffer.length - n));
52
+ }
53
+ get lastSeq() {
54
+ return this.seqCounter;
55
+ }
56
+ /** Register a push listener; returns an unsubscribe function. */
57
+ onPush(listener) {
58
+ this.listeners.add(listener);
59
+ return () => {
60
+ this.listeners.delete(listener);
61
+ };
62
+ }
63
+ clear() {
64
+ this.buffer = [];
65
+ }
66
+ }
67
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/bot/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * BotManager — owns the single bot session and its lifecycle.
3
+ *
4
+ * Status FSM: disconnected → connecting → online → (reconnecting) → online | disconnected
5
+ * Lifecycle (connect/disconnect/reconnect) and end/kicked handling live here.
6
+ * Lifecycle + msa-code events are pushed to the EventBus so the resource/log
7
+ * layer can forward them to the MCP client.
8
+ */
9
+ import { type Bot } from "mineflayer";
10
+ import type { EventBus } from "./events.js";
11
+ import type { WindowManager } from "./windows.js";
12
+ import type { ActionLocks } from "./action-locks.js";
13
+ export type ConnectionStatus = "disconnected" | "connecting" | "online" | "reconnecting";
14
+ export interface ConnectOptions {
15
+ host: string;
16
+ port?: number;
17
+ username: string;
18
+ password?: string;
19
+ auth?: "offline" | "microsoft" | "mojang";
20
+ /** Omit / empty string => auto-detect from server. */
21
+ version?: string;
22
+ brand?: string;
23
+ respawn?: boolean;
24
+ physicsEnabled?: boolean;
25
+ viewDistance?: "far" | "normal" | "short" | "tiny";
26
+ chatLengthLimit?: number;
27
+ defaultChatPatterns?: boolean;
28
+ disableChatSigning?: boolean;
29
+ accessToken?: string;
30
+ clientToken?: string;
31
+ profilesFolder?: string;
32
+ keepAlive?: boolean;
33
+ checkTimeoutInterval?: number;
34
+ hideErrors?: boolean;
35
+ logErrors?: boolean;
36
+ autoReconnect?: boolean;
37
+ connectTimeoutMs?: number;
38
+ }
39
+ export declare class BotManager {
40
+ private readonly events;
41
+ private readonly windows;
42
+ private readonly locks;
43
+ private _bot;
44
+ private _status;
45
+ private lastOptions;
46
+ private lastEndReason;
47
+ private detachEvents;
48
+ private intentionalQuit;
49
+ private reconnectTimer;
50
+ private reconnectAttempt;
51
+ constructor(events: EventBus, windows: WindowManager, locks: ActionLocks);
52
+ get status(): ConnectionStatus;
53
+ /** The active, spawned bot, or throw NOT_CONNECTED. */
54
+ requireBot(): Bot;
55
+ botOrNull(): Bot | null;
56
+ statusReport(): Record<string, unknown>;
57
+ connect(opts: ConnectOptions): Promise<Record<string, unknown>>;
58
+ disconnect(reason?: string, force?: boolean): Promise<Record<string, unknown>>;
59
+ reconnect(override?: Partial<ConnectOptions>): Promise<Record<string, unknown>>;
60
+ /** Best-effort shutdown for process exit. */
61
+ shutdown(): void;
62
+ private buildBotOptions;
63
+ private spawnBot;
64
+ /** Permanent end/kicked handling (active after a successful spawn). */
65
+ private attachLifecycle;
66
+ private scheduleReconnect;
67
+ private cancelReconnectTimer;
68
+ private setStatus;
69
+ private detachAndClearBot;
70
+ private teardown;
71
+ }
72
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/bot/manager.ts"],"names":[],"mappings":"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"}