{"id":50906958,"url":"https://github.com/chapmanjw/minecraft-java-fabric-mcp-server","last_synced_at":"2026-06-16T06:03:09.748Z","repository":{"id":359268232,"uuid":"1244147824","full_name":"chapmanjw/minecraft-java-fabric-mcp-server","owner":"chapmanjw","description":"MCP Server Mod for Minecraft Java Edition and the FabricMC Fabric API","archived":false,"fork":false,"pushed_at":"2026-05-29T13:39:24.000Z","size":2689,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-29T15:14:43.120Z","etag":null,"topics":["claude","claude-code","mcp","mcp-server","minecraft","minecraft-java","minecraft-mod"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chapmanjw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-20T02:20:59.000Z","updated_at":"2026-05-29T13:39:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/chapmanjw/minecraft-java-fabric-mcp-server","commit_stats":null,"previous_names":["chapmanjw/minecraft-java-fabric-mcp-server"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/chapmanjw/minecraft-java-fabric-mcp-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chapmanjw%2Fminecraft-java-fabric-mcp-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chapmanjw%2Fminecraft-java-fabric-mcp-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chapmanjw%2Fminecraft-java-fabric-mcp-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chapmanjw%2Fminecraft-java-fabric-mcp-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chapmanjw","download_url":"https://codeload.github.com/chapmanjw/minecraft-java-fabric-mcp-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chapmanjw%2Fminecraft-java-fabric-mcp-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34393302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","claude-code","mcp","mcp-server","minecraft","minecraft-java","minecraft-mod"],"created_at":"2026-06-16T06:03:01.674Z","updated_at":"2026-06-16T06:03:09.740Z","avatar_url":"https://github.com/chapmanjw.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/images/logo.png\" width=\"200\" alt=\"Minecraft Java Fabric MCP Server logo\"\u003e\n\u003c/p\u003e\n\n# Minecraft Java MCP Server (Fabric)\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://modrinth.com/mod/fabric-api-mcp-server\"\u003e\u003cimg src=\"https://img.shields.io/badge/Modrinth-Download-00AF5C?logo=modrinth\u0026logoColor=white\" alt=\"Download on Modrinth\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.curseforge.com/minecraft/mc-mods/fabric-api-mcp-server\"\u003e\u003cimg src=\"https://img.shields.io/badge/CurseForge-Download-F16436?logo=curseforge\u0026logoColor=white\" alt=\"Download on CurseForge\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003e **Install the mod from [Modrinth](https://modrinth.com/mod/fabric-api-mcp-server) or\n\u003e [CurseForge](https://www.curseforge.com/minecraft/mc-mods/fabric-api-mcp-server).** Pick the jar\n\u003e that matches your Minecraft version, drop it in `mods/` alongside Fabric API, and launch. Full\n\u003e walkthrough in [Quick start](#quick-start-single-player-default-config) below.\n\nA [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that runs **inside Minecraft\nJava Edition as a Fabric mod**. It exposes the server-side Minecraft API and the Fabric API as MCP\ntools so an MCP client — Claude Desktop, Cursor, or any agent that speaks MCP — can read and\nmanipulate a live world programmatically.\n\n![A voxel mascot built in a live world over MCP](docs/images/bean.png)\n\n*An agent built this over MCP — authored as a parametric voxel model, then placed\nin a single `block_fill_batch` and verified with `block_render_region` (the\nserver-side render that produced no screenshot dependency — it reads block map\ncolours straight from the world).*\n\n![Ghasticlawd, a voxel Ghast-and-Claude mascot, built in a live world](docs/images/ghasticlawd.png)\n\n*And **Ghasticlawd** — the project's Ghast × Claude mascot — voxelized, placed via\n`block_fill_batch`, and confirmed with `block_render_region`.*\n\n![A layered red-rock canyon inspired by the national parks of the American West, built in a live world over MCP](docs/images/canyon.png)\n\n*And terrain, too — this red-rock canyon, inspired by the national parks of the\nAmerican West, was generated as a hydraulically eroded heightfield,\nrender-checked, then materialized into the world through `block_fill_batch` and\nverified with `block_render_region`.*\n\nThe mod ships separate jars for each supported Minecraft version. The build matrix in v0.2.0 is\n**1.21.11**, **26.1.1**, and **26.1.2**.\n\n### Two endpoints: world + inspection\n\nThe same jar exposes two MCP servers. The **`main`** entrypoint serves the world tools on\n`minecraft-java` (default port 8765) wherever a server runs — dedicated or single-player. The\n**`client`** entrypoint runs inside a real, rendered client and serves an inspection-only surface\non `minecraft-java-client` (default port 8766): `view_capture` returns the player's actual\nfirst-person frame as a PNG, and `sense_*` / `client_status` read client-side perception. It is the\nway an agent SEES the world as a player does — the real rendered pixels the headless server can't\nproduce. Run server-only, client-only (single-player gives you both endpoints from one process), or\na server+client combo. See\n[docs/configuration.md](docs/configuration.md#two-mcp-servers-world--inspection).\n\n## ⚠️ Built on Minecraft and Fabric API internals\n\nThis mod depends on Minecraft's server-side internals via the Fabric API. The API surface evolves\nbetween Minecraft versions and a Minecraft update can change, deprecate, or remove methods this\nmod relies on. Pin your Minecraft installation, your Fabric API jar, and this mod's jar to known-good\nversions and upgrade them together. Treat the stack as **experimental**.\n\n## The sibling projects\n\nThis server pairs with a companion Claude Code plugin, and the whole thing is the Java Edition\ncounterpart of an existing Bedrock stack:\n\n| Repository | Edition | Role |\n| --- | --- | --- |\n| **`minecraft-java-fabric-mcp-server`** (this repo) | Java Edition | The MCP server, packaged as a Fabric mod. Loads inside Minecraft and exposes the Java API as MCP tools. |\n| [`minecraft-java-fabric-claude-plugin`](https://github.com/chapmanjw/minecraft-java-fabric-claude-plugin) | Java Edition | The companion Claude Code plugin. Bundles the MCP connection plus setup and builder skills/agents that drive this server. |\n| [`minecraft-bedrock-mcp-server`](https://github.com/chapmanjw/minecraft-bedrock-mcp-server) | Bedrock Edition | The Node/TypeScript MCP server for the Bedrock Dedicated Server. |\n| [`minecraft-bedrock-mcp-behavior-pack`](https://github.com/chapmanjw/minecraft-bedrock-mcp-behavior-pack) | Bedrock Edition | The companion behavior pack for the Bedrock setup. |\n\nThe plugin is optional — any MCP client (Claude Desktop, Cursor, a hand-configured `claude mcp add`)\ncan talk to this server directly — but on Claude Code it's the fastest path: it wires up the\nconnection and ships the building skills and agents. See\n[Connect an MCP client](#7-connect-an-mcp-client) below.\n\nThe Java and Bedrock stacks are independent — installing one has no effect on the other. They share\na tone and configuration style but expose different (overlapping) tool surfaces because the Java and\nBedrock Script APIs differ substantially.\n\n## How it works\n\n```\nMCP client (Claude Desktop, Cursor, …)\n   │   MCP over Streamable HTTP, localhost-only by default\n   ▼\n[ Fabric mod: HTTP transport ]   ←—— Host / Origin / optional bearer validation\n   │\n   ▼\n[ Protocol layer ] ←—— JSON-RPC 2.0 over Streamable HTTP, tool registry\n   │\n   ▼\n[ Runtime: MinecraftMainThreadExecutor ]   ←—— marshals every world touch onto the server main thread\n   │\n   ▼\n[ Adapter layer ]   ←—— version-stable interface; per-version implementations\n   │\n   ▼\nthe loaded Minecraft world (integrated single-player, or dedicated server)\n```\n\nEvery tool call:\n\n1. Arrives on an HTTP thread of the embedded JDK `HttpServer`.\n2. Passes Host / Origin / (optional) bearer / body-size / rate-limit checks.\n3. Is dispatched by the MCP layer to a tool implementation.\n4. The tool submits any Minecraft API access through the main-thread executor.\n5. The executor completes the work on the next server tick and returns the result.\n6. The HTTP thread serializes the result to JSON and responds.\n\nSee [docs/architecture.md](docs/architecture.md) for the detailed layering rationale.\n\n## Quick start (single-player, default config)\n\nEnd-to-end: a clean machine to \"Claude making it rain chicken jockeys in your village.\" The default\nconfiguration binds to `127.0.0.1:8765`, **no token required**, with strict Host/Origin validation\nthat defends against DNS-rebinding and CSRF.\n\n### 1. Install Java\n\nThe mod runs inside the Minecraft launcher's JVM, which the launcher itself manages — for typical\nsingle-player play you don't need to install Java separately. (You only need a system JDK if you're\n[building from source](#building-from-source).)\n\n### 2. Install Minecraft Java Edition and the launcher\n\nIf you don't already have it, get the Minecraft Launcher from\n[minecraft.net/download](https://www.minecraft.net/download). Launch it once, sign in, and load a\nvanilla world to confirm the install works.\n\n### 3. Install Fabric Loader\n\nDownload the [Fabric Loader installer](https://fabricmc.net/use/installer/) and run it. Pick the\nMinecraft version you want (one of **1.21.11**, **26.1.1**, or **26.1.2** — the versions this mod\nships jars for) and click Install. The installer registers a new \"fabric-loader-…\" profile in the\nMinecraft Launcher and creates a `mods/` folder under your game directory.\n\n### 4. Download the mod and Fabric API\n\n- This mod — get it from your preferred mod host and pick the jar whose suffix matches your\n  Minecraft version (e.g. `minecraft-fabric-mcp-0.2.0+1.21.11.jar`):\n  - **[Modrinth](https://modrinth.com/mod/fabric-api-mcp-server)** (recommended)\n  - **[CurseForge](https://www.curseforge.com/minecraft/mc-mods/fabric-api-mcp-server)**\n  - or the [GitHub Releases page](https://github.com/chapmanjw/minecraft-java-fabric-mcp-server/releases).\n- [Fabric API](https://modrinth.com/mod/fabric-api): pick the version that matches the same MC\n  version.\n\n### 5. Install both jars\n\nDrop both jars into your Minecraft `mods/` directory:\n\n- **Windows**: `%APPDATA%\\.minecraft\\mods\\`\n- **macOS**: `~/Library/Application Support/minecraft/mods/`\n- **Linux**: `~/.minecraft/mods/`\n\n### 6. Launch the Fabric profile\n\nOpen the Minecraft Launcher, select the **fabric-loader-…** profile from the dropdown, click Play,\nand open any world (existing or new). When the world finishes loading, the integrated server starts\nand the MCP listener binds to `http://127.0.0.1:8765/mcp`. Confirm with:\n\n```sh\ncurl http://127.0.0.1:8765/healthz\n# → {\"status\":\"ok\"}\n```\n\n### 7. Connect an MCP client\n\nThe mod speaks MCP over **Streamable HTTP**. Connect from whichever client you use.\n\n**Claude Code (CLI) — via the plugin (recommended):** the companion\n[`minecraft-java-fabric-claude-plugin`](https://github.com/chapmanjw/minecraft-java-fabric-claude-plugin)\nwires up the MCP connection *and* installs the setup and building skills/agents. From a Claude Code\nsession, run:\n\n```\n/plugin marketplace add chapmanjw/minecraft-java-fabric-claude-plugin\n/plugin install minecraft-java@minecraft-java-claude\n```\n\nRestart Claude Code afterward. See the plugin's README for what each skill and agent does.\n\n**Claude Code (CLI) — manual:** if you'd rather connect the raw tools without the plugin, run once\nfrom a terminal —\n\n```sh\nclaude mcp add --transport http minecraft-java http://localhost:8765/mcp\n```\n\n**Claude Desktop:** edit the desktop app's `claude_desktop_config.json` (Settings → Developer → Edit\nConfig) and add:\n\n```json\n{\n  \"mcpServers\": {\n    \"minecraft-java\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-remote\", \"http://localhost:8765/mcp\"]\n    }\n  }\n}\n```\n\nThen restart Claude Desktop. For authenticated / remote setups, see\n[docs/claude-desktop-integration.md](docs/claude-desktop-integration.md) and\n[docs/cursor-integration.md](docs/cursor-integration.md).\n\n### 8. Try it\n\nIn any Claude session with the MCP server connected, ask it natural-language things like:\n\n- _\"Who's online in Minecraft right now?\"_ → `player_list_online`\n- _\"Give me 64 diamonds.\"_ → `player_give_item`\n- _\"Set it to noon and clear the weather.\"_ → `level_set_time`, `level_set_weather`\n- _\"Build me a 5×5×5 box of glass at my feet.\"_ → `block_fill_region`\n- _\"Find a nearby village.\"_ → `entity_query` for `minecraft:villager`\n- _\"Make it rain chicken jockeys over the village.\"_ → 20× `command_execute` with\n  `summon minecraft:chicken \u003cx\u003e \u003cy\u003e \u003cz\u003e {Passengers:[{id:\"minecraft:zombie\",IsBaby:1b}]}` plus\n  `level_set_weather` set to `thunder` for atmosphere.\n\nThat last one is the canonical smoke test. If chickens with baby zombie riders rain down from the\nsky over your village while a thunderstorm rolls in, the whole stack is wired up correctly.\n\nThe full single-player walkthrough (with dedicated-server and LAN variants) lives in\n[docs/setup-singleplayer.md](docs/setup-singleplayer.md). For a dedicated server with bearer auth\nand remote access, see [docs/setup-dedicated-server.md](docs/setup-dedicated-server.md).\n\n## Configuration\n\nAll configuration is JSON-on-disk at `\u003cgame dir\u003e/config/minecraft_fabric_mcp/config.json`, with every field\noverridable by an environment variable (`MCP_\u003cUPPER_SNAKE_FIELD\u003e`). Defaults are baked into the mod —\nthe file only needs to exist if you're overriding something.\n\n| Field | Default | Description |\n| --- | --- | --- |\n| `host` | `127.0.0.1` | Bind address. Non-loopback requires `auth_required=true` and `allow_remote=true`. |\n| `port` | `8765` | Listen port. |\n| `auth_required` | `false` | When true, every request must carry `Authorization: Bearer \u003cbearer_token\u003e`. |\n| `bearer_token` | _(null)_ | When `auth_required=true` and this is null, the mod generates a 32-byte hex token and writes it back into the config file. |\n| `allow_remote` | `false` | Required true when `host` is non-loopback. Belt-and-suspenders so you don't accidentally expose the listener. |\n| `allowed_origins` | `[]` | Browser-style `Origin` allow-list. Default rejects any request carrying an `Origin` header. |\n| `command_timeout_ms` | `15000` | Per-tool wait for main-thread work. |\n| `rate_limit_rpm` | `60` | Per-client requests per minute. |\n| `max_body_bytes` | `16777216` | Max request body. |\n| `event_buffer_size` | `1024` | Default per-subscription ring buffer size for `events_*` tools. |\n| `queue_max` | `256` | Max concurrent async jobs (huge bulk operations). |\n| `log_level` | `info` | SLF4J log level. |\n| `tls_cert_path` / `tls_key_path` | _(null)_ | If both set, the listener serves HTTPS. Both must be set, or both null. |\n| `metrics_enabled` | `false` | Reserved for the Prometheus `/metrics` endpoint (v0.2.0). |\n| `included_categories` | `[]` | Allow-list of domain categories. If non-empty it replaces the default-ON set. One of `blocks`, `structures`, `world`, `entities`, `players`, `items`, `gameplay`, `scripting`, `registries`, `server`. |\n| `excluded_categories` | `[]` | Domain categories to drop. Applied after the allow-list (or the default-ON set). |\n| `max_access` | `write` | Access cap: `read`, `write`, or `admin`. Tools above the cap are dropped. The default `write` keeps admin/destructive tools off until you opt in. |\n| `exclude_write_tools` | `false` | Legacy switch, equivalent to `max_access: read`. When true, only read tools register. |\n\nSee [Tool categories, access levels \u0026 defaults](#tool-categories-access-levels--defaults) for the full model and worked examples.\n\nSee [docs/configuration.md](docs/configuration.md) for the full reference and recipe-style examples.\n\n## Security model summary\n\n- The default bind is `127.0.0.1` with no token. Anything on the same machine can talk to the MCP\n  endpoint; nothing else can.\n- The `Host` header is validated against the bind address — DNS rebinding attacks that resolve an\n  attacker-controlled domain to 127.0.0.1 still get rejected because their `Host` header is wrong.\n- The `Origin` header is validated against `allowed_origins` (empty by default). Browsers always\n  send `Origin` on cross-origin requests; legitimate MCP clients (`mcp-remote`, Cursor) do not.\n- Binding non-loopback requires both `allow_remote: true` and `auth_required: true`. On first run\n  with auth enabled, the mod generates a 32-byte hex bearer token, writes it back to the config\n  file (with POSIX 600 permissions where supported), and logs it once.\n\nFull threat model in [docs/security.md](docs/security.md).\n\n## Tool surface\n\nThe mod registers tools whose names follow the **Minecraft Java API class** convention rather than\nthe Bedrock `mc_\u003cdomain\u003e_\u003caction\u003e` style. Tools group by the class or concept they operate on:\n\n| Domain | Examples |\n| --- | --- |\n| `server_*` | `server_get_status`, `server_set_motd`, `server_save_all_worlds` |\n| `level_*` | `level_set_time`, `level_set_weather`, `level_create_explosion`, `level_get_biome_at` |\n| `block_*` | `block_get_state`, `block_fill_region`, `block_fill_batch`, `block_scan_summary`, `block_render_region` |\n| `block_entity_*` | `block_entity_get_nbt`, `block_entity_set_nbt` |\n| `entity_*` | `entity_summon`, `entity_teleport`, `entity_apply_effect` |\n| `player_*` | `player_list_online`, `player_give_item`, `player_send_title` |\n| `inventory_*` | `inventory_get`, `inventory_set_slot`, `inventory_count_items` |\n| `itemstack_*` | `itemstack_describe`, `itemstack_drop_at` |\n| `command_*` | `command_execute`, `command_execute_as` |\n| `scoreboard_*` | `scoreboard_add_objective`, `scoreboard_set_score`, `scoreboard_add_team` |\n| `data_*` | `data_storage_get`, `data_attachment_set` |\n| `structure_*` | `structure_save_from_world`, `structure_load_to_world` |\n| `datapack_*` | `datapack_enable`, `datapack_disable` |\n| `loot_table_*` / `recipe_*` / `tag_*` / `resource_loader_*` | registry-style read tools |\n| `events_*` | `events_subscribe`, `events_poll`, `events_unsubscribe` |\n\nA full reference with JSON Schemas and per-version annotations lives in [docs/tools.md](docs/tools.md).\n\n## Tool categories, access levels \u0026 defaults\n\nThe 183 tools are filtered along two independent axes so you can narrow the surface by\n**subsystem** and by **risk** at the same time:\n\n- **Domain** — which part of Minecraft the tool touches: blocks, entities, the server itself,\n  and so on. Ten categories, each tied to a tool-name prefix. This is the \"I only care about\n  world-building, hide the scoreboard plumbing\" axis.\n- **Access** — how dangerous the tool is: `read` (inspects state, mutates nothing) \u003c\n  `write` (the normal case: changes a block, an entity, an item) \u003c\n  `admin` (world-wide, server-lifecycle, or destructive — explosions, world-border resizing,\n  difficulty and game-rule changes, datapack toggles, kicking players, registering commands).\n  This is the \"let the agent build, but don't let it reshape the world border or reload\n  resources\" axis.\n\nAn operator filters on both: pick the subsystems you want, then cap the blast radius.\n\n### The ten domain categories\n\n| Category | Domains / prefixes | Purpose | Default | ~Tools |\n| --- | --- | --- | --- | --- |\n| `blocks` | `block_*`, `block_entity_*` | Read, place, fill, clone, scan, render, and erode blocks and block-entity NBT | ON | 20 |\n| `structures` | `structure_*` | Save / load / list named structure templates and their files | ON | 9 |\n| `world` | `level_*`, `worldborder_*` | Time, weather, biomes, dimensions, spawn, features, particles, explosions, the world border | ON | 31 |\n| `entities` | `entity_*` | Summon, query, teleport, tag, damage, effect, and edit-NBT for non-player entities | ON | 17 |\n| `players` | `player_*`, `player_screen_*` | Inspect and act on connected players: inventory, XP, gamemode, messages, kick | opt-in | 16 |\n| `items` | `inventory_*`, `itemstack_*`, `item_modify_*` | Inventory slots, item-stack inspection, container item edits | ON | 9 |\n| `gameplay` | `scoreboard_*`, `bossbar_*`, `advancement_*` | Scoreboards, teams, boss bars, advancements — the game-state logic layer | opt-in | 30 |\n| `scripting` | `command_*`, `function_*`, `schedule_*`, `events_*`, `data_storage_*`, `data_attachment_*` | Commands, datapack functions, scheduled work, event subscriptions, custom data | ON | 21 |\n| `registries` | `recipe_*`, `loot_table_*`, `tag_*`, `content_registry_*`, `resource_loader_*`, `resource_condition_*`, `fluid_storage_*` | Recipe / loot / tag / resource lookups and content-registry edits | opt-in | 21 |\n| `server` | `server_*`, `datapack_*` | Server status, MOTD, world saves, resource reloads, datapack enable/disable | ON | 9 |\n\nCounts are the live 26.1.2 surface; earlier Minecraft targets register fewer (a tool gated on a\nFabric module or MC version drops out before categorization). Run `tools/list` against your build\nfor the exact set.\n\n### What you get with no config\n\nAn empty config (or no config file at all) registers the **lean default set: about 102 of the 183\ntools.** The rule is simple:\n\n- **Default-ON domains:** `blocks`, `structures`, `world`, `entities`, `items`, `scripting`,\n  `server`. The builder-and-operator core.\n- **Opt-in domains:** `players`, `gameplay`, `registries`. Useful, but noise for most world-building\n  sessions — turn them on when you need them.\n- **Default access cap:** `max_access = write`. Read and write tools register; **admin tools do\n  not.**\n\nSo the default surface is every read/write tool in the seven ON domains. The other 81 stay off until\nyou ask for them: 67 in the three opt-in domains (`players` 16 + `gameplay` 30 + `registries` 21)\nand 14 admin tools that sit in ON domains but are suppressed by the `write` cap.\n\nThe 15 admin-tagged tools (all opt-in via `max_access: admin`):\n\n```\nworldborder_set_size        worldborder_add_size         worldborder_set_center\nworldborder_set_warning_blocks  worldborder_set_warning_time\nworldborder_set_damage_amount   worldborder_set_damage_buffer\nlevel_set_difficulty        level_set_game_rule          level_create_explosion\ncommand_register            server_reload_resources\ndatapack_enable             datapack_disable             player_kick\n```\n\nFourteen of those sit in default-ON domains (only `player_kick` is in the opt-in `players` domain),\nso on a default config they are present-but-suppressed by the `write` cap. Raise the cap to `admin`\nand they appear.\n\n### How the filter resolves\n\nFor each supported tool, in order:\n\n1. **Domain allow-list.** If `included_categories` is non-empty, keep the tool only if its category\n   is listed. Otherwise keep it only if its category is default-ON.\n2. **Domain exclude.** Drop the tool if its category is in `excluded_categories`.\n3. **Access cap.** Drop the tool if its access rank exceeds `max_access` (`read` \u003c `write` \u003c\n   `admin`). `exclude_write_tools: true` is the legacy spelling of `max_access: read`.\n\n`included_categories` is an outright replacement for the default-ON set — list it and the ON/opt-in\ndistinction no longer applies; you get exactly the categories you named (still subject to the\nexclude list and the access cap).\n\n### Config recipes\n\n**(a) World-builder — the default.** No config needed. You get the ~102-tool core: build blocks and\nstructures, shape the world, summon and edit entities, move items, run commands and functions, save\nthe server. No admin reshaping, no scoreboard/registry clutter.\n\n```json\n{}\n```\n\n**(b) Read-only monitor.** Inspection only — nothing mutates. Good for an observer agent or a\ndashboard.\n\n```json\n{\n  \"max_access\": \"read\"\n}\n```\n\n(`{\"exclude_write_tools\": true}` does the same thing.)\n\n**(c) Datapack developer.** The default core plus the gameplay and registry surfaces for\nadvancements, loot, recipes, and tags. Still capped at `write`.\n\n```json\n{\n  \"included_categories\": [\n    \"blocks\", \"structures\", \"world\", \"entities\", \"items\",\n    \"scripting\", \"server\", \"gameplay\", \"registries\"\n  ]\n}\n```\n\nThere is no \"default-ON plus these two\" shorthand — the allow-list is all-or-nothing, so when you\nneed an opt-in domain, name the whole set you want (the seven ON domains plus your additions), as\nabove.\n\n**(d) Full operator.** Every category, every access level — the entire 183-tool surface, including\nadmin/destructive tools.\n\n```json\n{\n  \"included_categories\": [\n    \"blocks\", \"structures\", \"world\", \"entities\", \"players\", \"items\",\n    \"gameplay\", \"scripting\", \"registries\", \"server\"\n  ],\n  \"max_access\": \"admin\"\n}\n```\n\nThis is also how you **restore the old behavior.** Before this change an empty config registered all\n183 tools; now an empty config gives the lean ~102. The snippet above brings the full surface back.\n\n### The `command_execute` caveat\n\n`command_execute` (and `command_execute_as`) are tagged **write**, not admin, because they are the\nworkhorse of almost every session. But a command can do anything the server console can —\n`/difficulty`, `/worldborder`, `/gamerule`, `/datapack`, `/stop`. The access cap classifies the MCP\ntool, not the command string it carries, so `max_access: write` is **not** an airtight sandbox: an\nagent with `command_execute` can reach admin-level effects by typing the command directly.\n\nFor a genuinely hardened deployment, drop the command surface entirely — exclude `scripting`, or use\nan allow-list that omits it:\n\n```json\n{\n  \"included_categories\": [\"blocks\", \"structures\", \"world\", \"entities\", \"items\", \"server\"],\n  \"max_access\": \"write\"\n}\n```\n\nThe category and access filters limit what an agent can *easily* do and shrink the tool list it\nreasons over; they are not a substitute for the network-level controls (loopback bind, bearer auth,\nHost/Origin validation) described in [docs/security.md](docs/security.md).\n\n## Version compatibility\n\nThe mod ships **one jar per Minecraft version**. The v0.2.0 build matrix:\n\n| Minecraft | Required JDK | Mappings        | Mod jar suffix |\n| --------- | ------------ | --------------- | -------------- |\n| 1.21.11   | 21           | Mojang official | `+1.21.11`     |\n| 26.1.1    | 25           | unobfuscated    | `+26.1.1`      |\n| 26.1.2    | 25           | unobfuscated    | `+26.1.2`      |\n\n`./gradlew chiseledBuild` produces all three jars in one invocation. Each Stonecutter version\nsubproject has its own `versions/\u003cver\u003e/build.gradle.kts` because the Fabric Loom plugin ID\ndiffers across Minecraft versions (legacy `fabric-loom` for 1.21.x; `net.fabricmc.fabric-loom`\nLoomNoRemap variant for 26.1+).\n\nEach tool declares the Minecraft and Fabric API constraints it needs via the `@McpTool`\nannotation, and the registration layer filters tools at startup. A tool that requires\n`fabric-biome-api-v1` only registers when that module is loaded; a tool restricted to MC 26.1+\nwon't appear in the tool list on 1.21.11. Run `tools/list` against your specific build to see what's\navailable.\n\nFull detail in [docs/version-compatibility.md](docs/version-compatibility.md).\n\n## Claude Desktop integration\n\nThe mod speaks MCP over **Streamable HTTP**. Claude Desktop connects via the\n[`mcp-remote`](https://www.npmjs.com/package/mcp-remote) adapter, which bridges a stdio entry to\nthe remote HTTP endpoint.\n\n```json\n{\n  \"mcpServers\": {\n    \"minecraft-java\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-remote\", \"http://localhost:8765/mcp\"]\n    }\n  }\n}\n```\n\nThat's the default-config form (localhost, no token). For the authenticated form and the path to\nClaude Desktop's config file on macOS / Windows, see\n[docs/claude-desktop-integration.md](docs/claude-desktop-integration.md). For Cursor,\nsee [docs/cursor-integration.md](docs/cursor-integration.md).\n\n## Endpoints\n\n| Route | Method(s) | Purpose |\n| --- | --- | --- |\n| `/mcp` | `POST` | Single JSON-RPC request → JSON-RPC response |\n| `/mcp` | `GET` | Server-to-client SSE stream (no spontaneous messages in v0.2.0) |\n| `/mcp` | `DELETE` | Close session (no-op in the stateless v0.2.0 dispatcher) |\n| `/mcp` | `OPTIONS` | CORS preflight |\n| `/healthz` | `GET` | Liveness probe (no auth) |\n\n## Building from source\n\n```sh\n# Build every version in the matrix (produces 3 jars)\n./gradlew chiseledBuild\n\n# Build a single version\n./gradlew :1.21.11:build\n./gradlew :26.1.2:build\n\n# Switch the Stonecutter active subproject (used as the default for plain `./gradlew build`)\n./gradlew \"Reset active project\" -Pversion=1.21.11\n./gradlew build\n```\n\nOutput jars land in `versions/\u003cmcver\u003e/build/libs/minecraft-fabric-mcp-\u003cmodver\u003e+\u003cmcver\u003e.jar`.\n\n**Requirements**: Gradle 9.4.0+ (the wrapper bundles it). The build needs both **JDK 21**\n(toolchain target for 1.21.x) and **JDK 25** (toolchain target for 26.1.x; the Gradle daemon\nmust also run on JDK 25 because Loom enforces it at configure time). Set them via standard\nenv vars: `JDK_21` and `JDK_25`, or `JAVA_HOME_21_X64` and `JAVA_HOME_25_X64`. Gradle's\ntoolchain locator picks each one up automatically on CI (`actions/setup-java` exposes them)\nand on developer machines (Corretto's Windows installer installs both into\n`C:\\Program Files\\Amazon Corretto\\`).\n\n## Stability and versioning\n\nThis mod is a stable foundation for separately built MCP clients and agents. Its **public\ncontract**, governed by semantic versioning, is:\n\n- tool **names**,\n- tool **input schemas**,\n- tool **output** (the `result` field of the response envelope),\n- the MCP wire protocol revision (`2025-06-18` in v0.2.0),\n- the configuration schema and environment variable names.\n\nInternal layering (transport, runtime, adapter implementations) is not part of the contract and\nmay change at any time.\n\nThe **underlying Minecraft + Fabric API surface is not part of our contract** — a Minecraft update\ncan still break behavior even when our public contract is unchanged. Pin versions; upgrade them in\nlock-step.\n\n## Development\n\n```sh\n./gradlew spotlessApply       # auto-format\n./gradlew check               # spotless, checkstyle, tests\n./gradlew chiseledTest        # unit tests across every version\n./gradlew \"Reset active project\" -Pversion=26.1.2\n./gradlew runServer           # launches the Fabric dev server with the mod loaded\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow, code-style notes, and PR\nchecklist.\n\n## Security disclosures\n\nSee [SECURITY.md](SECURITY.md). Use GitHub Security Advisories — don't open a public issue.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Star History\n\n\u003ca href=\"https://www.star-history.com/?repos=chapmanjw%2Fminecraft-java-fabric-mcp-server\u0026type=date\u0026legend=top-left\"\u003e\n \u003cpicture\u003e\n   \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/chart?repos=chapmanjw/minecraft-java-fabric-mcp-server\u0026type=date\u0026theme=dark\u0026legend=top-left\" /\u003e\n   \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/chart?repos=chapmanjw/minecraft-java-fabric-mcp-server\u0026type=date\u0026legend=top-left\" /\u003e\n   \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/chart?repos=chapmanjw/minecraft-java-fabric-mcp-server\u0026type=date\u0026legend=top-left\" /\u003e\n \u003c/picture\u003e\n\u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchapmanjw%2Fminecraft-java-fabric-mcp-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchapmanjw%2Fminecraft-java-fabric-mcp-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchapmanjw%2Fminecraft-java-fabric-mcp-server/lists"}