bruno_run_collection
Execute API test collections or specific folders to validate endpoints, generate test reports, and manage environment variables for comprehensive API testing workflows.
Instructions
Run an entire Bruno collection or a specific folder within it
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| collectionPath | Yes | Path to the Bruno collection | |
| environment | No | Name or path of the environment to use (optional) | |
| folderPath | No | Specific folder within collection to run (optional) | |
| envVariables | No | Environment variables as key-value pairs (optional) | |
| reporterJson | No | Path to write JSON report (optional) | |
| reporterJunit | No | Path to write JUnit XML report for CI/CD integration (optional) | |
| reporterHtml | No | Path to write HTML report (optional) | |
| dryRun | No | Validate all requests without executing HTTP calls (optional) |
Implementation Reference
- The RunCollectionHandler class provides the core implementation for the 'bruno_run_collection' tool. It handles execution of Bruno collections, security validation, formatting of results, and supports dry-run mode.export class RunCollectionHandler implements IToolHandler { private readonly brunoCLI: IBrunoCLI; private readonly formatter: RunResultFormatter; constructor(brunoCLI: IBrunoCLI) { this.brunoCLI = brunoCLI; this.formatter = new RunResultFormatter(); } getName(): string { return 'bruno_run_collection'; } async handle(args: unknown): Promise<ToolResponse> { const params = RunCollectionSchema.parse(args); // Security validation const validation = await validateToolParameters({ collectionPath: params.collectionPath, folderPath: params.folderPath, envVariables: params.envVariables }); if (!validation.valid) { logSecurityEvent({ type: 'access_denied', details: `Run collection blocked: ${validation.errors.join(', ')}`, severity: 'error' }); throw new McpError( ErrorCode.InvalidRequest, `Security validation failed: ${validation.errors.join(', ')}` ); } // Log warnings if any if (validation.warnings.length > 0) { validation.warnings.forEach(warning => { logSecurityEvent({ type: 'env_var_validation', details: warning, severity: 'warning' }); }); } // Handle dry run mode if (params.dryRun) { return await this.handleDryRun(params); } const result = await this.brunoCLI.runCollection( params.collectionPath, { environment: params.environment || params.enviroment, folderPath: params.folderPath, envVariables: params.envVariables, reporterJson: params.reporterJson, reporterJunit: params.reporterJunit, reporterHtml: params.reporterHtml } ); return { content: [ { type: 'text', text: this.formatter.format(result) } as TextContent ] }; } private async handleDryRun(params: RunCollectionParams): Promise<ToolResponse> { try { // List all requests in the collection/folder const requests = await this.brunoCLI.listRequests(params.collectionPath); // Filter by folder if specified let requestsToValidate = requests; if (params.folderPath) { requestsToValidate = requests.filter(req => req.folder && params.folderPath && req.folder.includes(params.folderPath) ); } const output: string[] = []; output.push('=== DRY RUN: Collection Validation ==='); output.push(''); output.push(`✅ Collection validated successfully (HTTP calls not executed)`); output.push(''); output.push(`Total Requests: ${requestsToValidate.length}`); output.push(''); // Validate each request output.push('Requests that would be executed:'); for (const req of requestsToValidate) { try { const details = await this.brunoCLI.getRequestDetails( params.collectionPath, req.name ); output.push(` ✓ ${req.name} - ${details.method} ${details.url}`); } catch (error) { output.push(` ✗ ${req.name} - Validation error: ${error}`); } } output.push(''); if (params.folderPath) { output.push(`Folder Filter: ${params.folderPath}`); output.push(''); } if (params.environment) { output.push(`Environment: ${params.environment}`); output.push(''); } if (params.envVariables && Object.keys(params.envVariables).length > 0) { output.push(`Environment Variables: ${Object.keys(params.envVariables).length} provided`); output.push(''); } output.push('ℹ️ This was a dry run - no HTTP requests were sent.'); output.push(' Remove dryRun parameter to execute the actual collection.'); return { content: [ { type: 'text', text: output.join('\n') } as TextContent ] }; } catch (error) { const maskedError = error instanceof Error ? maskSecretsInError(error) : error; throw new McpError( ErrorCode.InternalError, `Dry run validation failed: ${maskedError}` ); } } }
- Zod schema used for input parameter validation within the handler.const RunCollectionSchema = z.object({ collectionPath: z.string().describe('Path to the Bruno collection'), environment: z.string().optional().describe('Name or path of the environment to use'), enviroment: z.string().optional().describe('Alias for environment (to handle common typo)'), folderPath: z.string().optional().describe('Specific folder within collection to run'), envVariables: z.record(z.string()).optional().describe('Environment variables as key-value pairs'), reporterJson: z.string().optional().describe('Path to write JSON report'), reporterJunit: z.string().optional().describe('Path to write JUnit XML report'), reporterHtml: z.string().optional().describe('Path to write HTML report'), dryRun: z.boolean().optional().describe('Validate requests without executing HTTP calls') }); type RunCollectionParams = z.infer<typeof RunCollectionSchema>;
- src/index.ts:77-123 (schema)JSON Schema definition for the 'bruno_run_collection' tool, used for MCP tool listing and validation.{ name: 'bruno_run_collection', description: 'Run all requests in a Bruno collection or specific folder', inputSchema: { type: 'object', properties: { collectionPath: { type: 'string', description: 'Path to the Bruno collection' }, environment: { type: 'string', description: 'Name or path of the environment to use' }, enviroment: { type: 'string', description: 'Alias for environment (to handle common typo)' }, folderPath: { type: 'string', description: 'Specific folder within collection to run' }, envVariables: { type: 'object', description: 'Environment variables as key-value pairs', additionalProperties: { type: 'string' } }, reporterJson: { type: 'string', description: 'Path to write JSON report' }, reporterJunit: { type: 'string', description: 'Path to write JUnit XML report' }, reporterHtml: { type: 'string', description: 'Path to write HTML report' }, dryRun: { type: 'boolean', description: 'Validate requests without executing HTTP calls' } }, required: ['collectionPath'] } },
- src/index.ts:284-298 (registration)Registration of the RunCollectionHandler instance into the ToolRegistry during server initialization.private registerToolHandlers(): void { const container = getContainer(); const perfManager = container.get<PerformanceManager>(ServiceKeys.PERFORMANCE_MANAGER); // Register all tool handlers this.toolRegistry.register(new RunRequestHandler(this.brunoCLI)); this.toolRegistry.register(new RunCollectionHandler(this.brunoCLI)); this.toolRegistry.register(new ListRequestsHandler(this.brunoCLI)); this.toolRegistry.register(new HealthCheckHandler(this.brunoCLI, this.configLoader, perfManager)); this.toolRegistry.register(new DiscoverCollectionsHandler(this.brunoCLI)); this.toolRegistry.register(new ListEnvironmentsHandler(this.brunoCLI)); this.toolRegistry.register(new ValidateEnvironmentHandler(this.brunoCLI)); this.toolRegistry.register(new GetRequestDetailsHandler(this.brunoCLI)); this.toolRegistry.register(new ValidateCollectionHandler(this.brunoCLI)); }