/** * Shared utilities for MCP tool handlers. * * This module is used by both the local (stdio) and remote (Cloudflare Workers) * MCP servers. It must NOT import concrete classes from either client — error * detection uses duck-typing (checking for `statusCode`/`errorCode` properties) * so it works regardless of which FrihetApiError class threw the error. */ import type { ToolAnnotations, Annotations } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod/v4"; import type { PaginatedResponse } from "../types.js"; export declare const READ_ONLY_ANNOTATIONS: ToolAnnotations; export declare const CREATE_ANNOTATIONS: ToolAnnotations; export declare const UPDATE_ANNOTATIONS: ToolAnnotations; export declare const DELETE_ANNOTATIONS: ToolAnnotations; /** List operations: useful to both user and assistant for navigation, medium priority. */ export declare const LIST_CONTENT_ANNOTATIONS: Annotations; /** Get/read operations: useful to both, higher priority as specifically requested data. */ export declare const GET_CONTENT_ANNOTATIONS: Annotations; /** Mutating operations (create/update/delete): primarily for the user, highest priority. */ export declare const MUTATE_CONTENT_ANNOTATIONS: Annotations; /** Error responses: always high priority, always for the user. */ export declare const ERROR_CONTENT_ANNOTATIONS: Annotations; export interface AnnotatedTextContent { type: "text"; text: string; annotations?: Annotations; } export declare function truncateResponse(text: string, truncatedNotice?: string): string; /** * Maps an error to a user-friendly MCP tool response with error annotations. * Emits structured log entries for all errors. */ export declare function handleToolError(error: unknown, toolName?: string): { content: AnnotatedTextContent[]; isError: true; _meta?: Record; }; /** * Formats a paginated API response into readable text. */ export declare function formatPaginatedResponse(resourceName: string, response: PaginatedResponse>): string; /** Format an exhaustive list whose backend exposes no pagination controls. */ export declare function formatUnpaginatedListResponse(resourceName: string, response: { data: T[]; total: number; }): string; /** * Formats a single record for display. */ export declare function formatRecord(label: string, record: object): string; /** * Builds an annotated content block for list/search responses. */ export declare function listContent(text: string): AnnotatedTextContent; /** * Builds an annotated content block for get/read responses. */ export declare function getContent(text: string): AnnotatedTextContent; /** * Builds an annotated content block for create/update/delete responses. */ export declare function mutateContent(text: string): AnnotatedTextContent; /** * Returns agent-facing suggestions and warnings for a tool call, formatted * as plain text to be APPENDED to the human-readable `content` block. * * Why text, not structured fields: `structuredContent` is the strict * outputSchema contract. Spreading `{ _suggestions, _warnings }` into * structuredContent would make them undeclared enrichment (Inspector / * conformance failures, drift in the OpenAI reviewed surface's frozen * snapshot). The hints are agent-facing and deterministic from the * emitted data, so they belong in the text the model reads, not in the * JSON the schema validates. Pinned by * src/__tests__/paginated-strict-output.test.ts (ERP #1580): the strict * contract test asserts structuredContent never carries the old * `_suggestions` / `_warnings` keys. */ export declare function enrichResponse(resource: string, operation: string, data: unknown): string; /** * Wraps an item schema in a paginated envelope for list/search tools. * * The item schema is made `.partial()` (every field optional) BEFORE it goes * into the array. Rationale: every list/search endpoint accepts a `fields=` * projection (e.g. `fields=id,total` → rows shaped `{ id }`), and drafts * legitimately omit otherwise-populated fields (an invoice draft with no line * items, a null clientName). A non-partial item schema rejects the WHOLE list * call the moment any row is a projection or a draft — verified live: `GET * /invoices?fields=id,total` returns 200 with `{ id }`-shaped rows that failed * `invoiceItemOutput`'s required `clientName`/`items`. `.partial()` preserves * `.passthrough()`, so genuine fields still surface and stay documented; it only * drops the "required" constraint that a projection can't satisfy. Create/get * single-object tools keep their fuller item schemas (they return the whole row). */ export declare function paginatedOutput(itemSchema: T, opts?: { projectable?: boolean; }): z.ZodObject<{ data: z.ZodArray; }, z.core.$strip>>; total: z.ZodNumber; limit: z.ZodNumber; offset: z.ZodNumber; nextCursor: z.ZodOptional; }, z.core.$strip>; /** Schema for delete operation results. */ export declare const deleteResultOutput: z.ZodObject<{ success: z.ZodBoolean; id: z.ZodString; }, z.core.$strip>; /** * Schema for deletes of FISCAL DOCUMENTS (invoices, quotes) — the only two * resources where "delete" is not always a delete. * * The backend refuses to destroy a non-draft invoice/quote (VeriFactu hash * chain) and soft-CANCELS it instead, distinguishing the outcomes on the wire: * 204 = row destroyed, 200 + body = document kept with status=cancelled * (erp-main publicApi.ts `deleteResource`). `outcome` is what lets an agent * tell the user which one actually happened (GAP-12). * * Deliberately NOT folded into {@link deleteResultOutput}: that one is shared by * nine non-fiscal delete tools whose backend has no cancel branch, and widening * it would drift their published output schema for no behavioural reason. */ export declare const documentDeleteResultOutput: z.ZodObject<{ success: z.ZodBoolean; id: z.ZodString; outcome: z.ZodOptional>; status: z.ZodOptional; previousStatus: z.ZodOptional; cancelledVia: z.ZodOptional; }, z.core.$strip>; /** * Permissive structured-output schema for tools whose API returns an open * `Record` (summaries, single-object actions, VIES/portal * responses). Declares NO required fields and stays `.passthrough()`, so the * SDK's output validation (safeParseAsync of structuredContent) can NEVER * reject a real response — the same over-strict-schema class of bug that made * invoices inoperable in #65. The `.describe()` carries the semantic intent * into the JSON Schema so agents (and directory scanners) still see what the * tool returns, without the runtime risk of pinning a shape we don't control. */ export declare function openObjectOutput(description: string): z.ZodObject<{}, z.core.$loose>; export declare const invoiceItemOutput: z.ZodObject<{ id: z.ZodString; clientId: z.ZodOptional; clientName: z.ZodOptional>; items: z.ZodOptional; description: z.ZodString; quantity: z.ZodNumber; unitPrice: z.ZodNumber; taxRate: z.ZodOptional; discount: z.ZodOptional; }, z.core.$strip>>>; issueDate: z.ZodOptional; dueDate: z.ZodOptional; status: z.ZodOptional; notes: z.ZodOptional; taxRate: z.ZodOptional; discountRate: z.ZodOptional; total: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const expenseItemOutput: z.ZodObject<{ id: z.ZodString; description: z.ZodString; amount: z.ZodNumber; category: z.ZodOptional; date: z.ZodOptional; vendorId: z.ZodOptional; vendor: z.ZodOptional; taxDeductible: z.ZodOptional; paidDate: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const clientItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; email: z.ZodOptional; phone: z.ZodOptional; stage: z.ZodOptional; taxId: z.ZodOptional; address: z.ZodOptional; city: z.ZodOptional; state: z.ZodOptional; postalCode: z.ZodOptional; country: z.ZodOptional; }, z.core.$strip>>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const productItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; unitPrice: z.ZodNumber; description: z.ZodOptional; taxRate: z.ZodOptional; isActive: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const quoteItemOutput: z.ZodObject<{ id: z.ZodString; clientId: z.ZodOptional; clientName: z.ZodOptional>; items: z.ZodOptional; description: z.ZodString; quantity: z.ZodNumber; unitPrice: z.ZodNumber; taxRate: z.ZodOptional; discount: z.ZodOptional; }, z.core.$strip>>>; issueDate: z.ZodOptional; dueDate: z.ZodOptional; validUntil: z.ZodOptional; notes: z.ZodOptional; status: z.ZodOptional; total: z.ZodOptional; taxRate: z.ZodOptional; discountRate: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const vendorItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; email: z.ZodOptional; phone: z.ZodOptional; taxId: z.ZodOptional; address: z.ZodOptional; city: z.ZodOptional; state: z.ZodOptional; postalCode: z.ZodOptional; country: z.ZodOptional; }, z.core.$strip>>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const webhookItemOutput: z.ZodObject<{ id: z.ZodString; userId: z.ZodOptional; name: z.ZodString; url: z.ZodString; events: z.ZodArray; status: z.ZodEnum<{ active: "active"; inactive: "inactive"; paused: "paused"; }>; metadata: z.ZodOptional>; hasSecret: z.ZodBoolean; pausedReason: z.ZodOptional; lastTriggeredAt: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; _demo: z.ZodOptional>; _demoNotice: z.ZodOptional; }, z.core.$strict>; /** Create alone may echo the caller-supplied signing secret once. */ export declare const webhookCreateOutput: z.ZodObject<{ id: z.ZodString; userId: z.ZodOptional; name: z.ZodString; url: z.ZodString; events: z.ZodArray; status: z.ZodEnum<{ active: "active"; inactive: "inactive"; paused: "paused"; }>; metadata: z.ZodOptional>; hasSecret: z.ZodBoolean; pausedReason: z.ZodOptional; lastTriggeredAt: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; _demo: z.ZodOptional>; _demoNotice: z.ZodOptional; secret: z.ZodOptional; }, z.core.$strict>; /** `/webhooks` has no backend pagination contract. */ export declare const webhookListOutput: z.ZodObject<{ data: z.ZodArray; name: z.ZodString; url: z.ZodString; events: z.ZodArray; status: z.ZodEnum<{ active: "active"; inactive: "inactive"; paused: "paused"; }>; metadata: z.ZodOptional>; hasSecret: z.ZodBoolean; pausedReason: z.ZodOptional; lastTriggeredAt: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; _demo: z.ZodOptional>; _demoNotice: z.ZodOptional; }, z.core.$strict>>; total: z.ZodNumber; _demo: z.ZodOptional>; _demoNotice: z.ZodOptional; }, z.core.$strict>; export declare const contactItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; email: z.ZodOptional; phone: z.ZodOptional; role: z.ZodOptional; isPrimary: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const activityItemOutput: z.ZodObject<{ id: z.ZodString; type: z.ZodString; title: z.ZodString; description: z.ZodOptional; metadata: z.ZodOptional>; timestamp: z.ZodString; createdBy: z.ZodOptional>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; _demo: z.ZodOptional>; _demoNotice: z.ZodOptional; }, z.core.$strict>; export declare const noteItemOutput: z.ZodObject<{ id: z.ZodString; content: z.ZodString; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const depositItemOutput: z.ZodObject<{ id: z.ZodString; clientId: z.ZodString; clientName: z.ZodOptional; amount: z.ZodNumber; currency: z.ZodOptional; date: z.ZodOptional; description: z.ZodOptional; status: z.ZodOptional; paymentMethod: z.ZodOptional; reference: z.ZodOptional; notes: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const reservationItemOutput: z.ZodObject<{ id: z.ZodString; propertyId: z.ZodString; guestId: z.ZodOptional; status: z.ZodEnum<{ cancelled: "cancelled"; confirmed: "confirmed"; pending: "pending"; completed: "completed"; no_show: "no_show"; }>; checkIn: z.ZodString; checkOut: z.ZodString; nights: z.ZodOptional; guestCount: z.ZodNumber; channelId: z.ZodOptional; totalAmount: z.ZodOptional; currency: z.ZodOptional; notes: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const propertyItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; address: z.ZodOptional; city: z.ZodOptional; region: z.ZodOptional; postalCode: z.ZodOptional; country: z.ZodOptional; }, z.core.$strip>>; capacity: z.ZodOptional; ownerName: z.ZodOptional; licenseNumber: z.ZodOptional; isActive: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const kitchenTicketItemOutput: z.ZodObject<{ id: z.ZodString; stationId: z.ZodOptional; status: z.ZodOptional; tableRef: z.ZodOptional; items: z.ZodOptional; name: z.ZodOptional; quantity: z.ZodOptional; notes: z.ZodOptional; status: z.ZodOptional; }, z.core.$strip>>>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const kitchenStationItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodOptional; isActive: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const kitchenMenuItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodOptional; priceCents: z.ZodOptional; category: z.ZodOptional; isActive: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const kitchenFlowSummaryItemOutput: z.ZodObject<{ stationId: z.ZodString; stationName: z.ZodOptional; openTickets: z.ZodNumber; oldestWaitSeconds: z.ZodOptional; isBottleneck: z.ZodBoolean; }, z.core.$strip>; export declare const posTerminalItemOutput: z.ZodObject<{ id: z.ZodString; label: z.ZodOptional; deviceType: z.ZodOptional; locationId: z.ZodOptional; status: z.ZodOptional>; stripeReaderId: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const posSaleItemOutput: z.ZodObject<{ id: z.ZodString; terminalId: z.ZodOptional; status: z.ZodOptional>; amountCents: z.ZodOptional; currency: z.ZodOptional; paymentMethod: z.ZodOptional; items: z.ZodOptional>>; refundedAmountCents: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** * Schema for action results (send, mark paid, apply late fee, etc.). * * Verified against the LIVE action endpoints: `POST /invoices/:id/paid` returns * `{ success, status, paidAt }` on the happy path but `{ message, status }` when * the invoice is already paid (no `success`), and NO action endpoint returns an * `id`. Both `success` and `id` are therefore optional; `.passthrough()` lets * the genuine action fields (`status`, `paidAt`, `message`, …) surface. Before * this relaxation every mark_paid/send call failed MCP output validation on the * required `success`/`id` even after the `{ data, meta }` unwrap. */ export declare const actionResultOutput: z.ZodObject<{ success: z.ZodOptional; id: z.ZodOptional; message: z.ZodOptional; messageId: z.ZodOptional; data: z.ZodOptional; meta: z.ZodOptional; }, z.core.$loose>; /** * Schema for `create_credit_note` — the credit-note action returns * `{ success, creditNote: { id, documentNumber, originalInvoiceId, reason, * fullCredit } }` (verified in publicApi.ts), NOT a full invoice. It previously * (wrongly) declared `invoiceItemOutput`, which the action result can never * satisfy even after unwrapping. */ export declare const creditNoteResultOutput: z.ZodObject<{ success: z.ZodOptional; creditNote: z.ZodOptional; documentNumber: z.ZodOptional; originalInvoiceId: z.ZodOptional; reason: z.ZodOptional; fullCredit: z.ZodOptional; status: z.ZodOptional; rectificationMethod: z.ZodOptional; totalCredited: z.ZodOptional; }, z.core.$loose>>; data: z.ZodOptional; meta: z.ZodOptional; }, z.core.$loose>; export declare const bankAccountItemOutput: z.ZodObject<{ id: z.ZodString; alias: z.ZodOptional; ibanLast4: z.ZodOptional; currency: z.ZodOptional; balance: z.ZodOptional; lastSyncedAt: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const bankTransactionItemOutput: z.ZodObject<{ id: z.ZodString; accountId: z.ZodOptional; amount: z.ZodNumber; currency: z.ZodOptional; description: z.ZodOptional; postedAt: z.ZodOptional; category: z.ZodOptional; status: z.ZodOptional>; matchedDocId: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** * Output schema for the Modelo 303/130/390 READ-ONLY summary tools. * * Aligned with the SHIPPED Cloudflare Function response (publicApi.ts), which * — after the client unwraps the `{ data, meta }` envelope — returns: * { model, period, months, modelo303|modelo130|modelo390, summary, readonly, note } * * `model` carries the modelo code ('303'|'130'|'390'). `modeloCode` is kept as * an OPTIONAL alias so legacy callers/fixtures that surface `modeloCode` * validate too (the CF itself emits `model`). The three `modelo*` totals * objects are mutually exclusive per request — each is optional so any one * model validates. `.passthrough()` lets the genuine totals surface even where * a field isn't explicitly enumerated. */ export declare const fiscalModeloSummaryOutput: z.ZodObject<{ model: z.ZodOptional; modeloCode: z.ZodOptional; period: z.ZodOptional; months: z.ZodOptional>; modelo303: z.ZodOptional; cuotaRepercutida: z.ZodOptional; baseDeducible: z.ZodOptional; cuotaDeducible: z.ZodOptional; resultado: z.ZodOptional; baseExenta: z.ZodOptional; baseNoSujetaORC: z.ZodOptional; outOfScope: z.ZodOptional>; }, z.core.$loose>>; modelo130: z.ZodOptional; gastos: z.ZodOptional; rendimientoNeto: z.ZodOptional; pagoFraccionado: z.ZodOptional; retencionesSoportadas: z.ZodOptional; }, z.core.$loose>>; modelo390: z.ZodOptional; cuotaRepercutida: z.ZodOptional; baseDeducible: z.ZodOptional; cuotaDeducible: z.ZodOptional; resultadoAnual: z.ZodOptional; baseExenta: z.ZodOptional; baseNoSujetaORC: z.ZodOptional; outOfScope: z.ZodOptional>; }, z.core.$loose>>; summary: z.ZodOptional; totalExpenses: z.ZodOptional; invoiceCount: z.ZodOptional; expenseCount: z.ZodOptional; clientCount: z.ZodOptional; }, z.core.$loose>>; readonly: z.ZodOptional>; note: z.ZodOptional; totalsByRate: z.ZodOptional>; totalDeductible: z.ZodOptional; totalDue: z.ZodOptional; deadline: z.ZodOptional; }, z.core.$loose>; export declare const verifactuStatusOutput: z.ZodObject<{ invoiceId: z.ZodString; lastSubmissionAt: z.ZodOptional; hash: z.ZodOptional; status: z.ZodOptional>; accepted: z.ZodOptional; submittedAt: z.ZodOptional>; csv: z.ZodOptional>; retryCount: z.ZodOptional; lastError: z.ZodOptional>; sandbox: z.ZodOptional; aeatResponse: z.ZodOptional; qrUrl: z.ZodOptional; }, z.core.$loose>; export declare const ticketbaiStatusOutput: z.ZodObject<{ invoiceId: z.ZodString; lastSubmissionAt: z.ZodOptional; hash: z.ZodOptional; status: z.ZodOptional>; aeatResponse: z.ZodOptional; qrUrl: z.ZodOptional; province: z.ZodOptional>; }, z.core.$loose>; export declare const timeEntryItemOutput: z.ZodObject<{ id: z.ZodString; userId: z.ZodOptional; projectId: z.ZodOptional; hours: z.ZodNumber; description: z.ZodOptional; billable: z.ZodOptional; date: z.ZodOptional; status: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; export declare const recurringInvoiceItemOutput: z.ZodObject<{ id: z.ZodString; templateName: z.ZodOptional; frequency: z.ZodOptional; nextRun: z.ZodOptional; recipient: z.ZodOptional; lineItems: z.ZodOptional>>; status: z.ZodOptional>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** * Schema for the MIME-discriminated `get_invoice_einvoice` artifact. * * Stored UBL/Facturae artifacts return strict UTF-8 `xml`; Factur-X artifacts * return PDF bytes as `base64`. Identity, MIME and byte size are always present. */ export declare const einvoiceResultOutput: z.ZodObject<{ id: z.ZodString; contentType: z.ZodString; sizeBytes: z.ZodNumber; xml: z.ZodOptional; base64: z.ZodOptional; filename: z.ZodOptional; }, z.core.$loose>; /** * Schema for `get_invoice_pdf` results (#1393 — content-type-aware). * * The backend serves raw `application/pdf` bytes. MCP `structuredContent` is * JSON-only, so callers receive bounded base64 plus request identity and size. */ export declare const pdfResultOutput: z.ZodObject<{ id: z.ZodString; contentType: z.ZodString; sizeBytes: z.ZodNumber; base64: z.ZodString; filename: z.ZodOptional; }, z.core.$loose>; export declare const timeSummaryOutput: z.ZodObject<{ from: z.ZodString; to: z.ZodString; totalHours: z.ZodNumber; billableHours: z.ZodNumber; nonBillableHours: z.ZodNumber; estimatedCostEur: z.ZodOptional; groups: z.ZodOptional; totalHours: z.ZodNumber; billableHours: z.ZodNumber; nonBillableHours: z.ZodNumber; estimatedCostEur: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$loose>; export declare const teamMemberItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodOptional>; email: z.ZodOptional>; role: z.ZodOptional>; status: z.ZodOptional>; invitedAt: z.ZodOptional>; joinedAt: z.ZodOptional>; createdAt: z.ZodOptional>; updatedAt: z.ZodOptional>; expiresAt: z.ZodOptional>; }, z.core.$loose>; /** * Gestoria message — single message in a contextual thread attached to a * document request, filing item, or fiscal obligation. Used by both gestor * and client; `senderRole` distinguishes them. */ export declare const gestoriaMessageItemOutput: z.ZodObject<{ id: z.ZodString; parentType: z.ZodOptional>; parentId: z.ZodOptional; senderUid: z.ZodOptional; senderRole: z.ZodOptional>; body: z.ZodString; createdAt: z.ZodOptional; readAt: z.ZodOptional; }, z.core.$loose>; /** Result of `gestoria_message_send` — message metadata + per-side unread counts. */ export declare const gestoriaMessageSendResultOutput: z.ZodObject<{ messageId: z.ZodString; createdAt: z.ZodOptional; unreadCounts: z.ZodOptional; client: z.ZodOptional; }, z.core.$loose>>; }, z.core.$loose>; /** * Document request template — reusable template gestores can bulk-send to N * client workspaces in one call. */ export declare const gestoriaTemplateItemOutput: z.ZodObject<{ id: z.ZodString; name: z.ZodString; title: z.ZodOptional; description: z.ZodOptional; dueDateOffsetDays: z.ZodOptional; attachmentRequired: z.ZodOptional; variables: z.ZodOptional; defaultValue: z.ZodOptional; }, z.core.$loose>>>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** Result of `gestoria_template_create` — minimal handle for chaining. */ export declare const gestoriaTemplateCreateResultOutput: z.ZodObject<{ templateId: z.ZodString; }, z.core.$loose>; /** * Result of `gestoria_template_bulk_send` — per-client outcome summary. * Mirrors callable `gestoriaBulkSendRequests` shape (Frihet-ERP PR #383). */ export declare const gestoriaBulkSendResultOutput: z.ZodObject<{ success: z.ZodNumber; failed: z.ZodArray; }, z.core.$loose>>; totalDuration: z.ZodOptional; }, z.core.$loose>; /** * Cross-client aging report — totals per overdue bucket + per-workspace * breakdown + top-N overdue invoices. Returned by `gestoria_aging_consolidated`. */ export declare const gestoriaAgingConsolidatedOutput: z.ZodObject<{ totals: z.ZodObject<{ current: z.ZodNumber; "30_60": z.ZodNumber; "60_90": z.ZodNumber; "90_plus": z.ZodNumber; }, z.core.$loose>; byWorkspace: z.ZodArray; current: z.ZodOptional; "30_60": z.ZodOptional; "60_90": z.ZodOptional; "90_plus": z.ZodOptional; total: z.ZodOptional; }, z.core.$loose>>; topOverdue: z.ZodArray; clientName: z.ZodOptional; amountDue: z.ZodOptional; daysOverdue: z.ZodOptional; dueDate: z.ZodOptional; }, z.core.$loose>>; generatedAt: z.ZodOptional; }, z.core.$loose>; /** Leave/PTO request — backend `/v1/leaves`. */ export declare const leaveRequestItemOutput: z.ZodObject<{ id: z.ZodString; employeeId: z.ZodOptional; type: z.ZodOptional; startDate: z.ZodOptional; endDate: z.ZodOptional; durationDays: z.ZodOptional; status: z.ZodOptional>; reason: z.ZodOptional; decisionReason: z.ZodOptional; decidedAt: z.ZodOptional; decidedBy: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** Attendance / time-entry record — backend `/v1/time-entries`. */ export declare const attendanceEntryItemOutput: z.ZodObject<{ id: z.ZodString; employeeId: z.ZodOptional; clockInAt: z.ZodOptional; clockOutAt: z.ZodOptional; durationMinutes: z.ZodOptional; mood: z.ZodOptional; location: z.ZodOptional; status: z.ZodOptional>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** Exact ERP DTO for `GET /v1/time-entries/overtime`. */ export declare const overtimeReportOutput: z.ZodObject<{ period: z.ZodString; employeeId: z.ZodNullable; recordCount: z.ZodNumber; dailyOvertime: z.ZodArray>; weeklyOvertime: z.ZodArray>; monthlyTotal: z.ZodObject<{ workedMinutes: z.ZodNumber; overtimeMinutes: z.ZodNumber; regularMinutes: z.ZodNumber; }, z.core.$strip>; annualOvertimeHours: z.ZodNumber; alerts: z.ZodArray; severity: z.ZodEnum<{ warning: "warning"; critical: "critical"; }>; message: z.ZodString; date: z.ZodString; }, z.core.$strip>>; data: z.ZodOptional; meta: z.ZodOptional; totalRegularHours: z.ZodOptional; totalOvertimeHours: z.ZodOptional; estimatedCostEur: z.ZodOptional; byEmployee: z.ZodOptional; generatedAt: z.ZodOptional; }, z.core.$loose>; /** Anomaly detection record — backend `/v1/anomalies`. */ export declare const anomalyItemOutput: z.ZodObject<{ id: z.ZodString; type: z.ZodOptional; severity: z.ZodOptional>; subjectId: z.ZodOptional; description: z.ZodOptional; detectedAt: z.ZodOptional; resolvedAt: z.ZodOptional; status: z.ZodOptional>; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** Webhook test result — backend `/v1/webhooks/:id/test`. */ export declare const webhookTestResultOutput: z.ZodObject<{ webhookId: z.ZodString; delivered: z.ZodBoolean; statusCode: z.ZodOptional; responseTimeMs: z.ZodOptional; eventType: z.ZodOptional; attemptedAt: z.ZodOptional; error: z.ZodOptional; }, z.core.$loose>; /** Exact normalized dataset DTO from `GET /v1/payroll/prep/export`. */ export declare const payrollExportOutput: z.ZodObject<{ month: z.ZodString; format: z.ZodEnum<{ a3: "a3"; contasol: "contasol"; sage: "sage"; siltra: "siltra"; }>; employees: z.ZodArray; categoriaProfesional: z.ZodNullable; prorrateoPagasExtras: z.ZodNullable; formaPago: z.ZodEnum<{ transferencia: "transferencia"; efectivo: "efectivo"; cheque: "cheque"; }>; iban: z.ZodNullable; }, z.core.$strip>>; summary: z.ZodObject<{ exportedCount: z.ZodNumber; skippedNotReady: z.ZodNumber; totalGrossAnnual: z.ZodNumber; }, z.core.$strip>; data: z.ZodOptional; meta: z.ZodOptional; fileUrl: z.ZodOptional; filename: z.ZodOptional; rowCount: z.ZodOptional; generatedAt: z.ZodOptional; }, z.core.$loose>; /** Exact readiness DTO from `GET /v1/payroll/prep/employees`. */ export declare const payrollChecklistOutput: z.ZodObject<{ month: z.ZodString; employees: z.ZodArray; hasPayrollProfile: z.ZodBoolean; ready: z.ZodBoolean; missingFields: z.ZodArray>; reviewedForMonth: z.ZodNullable; reviewedThisMonth: z.ZodBoolean; reviewedAt: z.ZodNullable; }, z.core.$strip>>; summary: z.ZodObject<{ total: z.ZodNumber; ready: z.ZodNumber; notReady: z.ZodNumber; reviewedThisMonth: z.ZodNumber; }, z.core.$strip>; data: z.ZodOptional; meta: z.ZodOptional; totalEmployees: z.ZodOptional; readyEmployees: z.ZodOptional; missingEmployees: z.ZodOptional; generatedAt: z.ZodOptional; }, z.core.$loose>; /** Onboarding workspace state — backend `/v1/onboarding/status`. */ export declare const onboardingStatusOutput: z.ZodObject<{ workspaceId: z.ZodOptional; persona: z.ZodOptional>; completedSteps: z.ZodOptional>; pendingSteps: z.ZodOptional>; percentComplete: z.ZodOptional; startedAt: z.ZodOptional; completedAt: z.ZodOptional; }, z.core.$loose>; /** Onboarding persona update result. */ export declare const onboardingPersonaResultOutput: z.ZodObject<{ workspaceId: z.ZodOptional; persona: z.ZodEnum<{ autonomo: "autonomo"; empresa: "empresa"; agencia: "agencia"; gestoria: "gestoria"; }>; updatedAt: z.ZodOptional; }, z.core.$loose>; /** * Documented RBAC-model snapshot — backend `/v1/permissions/matrix`. * This is not an exhaustive report of runtime authorization or Firestore rules. */ export declare const permissionsMatrixOutput: z.ZodObject<{ roles: z.ZodArray>; resources: z.ZodArray>; actions: z.ZodArray>; legacyAliases: z.ZodRecord>; matrix: z.ZodObject<{ owner: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; admin: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; manager: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; sales: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; accountant: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; employee: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; viewer: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; }, z.core.$strict>; source: z.ZodString; }, z.core.$loose>; /** * Caller's RBAC-model row and API-key scope state — backend `/v1/permissions/me`. * Known denials are intentionally non-exhaustive; a backend 403 is authoritative. */ export declare const permissionsMeOutput: z.ZodObject<{ role: z.ZodEnum<{ owner: "owner"; admin: "admin"; accountant: "accountant"; viewer: "viewer"; manager: "manager"; sales: "sales"; employee: "employee"; }>; isOwner: z.ZodBoolean; resources: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; scopes: z.ZodArray; legacyFieldSemantics: z.ZodObject<{ resources: z.ZodLiteral<"rbacResources">; scopes: z.ZodLiteral<"rbacCapabilities">; }, z.core.$strip>; rbac: z.ZodObject<{ role: z.ZodEnum<{ owner: "owner"; admin: "admin"; accountant: "accountant"; viewer: "viewer"; manager: "manager"; sales: "sales"; employee: "employee"; }>; isOwner: z.ZodBoolean; resources: z.ZodObject<{ workspace: z.ZodOptional>>; invoices: z.ZodOptional>>; quotes: z.ZodOptional>>; expenses: z.ZodOptional>>; clients: z.ZodOptional>>; products: z.ZodOptional>>; accounting: z.ZodOptional>>; people: z.ZodOptional>>; payroll: z.ZodOptional>>; integrations: z.ZodOptional>>; banking: z.ZodOptional>>; settings: z.ZodOptional>>; audit_log: z.ZodOptional>>; billing: z.ZodOptional>>; }, z.core.$strict>; capabilities: z.ZodArray; }, z.core.$strip>; apiKeyScopes: z.ZodArray; apiKeyUnrestricted: z.ZodBoolean; denied: z.ZodObject<{ einvoice: z.ZodBoolean; }, z.core.$strip>; deniedSemantics: z.ZodString; notIncluded: z.ZodArray>; }, z.core.$loose>; /** Legacy demo/write result retained for period_close and period_reopen only. */ export declare const periodStatusOutput: z.ZodObject<{ id: z.ZodString; type: z.ZodOptional>; status: z.ZodOptional>; startDate: z.ZodOptional; endDate: z.ZodOptional; closedAt: z.ZodOptional; closedBy: z.ZodOptional; reopenedAt: z.ZodOptional; reopenReason: z.ZodOptional; createdAt: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$loose>; /** Exact ERP DTO for `GET /v1/periods/current` and `GET /v1/periods/YYYY`. */ export declare const currentPeriodOutput: z.ZodObject<{ fiscalYear: z.ZodString; fiscalYearStart: z.ZodString; status: z.ZodEnum<{ open: "open"; closed: "closed"; }>; dateRange: z.ZodObject<{ from: z.ZodString; to: z.ZodString; }, z.core.$strip>; closing: z.ZodNullable; netIncome: z.ZodNullable; totalIncome: z.ZodNullable; totalExpenses: z.ZodNullable; journalEntries: z.ZodNullable; }, z.core.$strip>>; data: z.ZodOptional; meta: z.ZodOptional; id: z.ZodOptional; type: z.ZodOptional; startDate: z.ZodOptional; endDate: z.ZodOptional; closedAt: z.ZodOptional; closedBy: z.ZodOptional; reopenedAt: z.ZodOptional; reopenReason: z.ZodOptional; generatedAt: z.ZodOptional; }, z.core.$loose>; /** Return type of a tool handler — index signature required by MCP SDK */ interface ToolResult { [x: string]: unknown; content: AnnotatedTextContent[]; structuredContent?: Record; isError?: boolean; } /** * Wraps a tool handler to automatically log execution time, success/failure, * and record metrics. Catches errors and routes them through handleToolError. * * Usage in tool registration files: * ```ts * async ({ id }) => withToolLogging("get_invoice", async () => { * const result = await client.getInvoice(id); * return { content: [getContent(formatRecord("Invoice", result))], structuredContent: result }; * }) * ``` */ export declare function withToolLogging(toolName: string, fn: () => Promise): Promise; export {}; //# sourceMappingURL=shared.d.ts.map