place-block
Place a block at specific coordinates (x, y, z) in Minecraft using the MCP Server, with optional face direction for precise placement.
Instructions
Place a block at the specified position
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| faceDirection | No | Direction to place against (default: 'down') | |
| x | Yes | X coordinate | |
| y | Yes | Y coordinate | |
| z | Yes | Z coordinate |
Implementation Reference
- src/bot.ts:350-402 (handler)The handler function that implements the 'place-block' tool logic. It checks if the position is empty, defines possible adjacent faces for placement, prioritizes the specified faceDirection if provided, moves closer if needed to see the reference block, looks at the target position, and attempts to place the block using bot.placeBlock on each possible face until successful.async ({ x, y, z, faceDirection = 'down' }: { x: number, y: number, z: number, faceDirection?: FaceDirection }): Promise<McpResponse> => { try { const placePos = new Vec3(x, y, z); const blockAtPos = bot.blockAt(placePos); if (blockAtPos && blockAtPos.name !== 'air') { return createResponse(`There's already a block (${blockAtPos.name}) at (${x}, ${y}, ${z})`); } const possibleFaces: FaceOption[] = [ { direction: 'down', vector: new Vec3(0, -1, 0) }, { direction: 'north', vector: new Vec3(0, 0, -1) }, { direction: 'south', vector: new Vec3(0, 0, 1) }, { direction: 'east', vector: new Vec3(1, 0, 0) }, { direction: 'west', vector: new Vec3(-1, 0, 0) }, { direction: 'up', vector: new Vec3(0, 1, 0) } ]; // Prioritize the requested face direction if (faceDirection !== 'down') { const specificFace = possibleFaces.find(face => face.direction === faceDirection); if (specificFace) { possibleFaces.unshift(possibleFaces.splice(possibleFaces.indexOf(specificFace), 1)[0]); } } // Try each potential face for placing for (const face of possibleFaces) { const referencePos = placePos.plus(face.vector); const referenceBlock = bot.blockAt(referencePos); if (referenceBlock && referenceBlock.name !== 'air') { if (!bot.canSeeBlock(referenceBlock)) { // Try to move closer to see the block const goal = new goals.GoalNear(referencePos.x, referencePos.y, referencePos.z, 2); await bot.pathfinder.goto(goal); } await bot.lookAt(placePos, true); try { await bot.placeBlock(referenceBlock, face.vector.scaled(-1)); return createResponse(`Placed block at (${x}, ${y}, ${z}) using ${face.direction} face`); } catch (placeError) { console.error(`Failed to place using ${face.direction} face: ${(placeError as Error).message}`); continue; } } } return createResponse(`Failed to place block at (${x}, ${y}, ${z}): No suitable reference block found`); } catch (error) { return createErrorResponse(error as Error); }
- src/bot.ts:344-348 (schema)Zod input schema defining parameters for the 'place-block' tool: required x, y, z coordinates (numbers), and optional faceDirection enum.{ x: z.number().describe("X coordinate"), y: z.number().describe("Y coordinate"), z: z.number().describe("Z coordinate"), faceDirection: z.enum(['up', 'down', 'north', 'south', 'east', 'west']).optional().describe("Direction to place against (default: 'down')")
- src/bot.ts:341-404 (registration)Registration of the 'place-block' tool using server.tool() within registerBlockTools function, including description, inline schema, and handler.server.tool( "place-block", "Place a block at the specified position", { x: z.number().describe("X coordinate"), y: z.number().describe("Y coordinate"), z: z.number().describe("Z coordinate"), faceDirection: z.enum(['up', 'down', 'north', 'south', 'east', 'west']).optional().describe("Direction to place against (default: 'down')") }, async ({ x, y, z, faceDirection = 'down' }: { x: number, y: number, z: number, faceDirection?: FaceDirection }): Promise<McpResponse> => { try { const placePos = new Vec3(x, y, z); const blockAtPos = bot.blockAt(placePos); if (blockAtPos && blockAtPos.name !== 'air') { return createResponse(`There's already a block (${blockAtPos.name}) at (${x}, ${y}, ${z})`); } const possibleFaces: FaceOption[] = [ { direction: 'down', vector: new Vec3(0, -1, 0) }, { direction: 'north', vector: new Vec3(0, 0, -1) }, { direction: 'south', vector: new Vec3(0, 0, 1) }, { direction: 'east', vector: new Vec3(1, 0, 0) }, { direction: 'west', vector: new Vec3(-1, 0, 0) }, { direction: 'up', vector: new Vec3(0, 1, 0) } ]; // Prioritize the requested face direction if (faceDirection !== 'down') { const specificFace = possibleFaces.find(face => face.direction === faceDirection); if (specificFace) { possibleFaces.unshift(possibleFaces.splice(possibleFaces.indexOf(specificFace), 1)[0]); } } // Try each potential face for placing for (const face of possibleFaces) { const referencePos = placePos.plus(face.vector); const referenceBlock = bot.blockAt(referencePos); if (referenceBlock && referenceBlock.name !== 'air') { if (!bot.canSeeBlock(referenceBlock)) { // Try to move closer to see the block const goal = new goals.GoalNear(referencePos.x, referencePos.y, referencePos.z, 2); await bot.pathfinder.goto(goal); } await bot.lookAt(placePos, true); try { await bot.placeBlock(referenceBlock, face.vector.scaled(-1)); return createResponse(`Placed block at (${x}, ${y}, ${z}) using ${face.direction} face`); } catch (placeError) { console.error(`Failed to place using ${face.direction} face: ${(placeError as Error).message}`); continue; } } } return createResponse(`Failed to place block at (${x}, ${y}, ${z}): No suitable reference block found`); } catch (error) { return createErrorResponse(error as Error); } } );