AroFlo: Get BusinessUnits
aroflo_get_businessunitsRetrieve business unit data from AroFlo with customizable queries using WHERE clauses, sorting, and joins to filter and organize information.
Instructions
Query the AroFlo BusinessUnits zone (GET). Use pipe-delimited WHERE clauses like "and|field|=|value", ORDER clauses like "field|asc", and JOIN areas like "lineitems". where/order/join accept either a single string or an array. mode: data|verbose|debug|raw (default: data). Set compact=true and optionally select=["field","nested.field"] to reduce payload size. See resource "aroflo://docs/api/" (example: "aroflo://docs/api/quotes") for valid fields/values.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| where | No | ||
| order | No | ||
| join | No | ||
| page | No | ||
| pageSize | No | ||
| autoPaginate | No | ||
| maxPages | No | ||
| maxResults | No | ||
| maxItemsTotal | No | ||
| validateWhere | No | ||
| mode | No | ||
| verbose | No | ||
| debug | No | ||
| raw | No | ||
| compact | No | ||
| select | No | ||
| maxItems | No | ||
| extra | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/mcp/tools/get-zones.ts:56-271 (handler)The tool 'aroflo_get_businessunits' is dynamically registered within 'registerZoneGetTools' in 'src/mcp/tools/get-zones.ts' by iterating over 'AROFLO_ZONES'. The handler logic is the async function passed to 'server.registerTool'.
server.registerTool( toolName, { title: `AroFlo: Get ${zone}`, description: `Query the AroFlo ${zone} zone (GET). ` + `Use pipe-delimited WHERE clauses like "and|field|=|value", ORDER clauses like "field|asc", and JOIN areas like "lineitems". ` + `where/order/join accept either a single string or an array. ` + `mode: data|verbose|debug|raw (default: data). ` + `Set compact=true and optionally select=[\"field\",\"nested.field\"] to reduce payload size. ` + `See resource "aroflo://docs/api/<slug>" (example: "aroflo://docs/api/quotes") for valid fields/values.`, inputSchema, // MCP SDK expects output schemas to be object schemas (or raw object shapes). // `z.any()` causes output validation to crash under the current SDK. outputSchema: z.object({}).passthrough(), annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true } }, async (args) => { const mode = resolveOutputMode(args); const envelopeRequested = typeof args.mode === 'string' || Boolean(args.raw) || Boolean(args.verbose); try { const where = normalizeWhereParam(args.where); const order = normalizeOrderParam(args.order); const join = normalizeJoinParam(args.join); if (args.validateWhere !== false) { await validateWhereOrThrow({ zone, where }); } const autoPaginate = Boolean(args.autoPaginate); const startPage = args.page ?? 1; const pageSize = args.pageSize ?? (autoPaginate ? 200 : undefined); const maxResultsRaw = typeof args.maxItemsTotal === 'number' ? args.maxItemsTotal : args.maxResults; const maxResults = typeof args.maxResults === 'number' && typeof args.maxItemsTotal === 'number' ? Math.min(args.maxResults, args.maxItemsTotal) : maxResultsRaw; const maxPages = args.maxPages ?? (autoPaginate ? 25 : undefined); const debugInfo: Record<string, unknown> | undefined = args.debug ? { zone, normalized: { where, order, join, page: startPage, pageSize, extra: args.extra } } : undefined; let response = await client.get(zone, { where, order, join, page: startPage, pageSize, extra: args.extra }); let pagesFetched = 1; let truncated = false; let truncatedReason: string | undefined; let nextPage: number | undefined; if (autoPaginate) { let currentPage = startPage; let lastPageCount = extractZoneItems(zone, response.data).items.length; while (true) { const total = extractZoneItems(zone, response.data).items.length; if (typeof maxResults === 'number' && total >= maxResults) { truncated = true; truncatedReason = 'maxResults'; nextPage = currentPage + 1; break; } if (typeof maxPages === 'number' && pagesFetched >= maxPages) { truncated = true; truncatedReason = 'maxPages'; nextPage = currentPage + 1; break; } if (typeof pageSize === 'number' && lastPageCount < pageSize) { break; } currentPage += 1; const next = await client.get(zone, { where, order, join, page: currentPage, pageSize, extra: args.extra }); // If the next page contributes nothing, stop. const nextCount = extractZoneItems(zone, next.data).items.length; if (nextCount === 0) { break; } response = { ...response, data: mergeZoneResponseData(response.data, next.data).merged }; pagesFetched += 1; lastPageCount = nextCount; // Stop if the last page was short. if (typeof pageSize === 'number' && nextCount < pageSize) { break; } } } if (typeof maxResults === 'number') { const total = extractZoneItems(zone, response.data).items.length; if (total > maxResults) { const { truncated: newData } = truncateZoneArrays(response.data, maxResults); response = { ...response, data: newData }; truncated = true; truncatedReason = truncatedReason ?? 'maxResults'; } } let compactApplied = false; let effectiveResponse = response; const defaultSelect = zone === 'Tasks' && args.compact && (!args.select || args.select.length === 0) ? [ 'taskid', 'jobnumber', 'status', 'taskname', 'daterequested', 'createdutc', 'clientid', 'org.orgid', 'org.orgname', 'projectid', 'stageid', 'project.projectid', 'project.projectname', 'tasktotals.totalhrs' ] : undefined; const select = args.select ?? defaultSelect; if (args.compact || (select && select.length > 0) || args.maxItems) { compactApplied = true; const compactedData = compactZoneResponseData(response.data, { select, maxItems: args.maxItems }); effectiveResponse = { ...response, data: compactedData }; } // Backward compatible default: return the full AroFlo client response, optionally // annotated with pagination/debug metadata. The new minimal envelope is opt-in via // args.mode / args.verbose / args.raw. if (!envelopeRequested) { let finalData: unknown = effectiveResponse.data; if (autoPaginate || truncated) { finalData = withZoneResponseMeta(finalData, { pagesFetched, truncated, truncatedReason, nextPage }); } if (debugInfo) { finalData = withDebug(finalData, debugInfo); } return successToolResult({ ...effectiveResponse, data: finalData }); } const out = buildZoneDataEnvelope({ zone, response: effectiveResponse, page: startPage, pageSize, mode, mcp: autoPaginate || truncated ? { autoPaginate, pagesFetched, truncated, truncatedReason, nextPage } : undefined, debug: debugInfo, compactApplied, select, maxItems: args.maxItems }); return successToolResult(out); } catch (error) { return errorToolResult(error, { mode, debug: { zone } }); } } ); - src/mcp/tools/get-zones.ts:55-55 (registration)Dynamic registration of the tool name using 'zoneToToolSuffix'.
const toolName = `aroflo_get_${zoneToToolSuffix(zone)}`;