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);
        }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but offers minimal behavioral insight. It mentions 'placement, area filling, terrain queries' which implies both read and write operations, but doesn't disclose permissions needed, rate limits, destructive effects, or response formats. For a tool with 10 parameters and no annotations, this is inadequate disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise (6 phrases separated by commas) with zero wasted words. It's front-loaded with key concepts. However, the comma-separated list format lacks grammatical structure and reads more like tags than a coherent description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 10 parameters, no annotations, and no output schema, the description is insufficient. It doesn't explain the relationship between parameters, doesn't clarify that 'action' determines which other parameters are relevant, and provides no information about return values or error conditions. The description fails to compensate for the lack of structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds no specific parameter information beyond what's in the schema. It mentions 'placement, area filling, terrain queries' which loosely maps to some action values but doesn't explain parameter relationships or usage patterns. Baseline 3 is appropriate when schema does all the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description lists multiple operations (placement, area filling, terrain queries) but doesn't specify a single clear purpose or verb. It mentions 'block operations' which is tautological with the tool name 'blocks'. While it gives a sense of scope, it lacks a specific action statement that distinguishes it from sibling building tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus the many sibling building tools (build_cube, build_sphere, etc.) is provided. The description mentions 'single blocks, large areas' which implies some scope but doesn't clarify when to choose this over specialized building tools. No explicit alternatives or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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