place-block
Place blocks at specific coordinates in Minecraft using X, Y, Z positions and face directions to build structures or modify terrain.
Instructions
Place a block at the specified position
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X coordinate | |
| y | Yes | Y coordinate | |
| z | Yes | Z coordinate | |
| faceDirection | No | Direction to place against (default: 'down') |
Implementation Reference
- src/bot.ts:350-403 (handler)The async handler function that implements the place-block tool logic: checks if position is free, defines possible faces for placement, prioritizes requested faceDirection, iterates over faces to find reference block, moves closer if can't see, looks at position, and attempts bot.placeBlock.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-349 (schema)Zod input schema for the place-block tool defining required numeric coordinates x, y, z 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 via server.tool() call within registerBlockTools function, including name, description, schema, and inline 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); } } );