b24_batch
Execute multiple Bitrix24 API calls in one request, using results from previous calls as parameters for the next.
Instructions
Ejecuta múltiples llamadas a la API de Bitrix24 en una sola request HTTP. Los resultados de una llamada pueden usarse como parámetros de la siguiente con $result[alias][campo].
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| calls | Yes | Objeto donde cada clave es un alias y el valor es { method, params }. Los params pueden referenciar resultados previos con $result[alias][campo]. Ejemplo: { "deals": { "method": "crm.deal.list", "params": { "filter": { "STAGE_ID": "NEW" } } } } | |
| webhook_url | No |
Implementation Reference
- index.js:98-101 (registration)Registration of the 'b24_batch' MCP tool, wiring the schema (batchSchema) and handler (universalBatch) together.
server.tool('b24_batch', 'Ejecuta múltiples llamadas a la API de Bitrix24 en una sola request HTTP. ' + 'Los resultados de una llamada pueden usarse como parámetros de la siguiente con $result[alias][campo].', batchSchema.shape, wrap(universalBatch)); - src/tools/universal-call.js:29-39 (schema)Zod schema for b24_batch: defines 'calls' as a record of aliases with method/params, plus an optional webhook_url.
export const batchSchema = z.object({ calls: z.record(z.object({ method: z.string(), params: z.record(z.any()).optional().default({}), })).describe( 'Objeto donde cada clave es un alias y el valor es { method, params }. ' + 'Los params pueden referenciar resultados previos con $result[alias][campo]. ' + 'Ejemplo: { "deals": { "method": "crm.deal.list", "params": { "filter": { "STAGE_ID": "NEW" } } } }' ), webhook_url: z.string().url().optional(), }); - src/tools/universal-call.js:41-60 (handler)Handler function for b24_batch: builds Bitrix24 batch command format (cmd object), calls the 'batch' REST method with halt=0, and returns results, errors, and totals per alias.
export async function universalBatch({ calls, webhook_url }) { const client = new Bitrix24Client(resolveWebhook(webhook_url)); // Bitrix24 batch format const cmd = {}; for (const [alias, call] of Object.entries(calls)) { const paramStr = Object.entries(call.params || {}) .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(typeof v === 'object' ? JSON.stringify(v) : v)}`) .join('&'); cmd[alias] = `${call.method}?${paramStr}`; } const response = await client.call('batch', { cmd, halt: 0 }); return { portal: client.portal, result: response.result?.result ?? response.result, errors: response.result?.result_error ?? {}, total: response.result?.result_total ?? {}, }; } - src/utils/resolve-webhook.js:1-10 (helper)Helper function that resolves the webhook URL: uses the provided one or falls back to the B24_DEFAULT_WEBHOOK environment variable.
export function resolveWebhook(webhookParam) { const url = webhookParam || process.env.B24_DEFAULT_WEBHOOK; if (!url) { throw new Error( 'No se especificó webhook_url y no hay B24_DEFAULT_WEBHOOK configurado. ' + 'Indicá el webhook en el parámetro webhook_url o configuralo en el servidor MCP.' ); } return url; } - src/bitrix24/client.js:6-30 (helper)Bitrix24Client class used by universalBatch: wraps Axios HTTP calls with retries, rate limiting, and webhook URL handling.
export class Bitrix24Client { constructor(webhookUrl) { this.webhookUrl = webhookUrl.endsWith('/') ? webhookUrl : webhookUrl + '/'; this.limiter = new RateLimiter(500); this.portal = this._extractPortal(webhookUrl); } _extractPortal(url) { try { return new URL(url).hostname; } catch { return 'unknown'; } } async call(method, params = {}, retries = 0) { return this.limiter.schedule(async () => { try { const url = `${this.webhookUrl}${method}.json`; const response = await axios.post(url, params, { timeout: 30000 }); if (response.data.error) { throw new Error(`Bitrix24 error [${response.data.error}]: ${response.data.error_description}`); } return response.data; } catch (err) {