@promptpartner/bexio-mcp-server 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/dist/bexio-client.d.ts +350 -0
  4. package/dist/bexio-client.js +1045 -0
  5. package/dist/index.d.ts +15 -0
  6. package/dist/index.js +80 -0
  7. package/dist/logger.d.ts +17 -0
  8. package/dist/logger.js +28 -0
  9. package/dist/server.d.ts +18 -0
  10. package/dist/server.js +81 -0
  11. package/dist/shared/errors.d.ts +21 -0
  12. package/dist/shared/errors.js +54 -0
  13. package/dist/shared/index.d.ts +5 -0
  14. package/dist/shared/index.js +5 -0
  15. package/dist/shared/response.d.ts +24 -0
  16. package/dist/shared/response.js +92 -0
  17. package/dist/tools/accounting/definitions.d.ts +9 -0
  18. package/dist/tools/accounting/definitions.js +345 -0
  19. package/dist/tools/accounting/handlers.d.ts +10 -0
  20. package/dist/tools/accounting/handlers.js +121 -0
  21. package/dist/tools/accounting/index.d.ts +16 -0
  22. package/dist/tools/accounting/index.js +16 -0
  23. package/dist/tools/banking/definitions.d.ts +11 -0
  24. package/dist/tools/banking/definitions.js +349 -0
  25. package/dist/tools/banking/handlers.d.ts +9 -0
  26. package/dist/tools/banking/handlers.js +123 -0
  27. package/dist/tools/banking/index.d.ts +6 -0
  28. package/dist/tools/banking/index.js +6 -0
  29. package/dist/tools/company/definitions.d.ts +7 -0
  30. package/dist/tools/company/definitions.js +87 -0
  31. package/dist/tools/company/handlers.d.ts +7 -0
  32. package/dist/tools/company/handlers.js +31 -0
  33. package/dist/tools/company/index.d.ts +6 -0
  34. package/dist/tools/company/index.js +6 -0
  35. package/dist/tools/contacts/definitions.d.ts +6 -0
  36. package/dist/tools/contacts/definitions.js +150 -0
  37. package/dist/tools/contacts/handlers.d.ts +7 -0
  38. package/dist/tools/contacts/handlers.js +40 -0
  39. package/dist/tools/contacts/index.d.ts +6 -0
  40. package/dist/tools/contacts/index.js +5 -0
  41. package/dist/tools/deliveries/definitions.d.ts +6 -0
  42. package/dist/tools/deliveries/definitions.js +67 -0
  43. package/dist/tools/deliveries/handlers.d.ts +7 -0
  44. package/dist/tools/deliveries/handlers.js +28 -0
  45. package/dist/tools/deliveries/index.d.ts +6 -0
  46. package/dist/tools/deliveries/index.js +5 -0
  47. package/dist/tools/files/definitions.d.ts +6 -0
  48. package/dist/tools/files/definitions.js +217 -0
  49. package/dist/tools/files/handlers.d.ts +7 -0
  50. package/dist/tools/files/handlers.js +63 -0
  51. package/dist/tools/files/index.d.ts +6 -0
  52. package/dist/tools/files/index.js +5 -0
  53. package/dist/tools/index.d.ts +19 -0
  54. package/dist/tools/index.js +93 -0
  55. package/dist/tools/invoices/definitions.d.ts +6 -0
  56. package/dist/tools/invoices/definitions.js +147 -0
  57. package/dist/tools/invoices/handlers.d.ts +7 -0
  58. package/dist/tools/invoices/handlers.js +119 -0
  59. package/dist/tools/invoices/index.d.ts +6 -0
  60. package/dist/tools/invoices/index.js +5 -0
  61. package/dist/tools/items/definitions.d.ts +6 -0
  62. package/dist/tools/items/definitions.js +100 -0
  63. package/dist/tools/items/handlers.d.ts +7 -0
  64. package/dist/tools/items/handlers.js +36 -0
  65. package/dist/tools/items/index.d.ts +6 -0
  66. package/dist/tools/items/index.js +5 -0
  67. package/dist/tools/misc/definitions.d.ts +6 -0
  68. package/dist/tools/misc/definitions.js +126 -0
  69. package/dist/tools/misc/handlers.d.ts +7 -0
  70. package/dist/tools/misc/handlers.js +52 -0
  71. package/dist/tools/misc/index.d.ts +6 -0
  72. package/dist/tools/misc/index.js +5 -0
  73. package/dist/tools/orders/definitions.d.ts +6 -0
  74. package/dist/tools/orders/definitions.js +114 -0
  75. package/dist/tools/orders/handlers.d.ts +7 -0
  76. package/dist/tools/orders/handlers.js +62 -0
  77. package/dist/tools/orders/index.d.ts +6 -0
  78. package/dist/tools/orders/index.js +5 -0
  79. package/dist/tools/payments/definitions.d.ts +6 -0
  80. package/dist/tools/payments/definitions.js +74 -0
  81. package/dist/tools/payments/handlers.d.ts +7 -0
  82. package/dist/tools/payments/handlers.js +28 -0
  83. package/dist/tools/payments/index.d.ts +6 -0
  84. package/dist/tools/payments/index.js +5 -0
  85. package/dist/tools/payroll/definitions.d.ts +15 -0
  86. package/dist/tools/payroll/definitions.js +239 -0
  87. package/dist/tools/payroll/handlers.d.ts +14 -0
  88. package/dist/tools/payroll/handlers.js +152 -0
  89. package/dist/tools/payroll/index.d.ts +16 -0
  90. package/dist/tools/payroll/index.js +16 -0
  91. package/dist/tools/projects/definitions.d.ts +7 -0
  92. package/dist/tools/projects/definitions.js +430 -0
  93. package/dist/tools/projects/handlers.d.ts +7 -0
  94. package/dist/tools/projects/handlers.js +127 -0
  95. package/dist/tools/projects/index.d.ts +6 -0
  96. package/dist/tools/projects/index.js +6 -0
  97. package/dist/tools/purchase/definitions.d.ts +6 -0
  98. package/dist/tools/purchase/definitions.js +381 -0
  99. package/dist/tools/purchase/handlers.d.ts +7 -0
  100. package/dist/tools/purchase/handlers.js +120 -0
  101. package/dist/tools/purchase/index.d.ts +7 -0
  102. package/dist/tools/purchase/index.js +6 -0
  103. package/dist/tools/quotes/definitions.d.ts +6 -0
  104. package/dist/tools/quotes/definitions.js +174 -0
  105. package/dist/tools/quotes/handlers.d.ts +7 -0
  106. package/dist/tools/quotes/handlers.js +79 -0
  107. package/dist/tools/quotes/index.d.ts +6 -0
  108. package/dist/tools/quotes/index.js +5 -0
  109. package/dist/tools/reference/definitions.d.ts +7 -0
  110. package/dist/tools/reference/definitions.js +421 -0
  111. package/dist/tools/reference/handlers.d.ts +7 -0
  112. package/dist/tools/reference/handlers.js +161 -0
  113. package/dist/tools/reference/index.d.ts +6 -0
  114. package/dist/tools/reference/index.js +6 -0
  115. package/dist/tools/reminders/definitions.d.ts +6 -0
  116. package/dist/tools/reminders/definitions.js +132 -0
  117. package/dist/tools/reminders/handlers.d.ts +7 -0
  118. package/dist/tools/reminders/handlers.js +43 -0
  119. package/dist/tools/reminders/index.d.ts +6 -0
  120. package/dist/tools/reminders/index.js +5 -0
  121. package/dist/tools/reports/definitions.d.ts +6 -0
  122. package/dist/tools/reports/definitions.js +133 -0
  123. package/dist/tools/reports/handlers.d.ts +7 -0
  124. package/dist/tools/reports/handlers.js +33 -0
  125. package/dist/tools/reports/index.d.ts +6 -0
  126. package/dist/tools/reports/index.js +5 -0
  127. package/dist/tools/timetracking/definitions.d.ts +9 -0
  128. package/dist/tools/timetracking/definitions.js +226 -0
  129. package/dist/tools/timetracking/handlers.d.ts +9 -0
  130. package/dist/tools/timetracking/handlers.js +88 -0
  131. package/dist/tools/timetracking/index.d.ts +6 -0
  132. package/dist/tools/timetracking/index.js +6 -0
  133. package/dist/tools/users/definitions.d.ts +6 -0
  134. package/dist/tools/users/definitions.js +93 -0
  135. package/dist/tools/users/handlers.d.ts +7 -0
  136. package/dist/tools/users/handlers.js +35 -0
  137. package/dist/tools/users/index.d.ts +6 -0
  138. package/dist/tools/users/index.js +5 -0
  139. package/dist/transports/http.d.ts +17 -0
  140. package/dist/transports/http.js +203 -0
  141. package/dist/transports/index.d.ts +4 -0
  142. package/dist/transports/index.js +4 -0
  143. package/dist/types/common.d.ts +32 -0
  144. package/dist/types/common.js +11 -0
  145. package/dist/types/index.d.ts +9 -0
  146. package/dist/types/index.js +11 -0
  147. package/dist/types/schemas/accounting.d.ts +225 -0
  148. package/dist/types/schemas/accounting.js +96 -0
  149. package/dist/types/schemas/banking.d.ts +207 -0
  150. package/dist/types/schemas/banking.js +86 -0
  151. package/dist/types/schemas/company.d.ts +44 -0
  152. package/dist/types/schemas/company.js +23 -0
  153. package/dist/types/schemas/contacts.d.ts +104 -0
  154. package/dist/types/schemas/contacts.js +42 -0
  155. package/dist/types/schemas/deliveries.d.ts +40 -0
  156. package/dist/types/schemas/deliveries.js +22 -0
  157. package/dist/types/schemas/files.d.ts +152 -0
  158. package/dist/types/schemas/files.js +64 -0
  159. package/dist/types/schemas/index.d.ts +24 -0
  160. package/dist/types/schemas/index.js +44 -0
  161. package/dist/types/schemas/invoices.d.ts +594 -0
  162. package/dist/types/schemas/invoices.js +109 -0
  163. package/dist/types/schemas/items.d.ts +153 -0
  164. package/dist/types/schemas/items.js +43 -0
  165. package/dist/types/schemas/misc.d.ts +64 -0
  166. package/dist/types/schemas/misc.js +36 -0
  167. package/dist/types/schemas/orders.d.ts +657 -0
  168. package/dist/types/schemas/orders.js +101 -0
  169. package/dist/types/schemas/payments.d.ts +46 -0
  170. package/dist/types/schemas/payments.js +24 -0
  171. package/dist/types/schemas/payroll.d.ts +146 -0
  172. package/dist/types/schemas/payroll.js +65 -0
  173. package/dist/types/schemas/projects.d.ts +268 -0
  174. package/dist/types/schemas/projects.js +102 -0
  175. package/dist/types/schemas/purchase.d.ts +228 -0
  176. package/dist/types/schemas/purchase.js +114 -0
  177. package/dist/types/schemas/quotes.d.ts +102 -0
  178. package/dist/types/schemas/quotes.js +49 -0
  179. package/dist/types/schemas/reference.d.ts +240 -0
  180. package/dist/types/schemas/reference.js +99 -0
  181. package/dist/types/schemas/reminders.d.ts +76 -0
  182. package/dist/types/schemas/reminders.js +38 -0
  183. package/dist/types/schemas/reports.d.ts +69 -0
  184. package/dist/types/schemas/reports.js +36 -0
  185. package/dist/types/schemas/timetracking.d.ts +150 -0
  186. package/dist/types/schemas/timetracking.js +68 -0
  187. package/dist/types/schemas/users.d.ts +51 -0
  188. package/dist/types/schemas/users.js +27 -0
  189. package/dist/ui/contact-card/mcp-app.d.ts +1 -0
  190. package/dist/ui/contact-card/mcp-app.js +108 -0
  191. package/dist/ui/dashboard/mcp-app.d.ts +1 -0
  192. package/dist/ui/dashboard/mcp-app.js +81 -0
  193. package/dist/ui/invoice-preview/mcp-app.d.ts +1 -0
  194. package/dist/ui/invoice-preview/mcp-app.js +96 -0
  195. package/dist/ui-resources.d.ts +17 -0
  196. package/dist/ui-resources.js +124 -0
  197. package/dist/vite.config.d.ts +2 -0
  198. package/dist/vite.config.js +46 -0
  199. package/package.json +78 -0
@@ -0,0 +1,203 @@
1
+ /**
2
+ * HTTP Transport for Bexio MCP Server.
3
+ * Provides HTTP/REST access for n8n and other remote clients.
4
+ *
5
+ * IMPORTANT: All logging uses logger (stderr), stdout reserved for nothing in HTTP mode.
6
+ */
7
+ import Fastify from "fastify";
8
+ import cors from "@fastify/cors";
9
+ import { logger } from "../logger.js";
10
+ import { getAllToolDefinitions, createHandlerRegistry } from "../tools/index.js";
11
+ /**
12
+ * Creates an HTTP server for the MCP server.
13
+ * This enables n8n and other HTTP clients to interact with the Bexio API.
14
+ */
15
+ export async function createHttpServer(client, options) {
16
+ const { host, port } = options;
17
+ // Create handler registry
18
+ const handlerRegistry = createHandlerRegistry(client);
19
+ const app = Fastify({
20
+ logger: false, // We use our own logger
21
+ });
22
+ // Register CORS for browser/n8n access
23
+ await app.register(cors, {
24
+ origin: true,
25
+ });
26
+ logger.info("HTTP server initializing...");
27
+ // Health check endpoint
28
+ app.get("/", async () => {
29
+ return {
30
+ status: "running",
31
+ server: "bexio-mcp-server",
32
+ version: "2.0.0",
33
+ mode: "http",
34
+ };
35
+ });
36
+ // List tools endpoint (GET for simplicity)
37
+ app.get("/tools", async () => {
38
+ const tools = getAllToolDefinitions();
39
+ return { tools, count: tools.length };
40
+ });
41
+ // MCP-style JSON-RPC endpoint
42
+ app.post("/mcp", async (request, reply) => {
43
+ const body = request.body;
44
+ // Handle batch requests
45
+ if (Array.isArray(body)) {
46
+ const results = await Promise.all(body.map((req) => handleJsonRpcRequest(req, handlerRegistry)));
47
+ return results;
48
+ }
49
+ // Handle single request
50
+ return handleJsonRpcRequest(body, handlerRegistry);
51
+ });
52
+ // Direct tool call endpoint (simpler than JSON-RPC)
53
+ app.post("/tools/call", async (request, reply) => {
54
+ const toolName = request.body?.name;
55
+ try {
56
+ const { name, arguments: args = {} } = request.body;
57
+ if (!name) {
58
+ return reply.code(400).send({ error: "Tool name is required" });
59
+ }
60
+ const handler = handlerRegistry.get(name);
61
+ if (!handler) {
62
+ return reply.code(404).send({ error: `Unknown tool: ${name}` });
63
+ }
64
+ const result = await handler(args);
65
+ return {
66
+ success: true,
67
+ data: result,
68
+ tool: name,
69
+ timestamp: new Date().toISOString(),
70
+ };
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : String(error);
74
+ return reply.code(500).send({
75
+ success: false,
76
+ error: errorMessage,
77
+ tool: toolName || "unknown",
78
+ timestamp: new Date().toISOString(),
79
+ });
80
+ }
81
+ });
82
+ // n8n-specific endpoint for easier integration
83
+ app.post("/n8n/call", async (request, reply) => {
84
+ try {
85
+ const { tool, params = {} } = request.body;
86
+ if (!tool) {
87
+ return reply.code(400).send({ error: "Tool name is required" });
88
+ }
89
+ const handler = handlerRegistry.get(tool);
90
+ if (!handler) {
91
+ return reply.code(404).send({ error: `Unknown tool: ${tool}` });
92
+ }
93
+ const result = await handler(params);
94
+ return {
95
+ success: true,
96
+ data: result,
97
+ tool,
98
+ timestamp: new Date().toISOString(),
99
+ };
100
+ }
101
+ catch (error) {
102
+ const errorMessage = error instanceof Error ? error.message : String(error);
103
+ return reply.code(500).send({
104
+ success: false,
105
+ error: errorMessage,
106
+ tool: request.body?.tool || "unknown",
107
+ timestamp: new Date().toISOString(),
108
+ });
109
+ }
110
+ });
111
+ // Start server
112
+ try {
113
+ await app.listen({ host, port });
114
+ logger.info(`HTTP server listening on ${host}:${port}`);
115
+ logger.info("Available endpoints:");
116
+ logger.info(" GET / - Health check");
117
+ logger.info(" GET /tools - List all tools");
118
+ logger.info(" POST /mcp - JSON-RPC endpoint");
119
+ logger.info(" POST /tools/call - Direct tool call");
120
+ logger.info(" POST /n8n/call - n8n-friendly endpoint");
121
+ }
122
+ catch (error) {
123
+ logger.error("Failed to start HTTP server:", error);
124
+ throw error;
125
+ }
126
+ return app;
127
+ }
128
+ /**
129
+ * Handle a JSON-RPC request.
130
+ */
131
+ async function handleJsonRpcRequest(request, handlerRegistry) {
132
+ const { id, method, params } = request;
133
+ try {
134
+ // Handle MCP protocol methods
135
+ if (method === "initialize") {
136
+ return {
137
+ jsonrpc: "2.0",
138
+ id,
139
+ result: {
140
+ protocolVersion: "2024-11-05",
141
+ capabilities: { tools: {} },
142
+ serverInfo: {
143
+ name: "bexio-mcp-server",
144
+ version: "2.0.0",
145
+ },
146
+ },
147
+ };
148
+ }
149
+ if (method === "tools/list") {
150
+ const tools = getAllToolDefinitions();
151
+ return {
152
+ jsonrpc: "2.0",
153
+ id,
154
+ result: { tools },
155
+ };
156
+ }
157
+ if (method === "tools/call") {
158
+ const callParams = params;
159
+ if (!callParams?.name) {
160
+ return {
161
+ jsonrpc: "2.0",
162
+ id,
163
+ error: { code: -32602, message: "Invalid params: name is required" },
164
+ };
165
+ }
166
+ const handler = handlerRegistry.get(callParams.name);
167
+ if (!handler) {
168
+ return {
169
+ jsonrpc: "2.0",
170
+ id,
171
+ error: { code: -32601, message: `Unknown tool: ${callParams.name}` },
172
+ };
173
+ }
174
+ const result = await handler(callParams.arguments ?? {});
175
+ return {
176
+ jsonrpc: "2.0",
177
+ id,
178
+ result: {
179
+ content: [
180
+ {
181
+ type: "text",
182
+ text: JSON.stringify(result, null, 2),
183
+ },
184
+ ],
185
+ },
186
+ };
187
+ }
188
+ // Unknown method
189
+ return {
190
+ jsonrpc: "2.0",
191
+ id,
192
+ error: { code: -32601, message: `Method not found: ${method}` },
193
+ };
194
+ }
195
+ catch (error) {
196
+ const errorMessage = error instanceof Error ? error.message : String(error);
197
+ return {
198
+ jsonrpc: "2.0",
199
+ id,
200
+ error: { code: -32603, message: errorMessage },
201
+ };
202
+ }
203
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Transports barrel export.
3
+ */
4
+ export { createHttpServer, type HttpServerOptions } from "./http.js";
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Transports barrel export.
3
+ */
4
+ export { createHttpServer } from "./http.js";
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Common types shared across all domains.
3
+ * Keep this file under 50 lines.
4
+ */
5
+ import { z } from "zod";
6
+ export interface BexioConfig {
7
+ baseUrl: string;
8
+ apiToken: string;
9
+ }
10
+ export interface PaginationParams {
11
+ limit?: number;
12
+ offset?: number;
13
+ }
14
+ export interface BexioApiResponse<T = unknown> {
15
+ data?: T;
16
+ error?: string;
17
+ message?: string;
18
+ }
19
+ export declare const SearchCriteriaSchema: z.ZodObject<{
20
+ field: z.ZodString;
21
+ value: z.ZodString;
22
+ criteria: z.ZodDefault<z.ZodString>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ field: string;
25
+ value: string;
26
+ criteria: string;
27
+ }, {
28
+ field: string;
29
+ value: string;
30
+ criteria?: string | undefined;
31
+ }>;
32
+ export type SearchCriteria = z.infer<typeof SearchCriteriaSchema>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Common types shared across all domains.
3
+ * Keep this file under 50 lines.
4
+ */
5
+ import { z } from "zod";
6
+ // Search criteria for advanced searches
7
+ export const SearchCriteriaSchema = z.object({
8
+ field: z.string().min(1, "Field is required"),
9
+ value: z.string().min(1, "Value is required"),
10
+ criteria: z.string().default("like"),
11
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Types barrel export.
3
+ * Single import point for all types in the project.
4
+ *
5
+ * Usage:
6
+ * import { BexioConfig, ListContactsParamsSchema } from "./types/index.js";
7
+ */
8
+ export * from "./common.js";
9
+ export * from "./schemas/index.js";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Types barrel export.
3
+ * Single import point for all types in the project.
4
+ *
5
+ * Usage:
6
+ * import { BexioConfig, ListContactsParamsSchema } from "./types/index.js";
7
+ */
8
+ // Common types and interfaces
9
+ export * from "./common.js";
10
+ // All domain schemas
11
+ export * from "./schemas/index.js";
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Accounting Zod schemas and types.
3
+ * Domain: Accounting (Accounts, Account Groups, Calendar Years, Business Years, Manual Entries, VAT Periods, Journal)
4
+ *
5
+ * Manual entries use flat MCP parameters - handlers transform to nested Bexio API structure.
6
+ * Bexio validates double-entry rules server-side (debits must equal credits).
7
+ */
8
+ import { z } from "zod";
9
+ export declare const ListAccountsParamsSchema: z.ZodObject<{
10
+ limit: z.ZodDefault<z.ZodNumber>;
11
+ offset: z.ZodDefault<z.ZodNumber>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ limit: number;
14
+ offset: number;
15
+ }, {
16
+ limit?: number | undefined;
17
+ offset?: number | undefined;
18
+ }>;
19
+ export type ListAccountsParams = z.infer<typeof ListAccountsParamsSchema>;
20
+ export declare const GetAccountParamsSchema: z.ZodObject<{
21
+ account_id: z.ZodNumber;
22
+ }, "strip", z.ZodTypeAny, {
23
+ account_id: number;
24
+ }, {
25
+ account_id: number;
26
+ }>;
27
+ export type GetAccountParams = z.infer<typeof GetAccountParamsSchema>;
28
+ export declare const CreateAccountParamsSchema: z.ZodObject<{
29
+ account_no: z.ZodNumber;
30
+ name: z.ZodString;
31
+ account_group_id: z.ZodNumber;
32
+ is_active: z.ZodDefault<z.ZodBoolean>;
33
+ tax_id: z.ZodOptional<z.ZodNumber>;
34
+ }, "strip", z.ZodTypeAny, {
35
+ name: string;
36
+ account_no: number;
37
+ account_group_id: number;
38
+ is_active: boolean;
39
+ tax_id?: number | undefined;
40
+ }, {
41
+ name: string;
42
+ account_no: number;
43
+ account_group_id: number;
44
+ tax_id?: number | undefined;
45
+ is_active?: boolean | undefined;
46
+ }>;
47
+ export type CreateAccountParams = z.infer<typeof CreateAccountParamsSchema>;
48
+ export declare const SearchAccountsParamsSchema: z.ZodObject<{
49
+ search_criteria: z.ZodArray<z.ZodObject<{
50
+ field: z.ZodString;
51
+ value: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
52
+ criteria: z.ZodOptional<z.ZodString>;
53
+ }, "strip", z.ZodTypeAny, {
54
+ field: string;
55
+ value: string | number | boolean;
56
+ criteria?: string | undefined;
57
+ }, {
58
+ field: string;
59
+ value: string | number | boolean;
60
+ criteria?: string | undefined;
61
+ }>, "many">;
62
+ }, "strip", z.ZodTypeAny, {
63
+ search_criteria: {
64
+ field: string;
65
+ value: string | number | boolean;
66
+ criteria?: string | undefined;
67
+ }[];
68
+ }, {
69
+ search_criteria: {
70
+ field: string;
71
+ value: string | number | boolean;
72
+ criteria?: string | undefined;
73
+ }[];
74
+ }>;
75
+ export type SearchAccountsParams = z.infer<typeof SearchAccountsParamsSchema>;
76
+ export declare const ListAccountGroupsParamsSchema: z.ZodObject<{
77
+ limit: z.ZodDefault<z.ZodNumber>;
78
+ offset: z.ZodDefault<z.ZodNumber>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ limit: number;
81
+ offset: number;
82
+ }, {
83
+ limit?: number | undefined;
84
+ offset?: number | undefined;
85
+ }>;
86
+ export type ListAccountGroupsParams = z.infer<typeof ListAccountGroupsParamsSchema>;
87
+ export declare const ListCalendarYearsParamsSchema: z.ZodObject<{
88
+ limit: z.ZodDefault<z.ZodNumber>;
89
+ offset: z.ZodDefault<z.ZodNumber>;
90
+ }, "strip", z.ZodTypeAny, {
91
+ limit: number;
92
+ offset: number;
93
+ }, {
94
+ limit?: number | undefined;
95
+ offset?: number | undefined;
96
+ }>;
97
+ export type ListCalendarYearsParams = z.infer<typeof ListCalendarYearsParamsSchema>;
98
+ export declare const GetCalendarYearParamsSchema: z.ZodObject<{
99
+ year_id: z.ZodNumber;
100
+ }, "strip", z.ZodTypeAny, {
101
+ year_id: number;
102
+ }, {
103
+ year_id: number;
104
+ }>;
105
+ export type GetCalendarYearParams = z.infer<typeof GetCalendarYearParamsSchema>;
106
+ export declare const ListBusinessYearsParamsSchema: z.ZodObject<{
107
+ limit: z.ZodDefault<z.ZodNumber>;
108
+ offset: z.ZodDefault<z.ZodNumber>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ limit: number;
111
+ offset: number;
112
+ }, {
113
+ limit?: number | undefined;
114
+ offset?: number | undefined;
115
+ }>;
116
+ export type ListBusinessYearsParams = z.infer<typeof ListBusinessYearsParamsSchema>;
117
+ export declare const ListManualEntriesParamsSchema: z.ZodObject<{
118
+ limit: z.ZodDefault<z.ZodNumber>;
119
+ offset: z.ZodDefault<z.ZodNumber>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ limit: number;
122
+ offset: number;
123
+ }, {
124
+ limit?: number | undefined;
125
+ offset?: number | undefined;
126
+ }>;
127
+ export type ListManualEntriesParams = z.infer<typeof ListManualEntriesParamsSchema>;
128
+ export declare const GetManualEntryParamsSchema: z.ZodObject<{
129
+ entry_id: z.ZodNumber;
130
+ }, "strip", z.ZodTypeAny, {
131
+ entry_id: number;
132
+ }, {
133
+ entry_id: number;
134
+ }>;
135
+ export type GetManualEntryParams = z.infer<typeof GetManualEntryParamsSchema>;
136
+ /**
137
+ * Schema for creating a manual journal entry.
138
+ * Uses FLAT parameters for MCP interface - handler transforms to nested entries array.
139
+ * Bexio validates that debits equal credits server-side.
140
+ */
141
+ export declare const CreateManualEntryParamsSchema: z.ZodObject<{
142
+ type: z.ZodDefault<z.ZodLiteral<"manual_single_entry">>;
143
+ date: z.ZodString;
144
+ debit_account_id: z.ZodNumber;
145
+ credit_account_id: z.ZodNumber;
146
+ amount: z.ZodNumber;
147
+ description: z.ZodString;
148
+ reference_nr: z.ZodOptional<z.ZodString>;
149
+ tax_id: z.ZodOptional<z.ZodNumber>;
150
+ tax_account_id: z.ZodOptional<z.ZodNumber>;
151
+ currency_id: z.ZodOptional<z.ZodNumber>;
152
+ currency_factor: z.ZodDefault<z.ZodNumber>;
153
+ }, "strip", z.ZodTypeAny, {
154
+ type: "manual_single_entry";
155
+ date: string;
156
+ amount: number;
157
+ description: string;
158
+ debit_account_id: number;
159
+ credit_account_id: number;
160
+ currency_factor: number;
161
+ tax_id?: number | undefined;
162
+ currency_id?: number | undefined;
163
+ reference_nr?: string | undefined;
164
+ tax_account_id?: number | undefined;
165
+ }, {
166
+ date: string;
167
+ amount: number;
168
+ description: string;
169
+ debit_account_id: number;
170
+ credit_account_id: number;
171
+ type?: "manual_single_entry" | undefined;
172
+ tax_id?: number | undefined;
173
+ currency_id?: number | undefined;
174
+ reference_nr?: string | undefined;
175
+ tax_account_id?: number | undefined;
176
+ currency_factor?: number | undefined;
177
+ }>;
178
+ export type CreateManualEntryParams = z.infer<typeof CreateManualEntryParamsSchema>;
179
+ export declare const UpdateManualEntryParamsSchema: z.ZodObject<{
180
+ entry_id: z.ZodNumber;
181
+ entry_data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
182
+ }, "strip", z.ZodTypeAny, {
183
+ entry_id: number;
184
+ entry_data: Record<string, unknown>;
185
+ }, {
186
+ entry_id: number;
187
+ entry_data: Record<string, unknown>;
188
+ }>;
189
+ export type UpdateManualEntryParams = z.infer<typeof UpdateManualEntryParamsSchema>;
190
+ export declare const DeleteManualEntryParamsSchema: z.ZodObject<{
191
+ entry_id: z.ZodNumber;
192
+ }, "strip", z.ZodTypeAny, {
193
+ entry_id: number;
194
+ }, {
195
+ entry_id: number;
196
+ }>;
197
+ export type DeleteManualEntryParams = z.infer<typeof DeleteManualEntryParamsSchema>;
198
+ export declare const ListVatPeriodsParamsSchema: z.ZodObject<{
199
+ limit: z.ZodDefault<z.ZodNumber>;
200
+ offset: z.ZodDefault<z.ZodNumber>;
201
+ }, "strip", z.ZodTypeAny, {
202
+ limit: number;
203
+ offset: number;
204
+ }, {
205
+ limit?: number | undefined;
206
+ offset?: number | undefined;
207
+ }>;
208
+ export type ListVatPeriodsParams = z.infer<typeof ListVatPeriodsParamsSchema>;
209
+ export declare const GetJournalParamsSchema: z.ZodObject<{
210
+ start_date: z.ZodOptional<z.ZodString>;
211
+ end_date: z.ZodOptional<z.ZodString>;
212
+ limit: z.ZodDefault<z.ZodNumber>;
213
+ offset: z.ZodDefault<z.ZodNumber>;
214
+ }, "strip", z.ZodTypeAny, {
215
+ limit: number;
216
+ offset: number;
217
+ start_date?: string | undefined;
218
+ end_date?: string | undefined;
219
+ }, {
220
+ limit?: number | undefined;
221
+ offset?: number | undefined;
222
+ start_date?: string | undefined;
223
+ end_date?: string | undefined;
224
+ }>;
225
+ export type GetJournalParams = z.infer<typeof GetJournalParamsSchema>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Accounting Zod schemas and types.
3
+ * Domain: Accounting (Accounts, Account Groups, Calendar Years, Business Years, Manual Entries, VAT Periods, Journal)
4
+ *
5
+ * Manual entries use flat MCP parameters - handlers transform to nested Bexio API structure.
6
+ * Bexio validates double-entry rules server-side (debits must equal credits).
7
+ */
8
+ import { z } from "zod";
9
+ // ===== ACCOUNTS - Chart of Accounts (ACCT-01) =====
10
+ export const ListAccountsParamsSchema = z.object({
11
+ limit: z.number().int().positive().default(100),
12
+ offset: z.number().int().min(0).default(0),
13
+ });
14
+ export const GetAccountParamsSchema = z.object({
15
+ account_id: z.number().int().positive(),
16
+ });
17
+ export const CreateAccountParamsSchema = z.object({
18
+ account_no: z.number().int().positive({ message: "Account number is required and must be positive" }),
19
+ name: z.string().min(1, "Account name is required"),
20
+ account_group_id: z.number().int().positive({ message: "Account group ID is required" }),
21
+ is_active: z.boolean().default(true),
22
+ tax_id: z.number().int().positive().optional(),
23
+ });
24
+ export const SearchAccountsParamsSchema = z.object({
25
+ search_criteria: z.array(z.object({
26
+ field: z.string(),
27
+ value: z.union([z.string(), z.number(), z.boolean()]),
28
+ criteria: z.string().optional(),
29
+ })).min(1, "At least one search criterion is required"),
30
+ });
31
+ // ===== ACCOUNT GROUPS (ACCT-02) =====
32
+ export const ListAccountGroupsParamsSchema = z.object({
33
+ limit: z.number().int().positive().default(100),
34
+ offset: z.number().int().min(0).default(0),
35
+ });
36
+ // ===== CALENDAR YEARS (ACCT-03) =====
37
+ export const ListCalendarYearsParamsSchema = z.object({
38
+ limit: z.number().int().positive().default(100),
39
+ offset: z.number().int().min(0).default(0),
40
+ });
41
+ export const GetCalendarYearParamsSchema = z.object({
42
+ year_id: z.number().int().positive(),
43
+ });
44
+ // ===== BUSINESS YEARS (ACCT-04) =====
45
+ export const ListBusinessYearsParamsSchema = z.object({
46
+ limit: z.number().int().positive().default(100),
47
+ offset: z.number().int().min(0).default(0),
48
+ });
49
+ // ===== MANUAL ENTRIES (ACCT-05) =====
50
+ export const ListManualEntriesParamsSchema = z.object({
51
+ limit: z.number().int().positive().default(100),
52
+ offset: z.number().int().min(0).default(0),
53
+ });
54
+ export const GetManualEntryParamsSchema = z.object({
55
+ entry_id: z.number().int().positive(),
56
+ });
57
+ /**
58
+ * Schema for creating a manual journal entry.
59
+ * Uses FLAT parameters for MCP interface - handler transforms to nested entries array.
60
+ * Bexio validates that debits equal credits server-side.
61
+ */
62
+ export const CreateManualEntryParamsSchema = z.object({
63
+ // Entry type - defaults to manual single entry
64
+ type: z.literal("manual_single_entry").default("manual_single_entry"),
65
+ // Required fields
66
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format"),
67
+ debit_account_id: z.number().int().positive({ message: "Debit account ID is required" }),
68
+ credit_account_id: z.number().int().positive({ message: "Credit account ID is required" }),
69
+ amount: z.number().positive({ message: "Amount must be positive" }),
70
+ description: z.string().min(1, "Description is required"),
71
+ // Optional fields
72
+ reference_nr: z.string().optional(),
73
+ tax_id: z.number().int().positive().optional(),
74
+ tax_account_id: z.number().int().positive().optional(),
75
+ currency_id: z.number().int().positive().optional(),
76
+ currency_factor: z.number().positive().default(1),
77
+ });
78
+ export const UpdateManualEntryParamsSchema = z.object({
79
+ entry_id: z.number().int().positive(),
80
+ entry_data: z.record(z.unknown()),
81
+ });
82
+ export const DeleteManualEntryParamsSchema = z.object({
83
+ entry_id: z.number().int().positive(),
84
+ });
85
+ // ===== VAT PERIODS (ACCT-06) =====
86
+ export const ListVatPeriodsParamsSchema = z.object({
87
+ limit: z.number().int().positive().default(100),
88
+ offset: z.number().int().min(0).default(0),
89
+ });
90
+ // ===== ACCOUNTING JOURNAL (ACCT-07) =====
91
+ export const GetJournalParamsSchema = z.object({
92
+ start_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional(),
93
+ end_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional(),
94
+ limit: z.number().int().positive().default(100),
95
+ offset: z.number().int().min(0).default(0),
96
+ });