AroFlo: Get MessageBoard
aroflo_get_messageboardRetrieve message board data from AroFlo with customizable queries using WHERE, ORDER, and JOIN parameters to filter and organize information.
Instructions
Query the AroFlo MessageBoard 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/query-zone.ts:47-240 (handler)The tool 'aroflo_query_zone' is used for accessing all AroFlo zones (including MessageBoard). It handles dynamic queries for zones defined in AROFLO_ZONES.
server.registerTool( 'aroflo_query_zone', { title: 'AroFlo: Query Zone', description: 'Query an arbitrary AroFlo zone using WHERE/ORDER/JOIN clauses. ' + '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. ' + 'Set compact=true and optionally select=["field","nested.field"] to reduce payload size. ' + 'mode: data|verbose|debug|raw (default: data). ' + 'See resource "aroflo://docs/api" for the extracted zone docs.', 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: args.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: args.zone, normalized: { where, order, join, page: startPage, pageSize, extra: args.extra } } : undefined; let response = await client.get(args.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(args.zone, response.data).items.length; while (true) { const total = extractZoneItems(args.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(args.zone, { where, order, join, page: currentPage, pageSize, extra: args.extra }); const nextCount = extractZoneItems(args.zone, next.data).items.length; if (nextCount === 0) { break; } response = { ...response, data: mergeZoneResponseData(response.data, next.data).merged }; pagesFetched += 1; lastPageCount = nextCount; if (typeof pageSize === 'number' && nextCount < pageSize) { break; } } } if (typeof maxResults === 'number') { const total = extractZoneItems(args.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 select = args.select; 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 full AroFlo response. The 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: args.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: args.zone } }); } } );