Skip to main content
Glama
MUSE-CODE-SPACE

Vibe Coding Documentation MCP (MUSE)

muse_batch

Run multiple tool operations in batch with sequential or parallel execution, dependency management, and actions to execute, preview, cancel, or check status.

Instructions

Executes multiple tool operations in batch. Actions: execute (run batch), preview (plan without executing), status (check job status), cancel (stop running job), history (list past jobs). Supports sequential and parallel execution with dependency management.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
operationsNoArray of operations to execute
modeNoExecution mode (default: sequential)
stopOnErrorNoStop batch on first error (default: true)
timeoutNoTimeout per operation in ms (default: 60000)
jobIdNoJob ID for status/cancel actions
limitNoLimit for history action (default: 20)
statusNoFilter history by status
includeResultsNoInclude operation results in response (default: true)
includeErrorsNoInclude error details in response (default: true)

Implementation Reference

  • Main handler function for muse_batch tool. Implements execute (runs batch with dependency resolution), preview (plans execution), status (checks job status), cancel (stops running job), history (lists past jobs). Supports sequential and parallel execution with topological sorting of dependencies.
    export async function batchTool(input: BatchInput): Promise<BatchOutput> {
      const {
        action,
        operations,
        mode = 'sequential',
        stopOnError = true,
        timeout = 60000,
        jobId,
        limit = 20,
        status: filterStatus,
        includeResults = true,
        includeErrors = true,
      } = input;
    
      logger.info('Batch action requested', { action, mode, operationCount: operations?.length });
    
      try {
        switch (action) {
          case 'execute':
          case 'preview': {
            if (!operations || operations.length === 0) {
              return {
                success: false,
                action,
                error: 'operations are required',
              };
            }
    
            // Validate operations
            for (const op of operations) {
              if (!toolRegistry[op.tool]) {
                return {
                  success: false,
                  action,
                  error: `Unknown tool: ${op.tool}`,
                };
              }
            }
    
            // For preview, just return the plan
            if (action === 'preview') {
              const sortedOps = sortByDependencies(operations);
    
              const previewResults: OperationResult[] = sortedOps.map((op, index) => ({
                id: op.id || generateOpId(index, op.tool),
                tool: op.tool,
                status: 'pending',
              }));
    
              return {
                success: true,
                action,
                results: previewResults,
                message: `Preview: ${operations.length} operations will be executed in ${mode} mode`,
              };
            }
    
            // Execute
            const batchJobId = generateJobId();
            const startedAt = new Date().toISOString();
    
            activeJobs.set(batchJobId, { cancelled: false });
    
            const job: BatchJob = {
              id: batchJobId,
              status: 'running',
              operations: [],
              mode,
              startedAt,
              successCount: 0,
              failCount: 0,
            };
    
            jobHistory.set(batchJobId, job);
    
            const sortedOps = sortByDependencies(operations);
            const previousResults = new Map<string, any>();
    
            if (mode === 'sequential') {
              // Sequential execution
              for (let i = 0; i < sortedOps.length; i++) {
                const op = sortedOps[i];
    
                // Check for cancellation
                if (activeJobs.get(batchJobId)?.cancelled) {
                  job.status = 'cancelled';
                  break;
                }
    
                const result = await executeOperation(op, previousResults, timeout);
                job.operations.push(result);
    
                if (result.status === 'completed') {
                  job.successCount++;
                  previousResults.set(result.id, result.result);
                } else {
                  job.failCount++;
                  if (stopOnError) {
                    job.status = 'failed';
                    break;
                  }
                }
              }
            } else {
              // Parallel execution (respecting dependencies)
              const completed = new Set<string>();
              const pending = new Map<string, BatchOperation>();
    
              sortedOps.forEach((op, index) => {
                const id = op.id || generateOpId(index, op.tool);
                pending.set(id, { ...op, id });
              });
    
              while (pending.size > 0 && !activeJobs.get(batchJobId)?.cancelled) {
                // Find operations that can be executed (dependencies satisfied)
                const ready: BatchOperation[] = [];
                pending.forEach((op, id) => {
                  const deps = op.dependsOn || [];
                  if (deps.every((d) => completed.has(d))) {
                    ready.push(op);
                  }
                });
    
                if (ready.length === 0 && pending.size > 0) {
                  // Deadlock or cycle
                  job.status = 'failed';
                  job.operations.push({
                    id: 'deadlock',
                    tool: 'batch',
                    status: 'failed',
                    error: 'Deadlock detected: unable to proceed with remaining operations',
                  });
                  break;
                }
    
                // Execute ready operations in parallel
                const results = await Promise.all(
                  ready.map((op) => executeOperation(op, previousResults, timeout))
                );
    
                for (const result of results) {
                  job.operations.push(result);
                  completed.add(result.id);
                  pending.delete(result.id);
    
                  if (result.status === 'completed') {
                    job.successCount++;
                    previousResults.set(result.id, result.result);
                  } else {
                    job.failCount++;
                    if (stopOnError) {
                      job.status = 'failed';
                      pending.clear();
                      break;
                    }
                  }
                }
              }
            }
    
            // Finalize job
            if (job.status === 'running') {
              job.status = job.failCount > 0 ? 'failed' : 'completed';
            }
    
            job.completedAt = new Date().toISOString();
            job.totalDuration = new Date(job.completedAt).getTime() - new Date(startedAt).getTime();
    
            activeJobs.delete(batchJobId);
            jobHistory.set(batchJobId, job);
    
            // Prepare response
            const responseResults = job.operations.map((op) => ({
              ...op,
              result: includeResults ? op.result : undefined,
              error: includeErrors ? op.error : undefined,
            }));
    
            return {
              success: job.status === 'completed',
              action,
              job: { ...job, operations: responseResults },
              results: responseResults,
              message: `Batch ${job.status}: ${job.successCount} succeeded, ${job.failCount} failed`,
            };
          }
    
          case 'status': {
            if (!jobId) {
              return {
                success: false,
                action,
                error: 'jobId is required',
              };
            }
    
            const job = jobHistory.get(jobId);
            if (!job) {
              return {
                success: false,
                action,
                error: `Job not found: ${jobId}`,
              };
            }
    
            return {
              success: true,
              action,
              job,
              message: `Job ${job.status}`,
            };
          }
    
          case 'cancel': {
            if (!jobId) {
              return {
                success: false,
                action,
                error: 'jobId is required',
              };
            }
    
            const activeJob = activeJobs.get(jobId);
            if (!activeJob) {
              return {
                success: false,
                action,
                error: `Job not found or already completed: ${jobId}`,
              };
            }
    
            activeJob.cancelled = true;
    
            return {
              success: true,
              action,
              message: `Job ${jobId} cancellation requested`,
            };
          }
    
          case 'history': {
            let jobs = Array.from(jobHistory.values());
    
            // Filter by status if specified
            if (filterStatus) {
              jobs = jobs.filter((j) => j.status === filterStatus);
            }
    
            // Sort by start time (newest first)
            jobs.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
    
            // Paginate
            const total = jobs.length;
            const paginated = jobs.slice(0, limit);
    
            return {
              success: true,
              action,
              jobs: paginated,
              total,
              message: `Found ${total} batch jobs`,
            };
          }
    
          default:
            return {
              success: false,
              action,
              error: `Unknown action: ${action}`,
            };
        }
      } catch (error) {
        logger.error('Batch operation failed', error as Error);
        return {
          success: false,
          action,
          error: error instanceof Error ? error.message : 'Unknown error',
        };
      }
    }
  • MCP registration schema for muse_batch tool. Defines name, description, and inputSchema with properties: action (required enum), operations (array of tool/params/id/dependsOn), mode, stopOnError, timeout, jobId, limit, status, includeResults, includeErrors.
    export const batchSchema = {
      name: 'muse_batch',
      description: 'Executes multiple tool operations in batch. Actions: execute (run batch), preview (plan without executing), status (check job status), cancel (stop running job), history (list past jobs). Supports sequential and parallel execution with dependency management.',
      inputSchema: {
        type: 'object',
        properties: {
          action: {
            type: 'string',
            enum: ['execute', 'preview', 'status', 'cancel', 'history'],
            description: 'Action to perform',
          },
          operations: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                tool: {
                  type: 'string',
                  description: 'Tool name to execute (e.g., muse_analyze_code)',
                },
                params: {
                  type: 'object',
                  description: 'Parameters to pass to the tool',
                },
                id: {
                  type: 'string',
                  description: 'Optional operation ID for dependency reference',
                },
                dependsOn: {
                  type: 'array',
                  items: { type: 'string' },
                  description: 'IDs of operations this depends on',
                },
              },
              required: ['tool', 'params'],
            },
            description: 'Array of operations to execute',
          },
          mode: {
            type: 'string',
            enum: ['sequential', 'parallel'],
            description: 'Execution mode (default: sequential)',
          },
          stopOnError: {
            type: 'boolean',
            description: 'Stop batch on first error (default: true)',
          },
          timeout: {
            type: 'number',
            description: 'Timeout per operation in ms (default: 60000)',
          },
          jobId: {
            type: 'string',
            description: 'Job ID for status/cancel actions',
          },
          limit: {
            type: 'number',
            description: 'Limit for history action (default: 20)',
          },
          status: {
            type: 'string',
            enum: ['pending', 'running', 'completed', 'failed', 'cancelled'],
            description: 'Filter history by status',
          },
          includeResults: {
            type: 'boolean',
            description: 'Include operation results in response (default: true)',
          },
          includeErrors: {
            type: 'boolean',
            description: 'Include error details in response (default: true)',
          },
        },
        required: ['action'],
      },
    };
  • src/stdio.ts:124-127 (registration)
    Registration of muse_batch in the toolHandlers map. Maps 'muse_batch' name to an async handler that validates input via BatchSchema and calls batchTool.
    muse_batch: async (args: unknown) => {
      const validated = validateInput(BatchSchema, args);
      return batchTool(validated as Parameters<typeof batchTool>[0]);
    },
  • src/stdio.ts:149-169 (registration)
    Server tool listing registration. batchSchema is included in the tools array returned by ListToolsRequestSchema handler, making muse_batch available to clients.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          collectCodeContextSchema,
          summarizeDesignDecisionsSchema,
          generateDevDocumentSchema,
          normalizeForPlatformSchema,
          publishDocumentSchema,
          createSessionLogSchema,
          analyzeCodeSchema,
          sessionHistorySchema,
          exportSessionSchema,
          projectProfileSchema,
          gitSchema,
          sessionStatsSchema,
          autoTagSchema,
          templateSchema,
          batchSchema,
        ],
      };
    });
  • Zod validation schema (BatchSchema) for muse_batch tool input. Defines all input fields with types, defaults, and validation rules for actions, operations, execution mode, timeout, filtering, and output options.
    export const BatchSchema = z.object({
      action: z.enum(['execute', 'preview', 'status', 'cancel', 'history']),
    
      // Batch job definition
      operations: z.array(z.object({
        tool: z.string(),
        params: z.record(z.unknown()),
        id: z.string().optional(),
        dependsOn: z.array(z.string()).optional()
      })).optional(),
    
      // Execution options
      mode: z.enum(['sequential', 'parallel']).optional().default('sequential'),
      stopOnError: z.boolean().optional().default(true),
      timeout: z.number().min(1000).max(600000).optional().default(60000),
    
      // For status/cancel actions
      jobId: z.string().optional(),
    
      // For history action
      limit: z.number().optional().default(20),
      status: z.enum(['pending', 'running', 'completed', 'failed', 'cancelled']).optional(),
    
      // Output options
      includeResults: z.boolean().optional().default(true),
      includeErrors: z.boolean().optional().default(true)
    });
Behavior2/5

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

The description does not disclose behavioral traits beyond what is implied by the actions. With no annotations, it fails to mention potential destructive nature, authorization requirements, rate limits, or error handling nuances beyond stopOnError. For a tool that executes operations, more transparency is needed.

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 three sentences and clearly communicates the tool's purpose and key features. It is well-structured and front-loaded with the action list. Minor improvement could be trimming redundancy.

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?

Given the tool's complexity (10 parameters, no output schema), the description lacks information about return values, response format, or error details. It covers usage but misses critical context for an agent to anticipate behavior fully.

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?

The input schema has 100% coverage with descriptions for all parameters. The description does not add extra semantic value beyond summarizing the actions; thus it meets the baseline for high schema coverage.

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 identifies the tool as a batch executor for multiple tool operations, listing specific actions (execute, preview, status, cancel, history) and highlighting its ability to handle sequential/parallel execution with dependency management. It distinguishes itself from sibling tools which are individual operation tools.

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 on when to use this tool (for batching multiple operations) and explains actions and modes. However, it lacks explicit 'when not to use' guidance or mention of alternatives (e.g., calling tools individually).

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

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/MUSE-CODE-SPACE/vibe-coding-mcp'

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