Files

6.8 KiB

Shacraft MCP

shacraft-mcp is a separate process implementing MCP over stdio and JSON-RPC 2.0. It calls the running server's authorized Control API rather than opening world files directly. The server stores and validates revisions, limits, and operation durability.

cargo run -p shacraft-mcp -- --server http://127.0.0.1:4000 --data data

By default, the token is read from data/control.token. The --token-file /absolute/path/control.token argument overrides this path. The token is read when a control call is made, so MCP can start before the server. Standard output contains only JSON-RPC messages, one per line; diagnostics and CLI errors go to stderr. Do not launch it through a shell wrapper that prints unrelated text to stdout.

Example MCP client configuration (replace the paths with your own absolute paths):

{
  "mcpServers": {
    "shacraft": {
      "command": "/absolute/path/shacraft-core/target/release/shacraft-mcp",
      "args": ["--server", "http://127.0.0.1:4000", "--data", "/absolute/path/shacraft-data"]
    }
  }
}

Protocol

Supported versions are 2025-11-25, 2025-06-18, 2025-03-26, and 2024-11-05. The server returns the requested version if supported, or its newest supported version otherwise. The client starts with initialize, followed by notifications/initialized. Before that, only initialize and ping are available. Notifications receive no response; unknown request methods receive a JSON-RPC error. Argument and execution errors for known tools are returned in result.content with isError: true.

Implemented methods are tools/list, tools/call, resources/list, resources/read, resources/templates/list, prompts/list, prompts/get, and ping. Lists are small and returned in full. Subscriptions, asynchronous tasks, and list-change notifications are not advertised. Execution is sequential; a cancellation notification does not interrupt an HTTP request already in progress. The network timeout is 20 seconds, with a 3-second connection timeout.

Request lines and HTTP responses are limited to 8 MiB. An oversized input line is discarded through its terminating newline, after which stream parsing resumes. HTTP redirects are disabled so the bearer token is not forwarded to a redirected address.

Tools and workflow

  • world_list, world_create, world_read: inspect worlds and create an empty world or an instance of a pinned template.
  • catalog_search: exact states, runtime IDs, shapes, and implementation coverage information.
  • world_edit, world_undo, world_reset: atomic edits, conservative undo of the latest operation, and reset to the base.
  • build_plan, build_commit: preview a bounded structure made of box/line/cylinder primitives, then commit the plan.
  • entity_list, entity_spawn, entity_update, entity_delete: persistent world entities and their properties.
  • arena_configure, arena_start: persistent Spleef rules (timing, minimum players, elimination height, spawn points, floor material) and match start. Rules cannot change while a round is in progress; the floor material determines which blocks may be broken but does not rebuild the map.
  • metrics: measured RSS and separate cache payload estimates.
  • camera_capture: an isometric world image returned as an MCP image plus metadata. This is a server diagnostic projection, not a frame from the player's WebGL camera.

Complete JSON Schemas are available through tools/list. Tool names correspond to Control API names with the first _ replaced by a dot, for example world_editworld.edit.

To build, first read the revision and site through world_list/world_read, find exact materials through catalog_search, create a build_plan, inspect its bounds and volume, then call build_commit with a unique operation_id within the user's authorized scope. After committing, verify the result with camera_capture. On conflict, reread the world and create a new plan. Reuse an operation key only to retry an identical request.

Undo requires the current revision and the original edit's target_operation. Later changes and reset may make undo unavailable; the tool must not silently overwrite them.

Resources and prompt

The resources shacraft://server/status, shacraft://catalog/blocks, shacraft://catalog/entities, and shacraft://packages read public server information. The block resource provides an initial bounded page; use tool search and pagination to access the full catalog.

The construct prompt accepts world and request strings and describes the inspection, planning, editing, and visual verification sequence. It does not expand the user's authorization.

Run checks with cargo test -p shacraft-mcp. Unit tests cover lifecycle transitions, version negotiation, notifications receiving no responses, argument and token errors, invalid JSON-RPC IDs, recovery after an oversized line, and build-operation schemas. Additional end-to-end tests use a real server.

Protocol references: the official lifecycle, stdio transport, and tools specifications.

Verification with the real MCP SDK

After starting a separate test server:

node crates/shacraft-mcp/tests/sdk-smoke.mjs --data /absolute/path/test-server-data

The script uses @modelcontextprotocol/sdk (verified with 1.30.0), negotiates the protocol, reads every resource, invokes the prompt, exercises edit/replay/conflict/undo and plan/commit, receives a PNG, and checks entity CRUD and reset. It creates a separate world prefixed with mcp_sdk_. Set SHACRAFT_MCP_SDK to the installed SDK path; the local environment also supports a sibling minecraft-builder-mcp/bridge/node_modules directory. This independently verifies the protocol; the MCP executable does not depend on Minecraft Builder.

For a reproducible check with an automatically started separate server:

node scripts/check_mcp.mjs --binary target/release/shacraft-server --mcp-binary target/release/shacraft-mcp --port 4002 --output artifacts/mcp-sdk.json

The wrapper creates a temporary data directory, uses the real SDK, and stops the test server. It does not affect the working server on port 4000. --sdk or SHACRAFT_MCP_SDK specifies the path to an already installed SDK; results are written to a JSON file, including the error if verification fails.

The related end-to-end test, scripts/check_server.mjs, checks HTTP/WebSocket clients, actions, world instances, a complete match, and recovery after a real SIGKILL: acknowledged blocks, entities, and arena rules must survive restarting with the same data directory. Temporary test data is retained for investigation.