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

sequence

Chain actions from multiple tools to automate complex tasks in Minecraft Bedrock, such as teleporting players, building structures, and capturing media, with precise timing and error handling.

Instructions

Execute CROSS-TOOL SEQUENCES: Chain actions from multiple tools together with timing control. Perfect for complex automation like "teleport player → wait 2s → build cube → take screenshot → say message". Supports all tools: player(teleport/move/say), agent(move/turn), camera(shot/video), blocks(setblock/fill), world(time/weather), building(cube/sphere/line). Use wait_time for delays, on_error for handling failures.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
descriptionNoOptional description of what this sequence does
stepsYesArray of sequence steps. Each step needs: "tool" (player/agent/camera/blocks/world/building), "type" (action like teleport/move/shot/setblock/build), and tool-specific params. Optional: "wait_time" (seconds to wait after), "on_error" (continue/stop/retry), "retry_count" (max retries). Example: [{tool:"player",type:"teleport",x:0,y:70,z:0,wait_time:2},{tool:"blocks",type:"setblock",x:0,y:70,z:0,block:"diamond_block"}]

Implementation Reference

  • Main handler function for the 'sequence' tool. Orchestrates execution of multiple tool steps in sequence, handling timing (wait_time), error handling (on_error: continue/stop/retry), retries, logging, and aggregation of results.
    async execute(args: {
        steps: GlobalSequenceStep[];
        description?: string;
    }): Promise<ToolCallResult> {
        const { steps, description } = args;
        
        if (!steps || !Array.isArray(steps) || steps.length === 0) {
            return this.createErrorResponse('steps array is required for sequence execution');
        }
    
        try {
            let totalDuration = 0;
            const results: string[] = [];
            const sequenceId = Date.now().toString(36);
            
            if (description) {
                results.push(`Sequence: ${description}`);
            }
            
            for (let i = 0; i < steps.length; i++) {
                const step = steps[i];
                // デバッグログは標準エラー出力に送信(MCPモードでは非表示)
                if (process.stdin.isTTY !== false) {
                    console.error(`[Sequence ${sequenceId}] Executing step ${i + 1}/${steps.length}: ${step.tool}.${step.type}`);
                }
                
                const stepResult = await this.executeGlobalSequenceStep(step, i);
                
                if (!stepResult.success) {
                    const errorAction = step.on_error || 'stop';
                    
                    switch (errorAction) {
                        case 'continue':
                            results.push(`Step ${i + 1} (${step.tool}.${step.type}): Failed but continuing - ${stepResult.message}`);
                            if (process.stdin.isTTY !== false) {
                                console.error(`[Sequence ${sequenceId}] Step ${i + 1} failed but continuing`);
                            }
                            break;
                        case 'retry':
                            const retryResult = await this.retryGlobalSequenceStep(step, i);
                            if (!retryResult.success) {
                                return this.createErrorResponse(`Step ${i + 1} (${step.tool}.${step.type}) failed after retries: ${retryResult.message}`);
                            }
                            results.push(`Step ${i + 1} (${step.tool}.${step.type}): Succeeded after retry - ${retryResult.message}`);
                            if (process.stdin.isTTY !== false) {
                                console.error(`[Sequence ${sequenceId}] Step ${i + 1} succeeded after retry`);
                            }
                            break;
                        case 'stop':
                        default:
                            return this.createErrorResponse(`Step ${i + 1} (${step.tool}.${step.type}) failed: ${stepResult.message}`);
                    }
                } else {
                    results.push(`Step ${i + 1} (${step.tool}.${step.type}): ${stepResult.message || 'Executed'}`);
                    if (process.stdin.isTTY !== false) {
                        console.error(`[Sequence ${sequenceId}] Step ${i + 1} completed successfully`);
                    }
                }
                
                // 待ち時間処理
                const waitTime = step.wait_time || 0;
                if (waitTime > 0 && i < steps.length - 1) {
                    if (process.stdin.isTTY !== false) {
                        console.error(`[Sequence ${sequenceId}] Waiting ${waitTime}s before next step`);
                    }
                    await this.delay(waitTime);
                    totalDuration += waitTime;
                }
            }
            
            if (process.stdin.isTTY !== false) {
                console.error(`[Sequence ${sequenceId}] Completed all ${steps.length} steps`);
            }
            
            return this.createSuccessResponse(
                `Cross-tool sequence completed: ${steps.length} steps executed over ${totalDuration.toFixed(1)}s\n` +
                results.join('\n')
            );
            
        } catch (error) {
            return this.createErrorResponse(`Cross-tool sequence execution failed: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
  • Input schema defining the structure for sequence execution: required 'steps' array of objects with 'tool', 'type', optional 'wait_time', 'on_error', 'retry_count', and optional 'description'.
    readonly inputSchema: InputSchema = {
        type: 'object',
        properties: {
            steps: {
                type: 'array',
                description: 'Array of sequence steps. Each step needs: "tool" (player/agent/camera/blocks/world/building), "type" (action like teleport/move/shot/setblock/build), and tool-specific params. Optional: "wait_time" (seconds to wait after), "on_error" (continue/stop/retry), "retry_count" (max retries). Example: [{tool:"player",type:"teleport",x:0,y:70,z:0,wait_time:2},{tool:"blocks",type:"setblock",x:0,y:70,z:0,block:"diamond_block"}]',
                items: {
                    type: 'object',
                    description: 'Individual cross-tool sequence step',
                    properties: {
                        tool: {
                            type: 'string',
                            description: 'Tool name: player, agent, camera, blocks, world, or any building tool (build_cube, build_sphere, etc.)'
                        },
                        type: {
                            type: 'string', 
                            description: 'Action type: depends on tool - player(teleport/move/say), agent(move/turn), camera(shot/video), blocks(setblock/fill), world(time/weather/gamemode), building(build)'
                        },
                        wait_time: {
                            type: 'number',
                            description: 'Seconds to wait after this step (default: 0)',
                            minimum: 0,
                            maximum: 60
                        },
                        on_error: {
                            type: 'string',
                            description: 'Error handling: continue (ignore errors), stop (halt sequence), retry (try again)',
                            enum: ['continue', 'stop', 'retry']
                        },
                        retry_count: {
                            type: 'number',
                            description: 'Max retry attempts when on_error=retry (default: 3)',
                            minimum: 1,
                            maximum: 10
                        }
                    },
                    required: ['tool', 'type']
                }
            },
            description: {
                type: 'string',
                description: 'Optional description of what this sequence does'
            }
        },
        required: ['steps']
    };
  • src/server.ts:347-397 (registration)
    Instantiates SequenceTool as part of the tools array and configures it specifically by setting the tool registry (required for cross-tool sequencing), along with common setups like commandExecutor.
    private initializeTools(): void {
      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(), // ✅ 新規追加(可変制御点ベジェ曲線)
      ];
    
      // 全ツールにコマンド実行関数とSocket-BEインスタンスを設定
      const commandExecutor = async (
        command: string
      ): Promise<ToolCallResult> => {
        return this.executeCommand(command);
      };
    
      this.tools.forEach((tool) => {
        tool.setCommandExecutor(commandExecutor);
        tool.setSocketBEInstances(this.currentWorld, this.currentAgent);
      });
    
      // SequenceToolにツールレジストリを設定
      const sequenceTool = this.tools.find(
        (tool) => tool.name === "sequence"
      ) as SequenceTool;
      if (sequenceTool) {
        const toolRegistry = new Map<string, BaseTool>();
        this.tools.forEach((tool) => {
          toolRegistry.set(tool.name, tool);
        });
        sequenceTool.setToolRegistry(toolRegistry);
      }
    }
  • src/server.ts:491-573 (registration)
    Registers all tools including 'sequence' to the MCP server using mcpServer.registerTool with converted Zod schema and execution wrapper.
    private registerModularTools(): void {
      const schemaConverter = new SchemaToZodConverter();
    
      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 to execute a single global sequence step by looking up the specified tool from the registry and calling its execute method with prepared arguments.
    private async executeGlobalSequenceStep(step: GlobalSequenceStep, index: number): Promise<ToolCallResult> {
        // wait ステップは特別処理
        if (step.type === 'wait') {
            const waitTime = step.wait_time || 1;
            await this.delay(waitTime);
            return this.createSuccessResponse(`Waited ${waitTime}s`);
        }
    
        // 指定されたツールを取得
        const tool = this.toolRegistry.get(step.tool);
        if (!tool) {
            return this.createErrorResponse(`Tool '${step.tool}' not found in registry`);
        }
    
        // ツール用の引数を準備 (tool フィールドを除外)
        const { tool: toolName, ...toolArgs } = step;
        const executeArgs = { action: step.type, ...toolArgs };
    
        try {
            // 指定されたツールでアクションを実行
            return await tool.execute(executeArgs);
        } catch (error) {
            return this.createErrorResponse(`Tool ${step.tool} execution error: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
Behavior4/5

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

With no annotations provided, the description carries the full burden and does well by disclosing key behavioral traits: it's an execution tool for chaining actions, supports timing control with 'wait_time', includes error handling options ('on_error for handling failures'), and lists supported tool categories. However, it doesn't mention potential side effects, rate limits, or authentication requirements.

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

Conciseness5/5

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

The description is efficiently structured with zero waste: first sentence states core purpose, second provides use case example, third lists supported tools, and fourth highlights key parameters. Every sentence adds essential information without redundancy.

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

Completeness4/5

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

For a complex orchestration tool with no annotations and no output schema, the description provides good context about what the tool does, when to use it, and behavioral aspects. However, it doesn't explain what happens after execution (e.g., success/failure responses) or potential constraints, leaving some gaps in completeness.

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?

With 100% schema description coverage, the baseline is 3. The description adds some value by mentioning 'wait_time for delays, on_error for handling failures' and providing a concrete example, but doesn't significantly enhance parameter understanding beyond what's already documented in the detailed schema descriptions.

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

Purpose5/5

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

The description clearly states the tool's purpose with specific verbs ('Execute CROSS-TOOL SEQUENCES', 'Chain actions from multiple tools together with timing control') and distinguishes it from sibling tools by explaining it orchestrates actions from tools like player, agent, camera, etc. rather than performing individual actions directly.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('Perfect for complex automation' with examples) and mentions it 'Supports all tools' with a list, but doesn't explicitly state when NOT to use it or name specific alternatives among the sibling tools for simpler cases.

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
  • @leo4life2/minecraft-mcp-http
  • @Mming-Lab/minecraft-bedrock-mcp-server

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