Skip to main content
Glama
Mming-Lab
by Mming-Lab

blocks

Perform block operations in Minecraft Bedrock, including placement, area filling, terrain queries, and surface detection, using coordinates and block IDs for precise world manipulation.

Instructions

Block operations: placement, area filling, terrain queries, single blocks, large areas, surface detection

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesBlock operation to perform
block_idNoBlock ID (e.g., minecraft:stone, minecraft:dirt, minecraft:air)
modeNoBlock placement/fill mode
stepsNoArray of block actions for sequence. Each step should have "type" field and relevant parameters.
xNoX coordinate
x2NoSecond X coordinate for area operations
yNoY coordinate
y2NoSecond Y coordinate for area operations
zNoZ coordinate
z2NoSecond Z coordinate for area operations

Implementation Reference

  • The main execute method of BlocksTool that handles all 'blocks' tool actions: set_block, fill_area, get_top_solid_block, query_block_data, etc. This is the core handler logic.
    async execute(args: {
        action: string;
        x?: number;
        y?: number;
        z?: number;
        x2?: number;
        y2?: number;
        z2?: number;
        block_id?: string;
        mode?: string;
        steps?: SequenceStep[];
    }): Promise<ToolCallResult> {
        if (!this.world) {
            return { success: false, message: 'World not available. Ensure Minecraft is connected.' };
        }
    
        try {
            const { action } = args;
            let result: any;
            let message: string;
    
            switch (action) {
                case 'set_block':
                    if (args.x === undefined || args.y === undefined || args.z === undefined || !args.block_id) {
                        return { success: false, message: 'Coordinates (x,y,z) and block_id required for set_block' };
                    }
                    
                    if (!this.validateCoordinates(args.x, args.y, args.z)) {
                        return { success: false, message: 'Invalid coordinates. Y must be between -64 and 320.' };
                    }
    
                    const setOptions = args.mode && args.mode !== 'replace' ? 
                        { mode: args.mode as SetBlockMode } : undefined;
                    
                    await this.world.setBlock(
                        { x: args.x, y: args.y, z: args.z }, 
                        this.normalizeBlockId(args.block_id), 
                        setOptions
                    );
                    
                    message = `Block ${args.block_id} set at (${args.x}, ${args.y}, ${args.z})`;
                    if (args.mode && args.mode !== 'replace') {
                        message += ` with mode: ${args.mode}`;
                    }
                    break;
    
                case 'fill_area':
                    if (args.x === undefined || args.y === undefined || args.z === undefined ||
                        args.x2 === undefined || args.y2 === undefined || args.z2 === undefined || 
                        !args.block_id) {
                        return { success: false, message: 'All coordinates (x,y,z,x2,y2,z2) and block_id required for fill_area' };
                    }
    
                    if (!this.validateCoordinates(args.x, args.y, args.z) || 
                        !this.validateCoordinates(args.x2, args.y2, args.z2)) {
                        return { success: false, message: 'Invalid coordinates. Y values must be between -64 and 320.' };
                    }
    
                    // Calculate volume for safety check
                    const volume = Math.abs(args.x2 - args.x + 1) * 
                                 Math.abs(args.y2 - args.y + 1) * 
                                 Math.abs(args.z2 - args.z + 1);
                    
                    if (volume > 32768) {
                        return { success: false, message: `Area too large (${volume} blocks). Maximum is 32768 blocks.` };
                    }
    
                    let fillOptions: any = undefined;
                    if (args.mode && args.mode !== 'replace') {
                        fillOptions = { mode: args.mode as FillBlocksMode };
                    }
    
                    result = await this.world.fillBlocks(
                        { x: args.x, y: args.y, z: args.z },
                        { x: args.x2, y: args.y2, z: args.z2 },
                        this.normalizeBlockId(args.block_id),
                        fillOptions
                    );
    
                    message = `Filled ${result} blocks with ${args.block_id} from (${args.x},${args.y},${args.z}) to (${args.x2},${args.y2},${args.z2})`;
                    if (args.mode && args.mode !== 'replace') {
                        message += ` with mode: ${args.mode}`;
                    }
                    break;
    
                case 'get_top_solid_block':
                    const location = (args.x !== undefined && args.z !== undefined) ? 
                        { x: args.x, y: args.y || 320, z: args.z } : undefined;
                    
                    result = await this.world.getTopSolidBlock(location);
                    
                    if (location) {
                        message = `Top solid block found at (${args.x}, ${result?.y || 'none'}, ${args.z})`;
                    } else {
                        message = 'Top solid block found at current location';
                    }
                    break;
    
                case 'query_block_data':
                    result = await this.world.queryData('block');
                    message = 'Block data retrieved';
                    break;
    
                case 'query_item_data':
                    result = await this.world.queryData('item');
                    message = 'Item data retrieved';
                    break;
    
                case 'query_mob_data':
                    result = await this.world.queryData('mob');
                    message = 'Mob data retrieved';
                    break;
    
                case 'sequence':
                    if (!args.steps) {
                        return this.createErrorResponse('steps array is required for sequence action');
                    }
                    return await this.executeSequence(args.steps as SequenceStep[]);
    
                default:
                    return { success: false, message: `Unknown action: ${action}` };
            }
    
            return {
                success: true,
                message: message,
                data: { action, result, volume: result, timestamp: Date.now() }
            };
    
        } catch (error) {
            return {
                success: false,
                message: `Block operation error: ${error instanceof Error ? error.message : String(error)}`
            };
        }
    }
  • Input schema definition for the 'blocks' tool, defining parameters like action, coordinates, block_id, mode, etc.
    readonly inputSchema: InputSchema = {
        type: 'object',
        properties: {
            action: {
                type: 'string',
                description: 'Block operation to perform',
                enum: [
                    'set_block', 'fill_area', 'get_top_solid_block', 'query_block_data',
                    'query_item_data', 'query_mob_data', 'sequence'
                ]
            },
            x: { type: 'number', description: 'X coordinate' },
            y: { type: 'number', description: 'Y coordinate' },
            z: { type: 'number', description: 'Z coordinate' },
            x2: { type: 'number', description: 'Second X coordinate for area operations' },
            y2: { type: 'number', description: 'Second Y coordinate for area operations' },
            z2: { type: 'number', description: 'Second Z coordinate for area operations' },
            block_id: {
                type: 'string',
                description: 'Block ID (e.g., minecraft:stone, minecraft:dirt, minecraft:air)'
            },
            mode: {
                type: 'string',
                description: 'Block placement/fill mode',
                enum: ['replace', 'keep', 'destroy', 'hollow', 'outline']
            },
            steps: {
                type: 'array',
                description: 'Array of block actions for sequence. Each step should have "type" field and relevant parameters.'
            }
        },
        required: ['action']
    };
  • src/server.ts:348-372 (registration)
    Instantiation of BlocksTool in the tools array during server initialization.
    this.tools = [
      // Socket-BE Core API ツール(推奨 - シンプルでAI使いやすい)
      new AgentTool(),
      new WorldTool(),
      new PlayerTool(),
      new BlocksTool(),
      new SystemTool(),
      new CameraTool(),
      new SequenceTool(),
      new MinecraftWikiTool(),
    
      // Advanced Building ツール(高レベル建築機能)
      new BuildCubeTool(), // ✅ 完全動作
      new BuildLineTool(), // ✅ 完全動作
      new BuildSphereTool(), // ✅ 完全動作
      new BuildCylinderTool(), // ✅ 修正済み
      new BuildParaboloidTool(), // ✅ 基本動作
      new BuildHyperboloidTool(), // ✅ 基本動作
      new BuildRotateTool(), // ✅ 基本動作
      new BuildTransformTool(), // ✅ 基本動作
      new BuildTorusTool(), // ✅ 修正完了
      new BuildHelixTool(), // ✅ 修正完了
      new BuildEllipsoidTool(), // ✅ 修正完了
      new BuildBezierTool(), // ✅ 新規追加(可変制御点ベジェ曲線)
    ];
  • src/server.ts:494-573 (registration)
    Registration loop where BlocksTool (tool.name='blocks') is registered to the MCP server using registerTool.
    this.tools.forEach((tool) => {
      // inputSchemaをZod形式に変換(SchemaToZodConverterを使用)
      const zodSchema = schemaConverter.convert(tool.inputSchema);
    
      // ツールを登録
      this.mcpServer.registerTool(
        tool.name,
        {
          title: tool.name,
          description: tool.description,
          inputSchema: zodSchema,
        },
        async (args: any) => {
          try {
            const result = await tool.execute(args);
    
            let responseText: string;
    
            if (result.success) {
              // 建築ツールの場合は最適化
              if (tool.name.startsWith('build_')) {
                const optimized = optimizeBuildResult(result);
                responseText = `✅ ${optimized.message}`;
                if (optimized.summary) {
                  responseText += `\n\n📊 Summary:\n${JSON.stringify(optimized.summary, null, 2)}`;
                }
              } else {
                // 通常ツールの場合
                responseText = result.message || `Tool ${tool.name} executed successfully`;
                if (result.data) {
                  // データサイズチェック
                  const dataStr = JSON.stringify(result.data, null, 2);
                  const sizeWarning = checkResponseSize(dataStr);
    
                  if (sizeWarning) {
                    // 大きすぎる場合はデータタイプのみ表示
                    responseText += `\n\n${sizeWarning}`;
                    responseText += `\nData type: ${Array.isArray(result.data) ? `Array[${result.data.length}]` : typeof result.data}`;
                  } else {
                    responseText += `\n\nData: ${dataStr}`;
                  }
                }
              }
            } else {
              // エラーメッセージにヒントを追加
              const errorMsg = result.message || "Tool execution failed";
              const enrichedError = enrichErrorWithHints(errorMsg);
              responseText = `❌ ${enrichedError}`;
              if (result.data) {
                responseText += `\n\nDetails:\n${JSON.stringify(result.data, null, 2)}`;
              }
            }
    
            return {
              content: [
                {
                  type: "text",
                  text: responseText,
                },
              ],
            };
          } catch (error) {
            const errorMsg =
              error instanceof Error ? error.message : String(error);
            const errorStack = error instanceof Error ? error.stack : undefined;
    
            const exceptionMessage = `Tool execution failed with exception: ${errorMsg}${errorStack ? `\n\nStack trace:\n${errorStack}` : ""}`;
    
            return {
              content: [
                {
                  type: "text",
                  text: `❌ ${exceptionMessage}`,
                },
              ],
            };
          }
        }
      );
    });
  • Helper method for executing sequence steps specific to blocks tool.
        protected async executeSequenceStep(step: SequenceStep, index: number): Promise<ToolCallResult> {
            // wait ステップは基底クラスで処理される
            if (step.type === 'wait') {
                return await super.executeSequenceStep(step, index);
            }
    
            // ブロック特有のステップを実行
            const blocksArgs = { action: step.type, ...step };
            return await this.execute(blocksArgs);
        }
    }
Install Server

Other Tools

Related Tools

  • @Mming-Lab/minecraft-bedrock-mcp-server
  • @Mming-Lab/minecraft-bedrock-mcp-server
  • @Mming-Lab/minecraft-bedrock-mcp-server
  • @Mming-Lab/minecraft-bedrock-mcp-server
  • @Mming-Lab/minecraft-bedrock-mcp-server
  • @nacal/mcp-minecraft-remote

Latest Blog Posts

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/Mming-Lab/minecraft-bedrock-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server