@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,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Bexio MCP Server v2 Entry Point
4
+ *
5
+ * This is the main entry point for the Bexio MCP server.
6
+ * It handles:
7
+ * - Environment variable loading
8
+ * - Command line argument parsing
9
+ * - Server initialization and startup
10
+ * - Dual transport: stdio (Claude Desktop) and http (n8n/remote)
11
+ *
12
+ * IMPORTANT: All logging goes to stderr via logger.ts.
13
+ * stdout is reserved for MCP JSON-RPC protocol messages (stdio mode only).
14
+ */
15
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Bexio MCP Server v2 Entry Point
4
+ *
5
+ * This is the main entry point for the Bexio MCP server.
6
+ * It handles:
7
+ * - Environment variable loading
8
+ * - Command line argument parsing
9
+ * - Server initialization and startup
10
+ * - Dual transport: stdio (Claude Desktop) and http (n8n/remote)
11
+ *
12
+ * IMPORTANT: All logging goes to stderr via logger.ts.
13
+ * stdout is reserved for MCP JSON-RPC protocol messages (stdio mode only).
14
+ */
15
+ import { config } from "dotenv";
16
+ import { BexioMcpServer } from "./server.js";
17
+ import { BexioClient } from "./bexio-client.js";
18
+ import { logger } from "./logger.js";
19
+ import { createHttpServer } from "./transports/http.js";
20
+ // Load environment variables from .env file
21
+ config();
22
+ // Configuration from environment
23
+ const BEXIO_API_TOKEN = process.env["BEXIO_API_TOKEN"];
24
+ const BEXIO_BASE_URL = process.env["BEXIO_BASE_URL"] ?? "https://api.bexio.com/2.0";
25
+ function parseArgs() {
26
+ const args = process.argv.slice(2);
27
+ // Parse --mode
28
+ const modeIndex = args.indexOf("--mode");
29
+ const modeArg = modeIndex !== -1 ? args[modeIndex + 1] : "stdio";
30
+ const mode = modeArg === "http" ? "http" : "stdio";
31
+ // Parse --host (for HTTP mode)
32
+ const hostIndex = args.indexOf("--host");
33
+ const host = hostIndex !== -1 ? args[hostIndex + 1] ?? "0.0.0.0" : "0.0.0.0";
34
+ // Parse --port (for HTTP mode)
35
+ const portIndex = args.indexOf("--port");
36
+ const portStr = portIndex !== -1 ? args[portIndex + 1] : "8000";
37
+ const port = parseInt(portStr, 10) || 8000;
38
+ return { mode, host, port };
39
+ }
40
+ function validateEnvironment() {
41
+ if (!BEXIO_API_TOKEN) {
42
+ logger.error("BEXIO_API_TOKEN environment variable is required");
43
+ logger.error("Set it in your .env file or environment");
44
+ process.exit(1);
45
+ }
46
+ logger.info(`Using Bexio API base URL: ${BEXIO_BASE_URL}`);
47
+ }
48
+ async function main() {
49
+ const { mode, host, port } = parseArgs();
50
+ // Validate environment
51
+ validateEnvironment();
52
+ // Create Bexio client
53
+ const client = new BexioClient({
54
+ baseUrl: BEXIO_BASE_URL,
55
+ apiToken: BEXIO_API_TOKEN,
56
+ });
57
+ if (mode === "stdio") {
58
+ logger.info("Starting in stdio mode (for Claude Desktop)");
59
+ // Create and initialize server with client
60
+ const server = new BexioMcpServer();
61
+ server.initialize(client);
62
+ await server.run();
63
+ }
64
+ else if (mode === "http") {
65
+ logger.info(`Starting in HTTP mode on ${host}:${port} (for n8n/remote access)`);
66
+ // Create HTTP server
67
+ await createHttpServer(client, { host, port });
68
+ // Keep the process alive
69
+ logger.info("HTTP server running. Press Ctrl+C to stop.");
70
+ }
71
+ else {
72
+ logger.error(`Invalid mode: ${mode}. Use 'stdio' or 'http'.`);
73
+ process.exit(1);
74
+ }
75
+ }
76
+ // Run the server
77
+ main().catch((error) => {
78
+ logger.error("Fatal error:", error);
79
+ process.exit(1);
80
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Logger module that ONLY writes to stderr.
3
+ *
4
+ * CRITICAL: MCP protocol uses stdout for JSON-RPC messages.
5
+ * Any non-JSON output to stdout corrupts the protocol.
6
+ * All logging MUST go to stderr via console.error().
7
+ */
8
+ export declare function debug(message: string, ...args: unknown[]): void;
9
+ export declare function info(message: string, ...args: unknown[]): void;
10
+ export declare function warn(message: string, ...args: unknown[]): void;
11
+ export declare function error(message: string, ...args: unknown[]): void;
12
+ export declare const logger: {
13
+ debug: typeof debug;
14
+ info: typeof info;
15
+ warn: typeof warn;
16
+ error: typeof error;
17
+ };
package/dist/logger.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Logger module that ONLY writes to stderr.
3
+ *
4
+ * CRITICAL: MCP protocol uses stdout for JSON-RPC messages.
5
+ * Any non-JSON output to stdout corrupts the protocol.
6
+ * All logging MUST go to stderr via console.error().
7
+ */
8
+ function formatTimestamp() {
9
+ return new Date().toISOString();
10
+ }
11
+ export function debug(message, ...args) {
12
+ console.error(`[DEBUG] ${formatTimestamp()} ${message}`, ...args);
13
+ }
14
+ export function info(message, ...args) {
15
+ console.error(`[INFO] ${formatTimestamp()} ${message}`, ...args);
16
+ }
17
+ export function warn(message, ...args) {
18
+ console.error(`[WARN] ${formatTimestamp()} ${message}`, ...args);
19
+ }
20
+ export function error(message, ...args) {
21
+ console.error(`[ERROR] ${formatTimestamp()} ${message}`, ...args);
22
+ }
23
+ export const logger = {
24
+ debug,
25
+ info,
26
+ warn,
27
+ error,
28
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Bexio MCP Server v2
3
+ *
4
+ * SDK 1.25.2 patterns:
5
+ * - Import from "@modelcontextprotocol/sdk/server/mcp.js"
6
+ * - McpServer.tool() for individual tool registration
7
+ * - Use server.connect(transport) to start
8
+ */
9
+ import { BexioClient } from "./bexio-client.js";
10
+ export declare class BexioMcpServer {
11
+ private server;
12
+ private client;
13
+ constructor();
14
+ /** Initialize with Bexio client and register tools */
15
+ initialize(client: BexioClient): void;
16
+ private registerTools;
17
+ run(): Promise<void>;
18
+ }
package/dist/server.js ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Bexio MCP Server v2
3
+ *
4
+ * SDK 1.25.2 patterns:
5
+ * - Import from "@modelcontextprotocol/sdk/server/mcp.js"
6
+ * - McpServer.tool() for individual tool registration
7
+ * - Use server.connect(transport) to start
8
+ */
9
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { z } from "zod";
12
+ import { logger } from "./logger.js";
13
+ import { getAllToolDefinitions, getHandler } from "./tools/index.js";
14
+ import { formatSuccessResponse, formatErrorResponse, McpError } from "./shared/index.js";
15
+ import { registerUIResources } from "./ui-resources.js";
16
+ const SERVER_NAME = "bexio-mcp-server";
17
+ const SERVER_VERSION = "2.0.0";
18
+ export class BexioMcpServer {
19
+ server;
20
+ client = null;
21
+ constructor() {
22
+ this.server = new McpServer({
23
+ name: SERVER_NAME,
24
+ version: SERVER_VERSION,
25
+ });
26
+ }
27
+ /** Initialize with Bexio client and register tools */
28
+ initialize(client) {
29
+ this.client = client;
30
+ this.registerTools();
31
+ registerUIResources(this.server, client);
32
+ logger.info(`Initialized with ${getAllToolDefinitions().length} tools + 3 UI tools`);
33
+ }
34
+ registerTools() {
35
+ // Register ping tool for SDK validation
36
+ this.server.tool("ping", "Test tool that returns pong - validates SDK integration", {}, async () => {
37
+ logger.debug("ping tool called");
38
+ return {
39
+ content: [{ type: "text", text: "pong" }],
40
+ };
41
+ });
42
+ // Register all domain tools
43
+ const definitions = getAllToolDefinitions();
44
+ for (const def of definitions) {
45
+ const handler = getHandler(def.name);
46
+ if (!handler) {
47
+ logger.warn(`No handler found for tool: ${def.name}`);
48
+ continue;
49
+ }
50
+ // SDK 1.25.2 expects a ZodRawShape (plain object with Zod schemas)
51
+ // Use empty shape and let our handlers do the validation
52
+ this.server.tool(def.name, def.description || "", {}, async (args) => {
53
+ if (!this.client) {
54
+ return formatErrorResponse(McpError.internal("Bexio client not initialized"));
55
+ }
56
+ try {
57
+ const result = await handler(this.client, args);
58
+ return formatSuccessResponse(def.name, result);
59
+ }
60
+ catch (error) {
61
+ if (error instanceof McpError) {
62
+ return formatErrorResponse(error);
63
+ }
64
+ if (error instanceof z.ZodError) {
65
+ return formatErrorResponse(McpError.validation(error.message, { issues: error.issues }));
66
+ }
67
+ return formatErrorResponse(error instanceof Error
68
+ ? error
69
+ : new Error(String(error)));
70
+ }
71
+ });
72
+ }
73
+ logger.info(`Registered ${definitions.length + 1} tools (including ping)`);
74
+ }
75
+ async run() {
76
+ logger.info(`Starting ${SERVER_NAME} v${SERVER_VERSION}`);
77
+ const transport = new StdioServerTransport();
78
+ await this.server.connect(transport);
79
+ logger.info("Server connected to stdio transport");
80
+ }
81
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * McpError class for standardized error handling.
3
+ * Error messages include recovery suggestions for LLM self-correction.
4
+ */
5
+ export type McpErrorCode = "NOT_FOUND" | "VALIDATION_ERROR" | "BEXIO_API_ERROR" | "INTERNAL_ERROR";
6
+ export declare class McpError extends Error {
7
+ readonly code: McpErrorCode;
8
+ readonly details?: Record<string, unknown>;
9
+ readonly statusCode?: number;
10
+ constructor(code: McpErrorCode, message: string, details?: Record<string, unknown>, statusCode?: number);
11
+ /** Resource not found - suggests listing resources first */
12
+ static notFound(resource: string, id: string | number): McpError;
13
+ /** Validation error - includes specific field issues */
14
+ static validation(message: string, details?: Record<string, unknown>): McpError;
15
+ /** Bexio API error - includes status and recovery suggestions */
16
+ static bexioApi(message: string, statusCode?: number, details?: Record<string, unknown>): McpError;
17
+ /** Internal server error */
18
+ static internal(message: string, details?: Record<string, unknown>): McpError;
19
+ /** Convert to plain object for JSON serialization */
20
+ toJSON(): Record<string, unknown>;
21
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * McpError class for standardized error handling.
3
+ * Error messages include recovery suggestions for LLM self-correction.
4
+ */
5
+ export class McpError extends Error {
6
+ code;
7
+ details;
8
+ statusCode;
9
+ constructor(code, message, details, statusCode) {
10
+ super(message);
11
+ this.name = "McpError";
12
+ this.code = code;
13
+ this.details = details;
14
+ this.statusCode = statusCode;
15
+ }
16
+ /** Resource not found - suggests listing resources first */
17
+ static notFound(resource, id) {
18
+ return new McpError("NOT_FOUND", `${resource} with ID ${id} not found. Try listing ${resource.toLowerCase()}s first to find valid IDs.`, { resource, id });
19
+ }
20
+ /** Validation error - includes specific field issues */
21
+ static validation(message, details) {
22
+ return new McpError("VALIDATION_ERROR", `Validation failed: ${message}. Check the required fields and their formats.`, details);
23
+ }
24
+ /** Bexio API error - includes status and recovery suggestions */
25
+ static bexioApi(message, statusCode, details) {
26
+ let suggestion = "";
27
+ if (statusCode === 401) {
28
+ suggestion = " Check that BEXIO_API_TOKEN is valid and not expired.";
29
+ }
30
+ else if (statusCode === 403) {
31
+ suggestion = " The API token may lack permissions for this operation.";
32
+ }
33
+ else if (statusCode === 429) {
34
+ suggestion = " Rate limit exceeded. Wait a moment before retrying.";
35
+ }
36
+ else if (statusCode && statusCode >= 500) {
37
+ suggestion = " Bexio server error. Retry the request in a few seconds.";
38
+ }
39
+ return new McpError("BEXIO_API_ERROR", `Bexio API error: ${message}.${suggestion}`, details, statusCode);
40
+ }
41
+ /** Internal server error */
42
+ static internal(message, details) {
43
+ return new McpError("INTERNAL_ERROR", `Internal error: ${message}. Please report this issue.`, details);
44
+ }
45
+ /** Convert to plain object for JSON serialization */
46
+ toJSON() {
47
+ return {
48
+ code: this.code,
49
+ message: this.message,
50
+ details: this.details,
51
+ statusCode: this.statusCode,
52
+ };
53
+ }
54
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared utilities barrel export.
3
+ */
4
+ export * from "./errors.js";
5
+ export * from "./response.js";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared utilities barrel export.
3
+ */
4
+ export * from "./errors.js";
5
+ export * from "./response.js";
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Response formatting utilities for MCP tool responses.
3
+ * Maintains backward compatibility with v1 format.
4
+ */
5
+ import { McpError } from "./errors.js";
6
+ interface McpContent {
7
+ type: "text";
8
+ text: string;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface McpResponse {
12
+ content: McpContent[];
13
+ isError?: boolean;
14
+ [key: string]: unknown;
15
+ }
16
+ /** Format a successful tool response */
17
+ export declare function formatSuccessResponse(toolName: string, data: unknown, meta?: Record<string, unknown>): McpResponse;
18
+ /** Format an error response */
19
+ export declare function formatErrorResponse(error: McpError | Error): McpResponse;
20
+ /** Format a list response with pagination info */
21
+ export declare function formatListResponse(toolName: string, data: unknown[], hasMore: boolean, meta?: Record<string, unknown>): McpResponse;
22
+ /** Map tool names to response data keys */
23
+ export declare function getDataKey(toolName: string): string;
24
+ export {};
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Response formatting utilities for MCP tool responses.
3
+ * Maintains backward compatibility with v1 format.
4
+ */
5
+ import { McpError } from "./errors.js";
6
+ /** Format a successful tool response */
7
+ export function formatSuccessResponse(toolName, data, meta) {
8
+ const dataKey = getDataKey(toolName);
9
+ const responseMeta = {
10
+ source: "bexio",
11
+ fetched_at: new Date().toISOString(),
12
+ tool: toolName,
13
+ ...meta,
14
+ };
15
+ const responseData = {
16
+ [dataKey]: data,
17
+ meta: responseMeta,
18
+ };
19
+ const completionMarker = "\n\n--- RESPONSE COMPLETE ---";
20
+ return {
21
+ content: [
22
+ {
23
+ type: "text",
24
+ text: JSON.stringify(responseData, null, 2) + completionMarker,
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ /** Format an error response */
30
+ export function formatErrorResponse(error) {
31
+ let errorData;
32
+ if (error instanceof McpError) {
33
+ errorData = error.toJSON();
34
+ }
35
+ else {
36
+ errorData = {
37
+ code: "INTERNAL_ERROR",
38
+ message: error.message,
39
+ };
40
+ }
41
+ const completionMarker = "\n\n--- RESPONSE COMPLETE ---";
42
+ return {
43
+ content: [
44
+ {
45
+ type: "text",
46
+ text: `Error: ${JSON.stringify(errorData, null, 2)}${completionMarker}`,
47
+ },
48
+ ],
49
+ isError: true,
50
+ };
51
+ }
52
+ /** Format a list response with pagination info */
53
+ export function formatListResponse(toolName, data, hasMore, meta) {
54
+ return formatSuccessResponse(toolName, data, {
55
+ count: data.length,
56
+ has_more: hasMore,
57
+ ...meta,
58
+ });
59
+ }
60
+ /** Map tool names to response data keys */
61
+ export function getDataKey(toolName) {
62
+ const mapping = {
63
+ // Contacts
64
+ list_contacts: "contacts",
65
+ get_contact: "contact",
66
+ search_contacts: "contacts",
67
+ advanced_search_contacts: "contacts",
68
+ find_contact_by_number: "contact",
69
+ find_contact_by_name: "contacts",
70
+ update_contact: "contact",
71
+ // Invoices
72
+ list_invoices: "invoices",
73
+ list_all_invoices: "invoices",
74
+ get_invoice: "invoice",
75
+ search_invoices: "invoices",
76
+ search_invoices_by_customer: "invoices",
77
+ create_invoice: "invoice",
78
+ // Orders
79
+ list_orders: "orders",
80
+ get_order: "order",
81
+ create_order: "order",
82
+ search_orders: "orders",
83
+ search_orders_by_customer: "orders",
84
+ // Quotes
85
+ list_quotes: "quotes",
86
+ get_quote: "quote",
87
+ create_quote: "quote",
88
+ search_quotes: "quotes",
89
+ search_quotes_by_customer: "quotes",
90
+ };
91
+ return mapping[toolName] || "data";
92
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Accounting tool definitions.
3
+ * Contains MCP tool metadata for accounting domain.
4
+ * Includes: Accounts, Account Groups, Calendar Years, Business Years, Manual Entries, VAT Periods, Journal
5
+ *
6
+ * 15 tools total covering ACCT-01 through ACCT-07 requirements.
7
+ */
8
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
9
+ export declare const toolDefinitions: Tool[];