mcdev-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCDEV_AST_PARSER | No | Use AST-based Java indexer instead of regex parser. Set to '1' or 'true' before init or rebuild. | |
| MCDEV_RUN_COMMAND | No | Enable mc_run_command tool. Set to '1' or 'true' to enable. | |
| MCDEV_SCRIPT_LOGS | No | Enable mc_script_logs tool and script execution logging. Set to '1' or 'true' to enable. | |
| MCDEV_SUPPRESS_INDEXER_HINT | No | Suppress the one-time hint about indexer version mismatch. Set to '1' to silence. |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {} |
| resources | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| mc_versionB | Manage Minecraft versions for static analysis tools. Actions:
|
| mc_searchA | Search decompiled Minecraft or Fabric API source code for classes, methods, or fields by name pattern. Each hit returns enough context to make follow-up mc_get_class / mc_get_method calls unnecessary in trivial cases:
Pass type="class"/"method"/"field" to filter; defaults to all three. Results are capped (default 50, max 1000). Pass |
| mc_get_classA | Get info about a Minecraft or Fabric API class. Use the "view" parameter to control the response size:
|
| mc_get_methodA | Get the source code for a specific method in a class, with surrounding context. Useful for understanding method implementation details. |
| mc_find_refsA | Find callers (who calls this method) or callees (what this method calls) using the callgraph database. Useful for understanding code dependencies. Results are capped (default 100, max 5000). Pass |
| mc_list_classesA | List all classes under a specific package path. Returns class names and their source locations. Use this to discover classes in a package hierarchy. Results are capped (default 200, max 5000). Pass |
| mc_list_packagesA | List all available packages. Optionally filter by namespace (minecraft or fabric). Use this to discover package structure. Results are capped (default 500, max 5000). Pass |
| mc_find_hierarchyA | Find classes that extend (subclasses) or implement (implementors) a given class or interface. Useful for understanding class inheritance relationships. Results are capped (default 200, max 5000). Pass |
| mc_connectA | Connect to a running Minecraft instance with the DebugBridge mod. Optional - other runtime tools auto-connect if needed. Useful to specify a non-default port, reconnect to a different instance, or get session info. If port is not specified, scans ports 9876-9886 to find the mod. Use reset=true to disconnect and clear state before reconnecting. |
| mc_executeA | Execute GROOVY code in the Minecraft session (the runtime migrated from Lua to Apache Groovy 5 in mid-2026 — see the migration note at the end if you knew the old surface). The binding is persistent: undeclared assignments (x = 5) survive to later calls; def x is script-local. PREFER NATIVE TOOLS WHERE POSSIBLE — they're faster and avoid script overhead:
Pre-bound globals: mc (Minecraft instance), player, level — plus the "java" helper. Mojang names everywhere, on every Minecraft version: obj.foo reads a field (JavaBean getter fallback), obj.foo(args) calls a method. Overloads resolve by argument types; decimal literals coerce to double/float params. Minecraft classes can't be named directly on obfuscated builds — load them via java.type: def Vec3 = java.type('net.minecraft.world.phys.Vec3'); construct with Vec3(1, 2, 3) or Vec3.create(1, 2, 3). (Single-quote class names: double-quoted GStrings interpolate the $ in inner-class names.) The "java" helper provides:
Reflection helpers for exploring API:
Plain JDK classes work natively (System.currentTimeMillis(), new File(path).text = "..."). Sandbox: Runtime / ProcessBuilder / java.net.* are blocked; file I/O is allowed. Caveat: bridge-wrapped Minecraft objects don't auto-unwrap when passed to NATIVE Java calls like new File(wrappedFile, name) — pass strings/primitives or unwrap with wrapped.getTarget(). Bridge-dispatched calls (anything on mc/player/level or a java.type class) unwrap arguments automatically. Use "return " to get a value back; println/print output is captured. Returned Minecraft objects serialize as {className, ref, toString, fields} — resume them later with java.ref(ref). timeoutMs: optional per-call deadline in ms (default 10000, max 300000 = 5 min). Bump it for bulk reflection or heavy file I/O — but prefer sync{} batching or a native tool over raising the timeout. MIGRATING FROM THE OLD LUA SURFACE (pre-2026-06): obj:method(args) -> obj.method(args); java.import(name) -> java.type(name); java.new(Cls, args) -> Cls(args) or Cls.create(args); java.iter/java.array -> java.list; java.typeof -> java.typeName; java.cast - removed (dispatch walks the runtime hierarchy, no cast needed); io.open(...) -> new File(...); os.time() -> System.currentTimeMillis(); print(x) -> println x; pcall -> try/catch; local x -> def x; {a = 1} tables -> [a: 1] maps and [1, 2, 3] lists. |
| mc_snapshotA | Get a structured snapshot of the current game state. Returns player position, health, food, dimension, game mode, time of day, weather, etc. No scripting needed - quick overview of current state. |
| mc_screenshotA | Capture the current Minecraft client framebuffer as a JPEG file on the machine running the mod, and return its absolute path. Use the Read tool to view the image. The capture runs on the render thread and pauses for at most one frame; the game otherwise continues. Works while the game is paused (returns the last rendered frame). Defaults are tuned for low-bandwidth visual inspection: downscale=2, quality=0.75. Override only if you specifically need higher fidelity. The mod and the MCP server must run on the same machine for the returned path to be readable here. |
| mc_record_videoA | Capture a short burst of the Minecraft client framebuffer for debugging temporal rendering issues — animation glitches, shader bugs, particles, sub-tick artifacts that mc_screenshot can't resolve. Use the Read tool to view the result. Two output modes:
Caps (validated mod-side, request rejected if exceeded):
Pick interval deliberately. Default to a numeric ms (50–100 ms is usually right) — smooth motion, never drops frames. Use "frame" only when sub-tick detail matters; at that cadence the encoder may fall behind and the response's "dropped" count tells you how many frames were skipped. The mod and the MCP server must run on the same machine for the returned paths to be readable here. Files land under /debugbridge-recordings//. |
| mc_nearby_entitiesA | Get nearby entities in the world (mobs, items, projectiles, players, etc.). Returns id, type (Mojang class name), position, distance, and a primaryEquipment summary (held item / framed item / displayed item) where applicable. Prefer this over iterating entities via mc_execute — no script round-trip, and the summary shape is already curated. (If you do script it, batch the loop in sync { } .) Use mc_entity_details to drill into a specific entity by id. Set includeIcons=true to also receive a top-level icons map keyed by itemId ({base64Png, width, height, spriteName}) for every primaryEquipment item — lets you see what entities are holding/displaying without per-entity mc_get_entity_item_texture calls. Deduplicated across entities. |
| mc_entity_detailsA | Get full details for one entity by id (the id field returned by mc_nearby_entities). Includes equipment slots with damage and custom names, mounted vehicle, passengers, attributes, and frame contents where applicable. Returns {gone: true} if the entity has despawned or its chunk has unloaded. |
| mc_nearby_blocksA | Get nearby block-entities (signs, chests, banners, beacons, hoppers, furnaces, skulls, etc.) — the blocks worth browsing for debugging. Plain terrain (dirt, stone) is intentionally excluded. Returns x, y, z, blockId (e.g. "minecraft:oak_sign"), type (Mojang class name), and distance for each. Use mc_block_details to drill in. |
| mc_block_detailsA | Get details for the block-entity at (x, y, z): sign lines, chest contents, banner patterns, skull profile, beacon level, etc. Returns {gone: true} if there is no block-entity at that position (e.g. plain terrain, or it was broken since the last mc_nearby_blocks call). |
| mc_looked_at_entityA | Returns the entity id the player is currently aiming at, or null if none is within range. Useful for "what is that thing?" questions where the user gestures at an entity in the world. Pair with mc_entity_details. |
| mc_set_entity_glowA | Make an entity render with the team-color outline so the user can spot it in-world (or remove the outline). Client-side only — no server authority needed. Pair with mc_nearby_entities to find ids. Glow may "stick" to a stale id if the entity's chunk unloads; harmless. |
| mc_set_block_glowA | Highlight a block in-world (yellow outline on 1.19, vanilla test-highlight on 1.21.11) or remove the highlight. Useful for pointing a specific sign / chest / etc. out to the user. Pair with mc_nearby_blocks to find positions; use mc_clear_block_glow to clear all highlights at once. |
| mc_clear_block_glowA | Clear all block highlights set via mc_set_block_glow. |
| mc_get_item_textureA | Render the item in the player's inventory slot N as a PNG you can see directly. Honors damage / CustomModelData resource-pack overrides on 1.21.11; falls back to the baked sprite on 1.19. Returns the rendered PNG plus a one-line text caption with dimensions + sprite name. |
| mc_get_entity_item_textureA | Render an item carried by another entity (slot is "mainhand", "offhand", "head", "chest", "legs", or "feet") as a PNG you can see directly. Pair with mc_nearby_entities to find ids. |
| mc_get_item_texture_by_idA | Render the default texture for an item registry id (e.g. "minecraft:diamond_pickaxe") as a PNG you can see directly. No inventory slot required. |
| mc_chat_historyA | Get the most recent client-side chat messages — what the user has seen in the chat overlay, including system messages and command output. Prefer this over walking mc.gui.getChat().allMessages from Groovy (which costs one bridge round-trip per field on each message). Returns {plain, addedTime} per message, newest-first. Set includeJson=true to also receive each message as a structured Component (preserves colors, styles, click events, hover events) — handy for parsing colored command output. |
| mc_screen_inspectA | Snapshot the screen the player currently has open. Returns {open: false} if no screen is displayed; otherwise {open, type, title, ...}. For container screens (chests, anvils, brewing stands, etc.) also returns {menuClass, slots: [{idx, container, item:{itemId, count, damage, maxDamage, name}}]} in a single native pass — cheaper than iterating slots from a script (one bridge call instead of per-slot traffic). Set includeIcons=true to also receive a top-level icons map keyed by itemId ({base64Png, width, height, spriteName}) — lets you see every item in the container in one call. Deduplicated across slots so a chest of stone+dirt only renders two icons. Adds a few KB to the response per unique item. |
| mc_join_serverA | Join a multiplayer server by address ("host" or "host:port"). Disconnects from the current world/server first if needed, so this changes the user's play session — don't point it at a new server without being asked. The server's resource pack is pre-accepted by default so the join doesn't stall on the confirmation prompt. The bridge ack means the connect attempt has started — current bridges defer it until the client has settled (no startup/reload overlay), so a join issued right after client launch is safe and may take some extra seconds to ack. By default this also polls until the player is actually in-world: success when a game snapshot shows a player, failure when a DisconnectedScreen appears (its title is returned as the reason). When called from inside a world, the poll first waits for the old session to drop so a stale snapshot of it can't masquerade as the new join. Set wait=false to just fire the join and return. For repeated automated test runs, prefer a local throwaway server over a live community server — live servers have nondeterministic worlds, other players, and rules about automation. Requires session_control_enabled=true in the DebugBridge config. |
| mc_leave_serverA | Leave the current world or server and return to the title screen. If not in a world, it still resets whatever menu screen is open back to the title screen. This ends the user's current play session — only do it when asked, or as part of a dev loop the user set up. Fire-and-acknowledge: the ack means the disconnect was queued on the game thread, not that it finished. Requires session_control_enabled=true in the DebugBridge config. |
| mc_wait_until_in_worldA | Poll until the player is in a world (or the join visibly failed). Checks every second: a game snapshot with a player present means in-world; a DisconnectedScreen means the join failed and its title is returned as the reason; anything else keeps waiting until the timeout. Use after mc_join_server with wait=false, after a relaunch, or whenever you need to confirm the client finished loading into a world. If you fired the join from INSIDE a world (mc_join_server wait=false), pass requireAbsenceFirst=true: on older bridges the ack comes before the old world tears down, so the first polls can still see its player and report in-world for a join that hasn't happened yet (current bridges ack after teardown — the gate is harmless insurance there). Read-only — doesn't require session control to be enabled. |
| mc_quit_clientA | Gracefully shut down the entire Minecraft client. This tears down the user's whole play session, including any world or server they're in — only do it when asked, or as part of a dev loop the user set up (typically the quit step of build → deploy → quit → launch → mc_wait_for_bridge; see the mcdev://guides/dev-loop resource). Fire-and-acknowledge: the WebSocket is expected to drop moments after the ack (that counts as success). By default the tool then waits for the client to be truly gone: it resolves the PID listening on the bridge port before quitting, polls until the port stops listening, then until that process exits — so on success it's safe to relaunch immediately, even through launchers that track the instance (Prism silently ignores --launch while the old process lives). When the PID can't be resolved (no lsof, permissions), it falls back to port-close-only and the result says so — the JVM can outlive the port by a few seconds, so in that case confirm the process exited yourself (pgrep / kill -0) before relaunching. Requires session_control_enabled=true in the DebugBridge config. |
| mc_wait_for_bridgeA | Block until a freshly (re)launched Minecraft client's DebugBridge answers, then connect to it. Sweeps ports 9876-9886 once per second, verifying the answering instance is the expected one — by game directory when known from the previous connection, else by Minecraft version — so a second running instance (e.g. a 1.19 client next to the 1.21 one) is never mistaken for it. Read-only; doesn't require session control. Use this instead of polling mc_connect yourself after launching the client (typically right after mc_quit_client + a detached launch command — see the mcdev://guides/dev-loop resource). On timeout, the likely causes are a launcher login prompt or a crash during startup. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| python-scripting | How to drive a live Minecraft instance from Python by speaking the DebugBridge WebSocket protocol directly — wire format, a minimal asyncio client, and the Groovy surface you send through it. Read this before writing a Python script that bypasses the mcdev-mcp tools. |
| dev-loop | How a coding agent runs the full mod test loop without human interaction: discover the launcher and instance from the bridge's gameDir, deploy the jar, quit via mc_quit_client, launch detached from the shell, reconnect with mc_wait_for_bridge, and rejoin a server. Read this before restarting the Minecraft client or automating mod testing. |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/use-ai-for-mc/mcdev-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server