@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,124 @@
1
+ /**
2
+ * MCP Apps UI Resources Registration.
3
+ *
4
+ * Registers UI tools and resources for interactive invoice preview,
5
+ * contact card, and dashboard summary.
6
+ *
7
+ * Uses @modelcontextprotocol/ext-apps SDK for UI resource handling.
8
+ */
9
+ import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server";
10
+ import { z } from "zod";
11
+ import fs from "node:fs/promises";
12
+ import path from "node:path";
13
+ import { logger } from "./logger.js";
14
+ // UI Resource URIs using ui:// scheme
15
+ const INVOICE_PREVIEW_URI = "ui://bexio/invoice-preview.html";
16
+ const CONTACT_CARD_URI = "ui://bexio/contact-card.html";
17
+ const DASHBOARD_URI = "ui://bexio/dashboard.html";
18
+ /**
19
+ * Register MCP Apps UI resources and tools.
20
+ *
21
+ * @param server - McpServer instance
22
+ * @param client - BexioClient for API calls
23
+ */
24
+ export function registerUIResources(server, client) {
25
+ // Path to built UI files (vite outputs to dist/ui/ui/<name>/<name>.html)
26
+ const uiBasePath = path.join(import.meta.dirname, "../dist/ui/ui");
27
+ // ===== INVOICE PREVIEW =====
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ registerAppTool(server, "preview_invoice", {
30
+ title: "Preview Invoice",
31
+ description: "Display an interactive invoice preview with line items, totals, and status",
32
+ inputSchema: { invoice_id: z.number().int().describe("The invoice ID to preview") },
33
+ _meta: { ui: { resourceUri: INVOICE_PREVIEW_URI } },
34
+ }, async (args) => {
35
+ const invoiceId = args.invoice_id;
36
+ logger.debug(`preview_invoice called for invoice ${invoiceId}`);
37
+ const invoice = await client.getInvoice(invoiceId);
38
+ return {
39
+ content: [{ type: "text", text: JSON.stringify(invoice) }],
40
+ };
41
+ });
42
+ registerAppResource(server, INVOICE_PREVIEW_URI, INVOICE_PREVIEW_URI, { mimeType: RESOURCE_MIME_TYPE }, async () => {
43
+ const html = await fs.readFile(path.join(uiBasePath, "invoice-preview/invoice-preview.html"), "utf-8");
44
+ return {
45
+ contents: [{ uri: INVOICE_PREVIEW_URI, mimeType: RESOURCE_MIME_TYPE, text: html }],
46
+ };
47
+ });
48
+ // ===== CONTACT CARD =====
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ registerAppTool(server, "show_contact_card", {
51
+ title: "Show Contact Card",
52
+ description: "Display a formatted contact card with name, contact details, and address",
53
+ inputSchema: { contact_id: z.number().int().describe("The contact ID to display") },
54
+ _meta: { ui: { resourceUri: CONTACT_CARD_URI } },
55
+ }, async (args) => {
56
+ const contactId = args.contact_id;
57
+ logger.debug(`show_contact_card called for contact ${contactId}`);
58
+ const contact = await client.getContact(contactId);
59
+ return {
60
+ content: [{ type: "text", text: JSON.stringify(contact) }],
61
+ };
62
+ });
63
+ registerAppResource(server, CONTACT_CARD_URI, CONTACT_CARD_URI, { mimeType: RESOURCE_MIME_TYPE }, async () => {
64
+ const html = await fs.readFile(path.join(uiBasePath, "contact-card/contact-card.html"), "utf-8");
65
+ return {
66
+ contents: [{ uri: CONTACT_CARD_URI, mimeType: RESOURCE_MIME_TYPE, text: html }],
67
+ };
68
+ });
69
+ // ===== DASHBOARD =====
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ registerAppTool(server, "show_dashboard", {
72
+ title: "Show Dashboard",
73
+ description: "Display a summary dashboard with open invoices, overdue amounts, and recent contacts",
74
+ _meta: { ui: { resourceUri: DASHBOARD_URI } },
75
+ }, async () => {
76
+ logger.debug("show_dashboard called");
77
+ // Fetch dashboard data
78
+ const [openInvoices, overdueInvoices, contacts] = await Promise.all([
79
+ client.getOpenInvoices(),
80
+ client.getOverdueInvoices(),
81
+ client.listContacts({ limit: 5 }),
82
+ ]);
83
+ // Calculate totals
84
+ const openTotal = openInvoices.reduce((sum, inv) => {
85
+ const total = parseFloat(inv.total_gross || "0");
86
+ return sum + total;
87
+ }, 0);
88
+ const overdueTotal = overdueInvoices.reduce((sum, inv) => {
89
+ const total = parseFloat(inv.total_gross || "0");
90
+ return sum + total;
91
+ }, 0);
92
+ // Get currency from first invoice or default to CHF
93
+ const firstInvoice = openInvoices[0];
94
+ const currencyId = firstInvoice?.currency_id || 1;
95
+ const currency = currencyId === 1 ? "CHF" : currencyId === 2 ? "EUR" : "USD";
96
+ // Format recent contacts
97
+ const recentContacts = contacts.map((c) => {
98
+ const contact = c;
99
+ return {
100
+ id: contact.id,
101
+ name_1: contact.name_1,
102
+ name_2: contact.name_2 || null,
103
+ };
104
+ });
105
+ const dashboardData = {
106
+ open_invoices_count: openInvoices.length,
107
+ open_invoices_total: openTotal,
108
+ overdue_count: overdueInvoices.length,
109
+ overdue_total: overdueTotal,
110
+ recent_contacts: recentContacts,
111
+ currency,
112
+ };
113
+ return {
114
+ content: [{ type: "text", text: JSON.stringify(dashboardData) }],
115
+ };
116
+ });
117
+ registerAppResource(server, DASHBOARD_URI, DASHBOARD_URI, { mimeType: RESOURCE_MIME_TYPE }, async () => {
118
+ const html = await fs.readFile(path.join(uiBasePath, "dashboard/dashboard.html"), "utf-8");
119
+ return {
120
+ contents: [{ uri: DASHBOARD_URI, mimeType: RESOURCE_MIME_TYPE, text: html }],
121
+ };
122
+ });
123
+ logger.info("Registered 3 UI tools and 3 UI resources (MCP Apps)");
124
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
@@ -0,0 +1,46 @@
1
+ import { defineConfig } from "vite";
2
+ import { viteSingleFile } from "vite-plugin-singlefile";
3
+ import { resolve } from "path";
4
+ import { readdirSync, existsSync } from "fs";
5
+ // Get list of UI entry points dynamically
6
+ function getUiEntries() {
7
+ const uiDir = resolve(__dirname, "ui");
8
+ if (!existsSync(uiDir))
9
+ return {};
10
+ const entries = {};
11
+ const dirs = readdirSync(uiDir, { withFileTypes: true })
12
+ .filter(d => d.isDirectory());
13
+ for (const dir of dirs) {
14
+ const htmlPath = resolve(uiDir, dir.name, `${dir.name}.html`);
15
+ if (existsSync(htmlPath)) {
16
+ entries[dir.name] = htmlPath;
17
+ }
18
+ }
19
+ return entries;
20
+ }
21
+ export default defineConfig({
22
+ plugins: [
23
+ viteSingleFile({
24
+ // Disable recommended config to allow multiple entry points
25
+ useRecommendedBuildConfig: false,
26
+ removeViteModuleLoader: false,
27
+ deleteInlinedFiles: true,
28
+ }),
29
+ ],
30
+ root: ".",
31
+ base: "./",
32
+ build: {
33
+ outDir: "../dist/ui",
34
+ emptyOutDir: true,
35
+ // Inline all assets
36
+ assetsInlineLimit: () => true,
37
+ // Emit all CSS as single file for inlining
38
+ cssCodeSplit: false,
39
+ // Assets in root, not assets/ subdir
40
+ assetsDir: "",
41
+ rollupOptions: {
42
+ input: getUiEntries(),
43
+ // No inlineDynamicImports since we have multiple entries
44
+ },
45
+ },
46
+ });
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@promptpartner/bexio-mcp-server",
3
+ "version": "2.0.0",
4
+ "description": "Model Context Protocol server for Bexio API integration",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "bexio-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc && npm run build:ui",
17
+ "build:ui": "node -e \"const fs=require('fs'); if(fs.existsSync('ui')){const{execSync}=require('child_process');execSync('npx vite build',{stdio:'inherit'})}else{console.log('Skipping UI build - ui/ not found')}\"",
18
+ "dev": "tsx watch src/index.ts",
19
+ "dev:ui": "vite build --watch",
20
+ "start": "node dist/index.js",
21
+ "test": "vitest",
22
+ "type-check": "tsc --noEmit",
23
+ "clean": "node -e \"const fs=require('fs'); if(fs.existsSync('dist')){fs.rmSync('dist',{recursive:true}); console.log('Cleaned dist/')}\"",
24
+ "prebuild": "npm run clean",
25
+ "pack:mcpb": "npm run build && npm run copy:bundle && cd .. && mcpb pack",
26
+ "copy:bundle": "node -e \"const fs=require('fs'); const path=require('path'); function copyDir(src,dest){fs.mkdirSync(dest,{recursive:true});fs.readdirSync(src).forEach(f=>{const srcPath=path.join(src,f);const destPath=path.join(dest,f);fs.statSync(srcPath).isDirectory()?copyDir(srcPath,destPath):fs.copyFileSync(srcPath,destPath)})} const rootDist=path.join(__dirname,'..','dist'); if(fs.existsSync(rootDist))fs.rmSync(rootDist,{recursive:true}); copyDir('dist',rootDist); console.log('Copied dist/ to root for MCPB bundling')\"",
27
+ "validate:mcpb": "cd .. && mcpb validate manifest.json",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "author": {
31
+ "name": "Lukas Hertig",
32
+ "email": "lukas@promptpartner.ai"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/promptpartner/bexio-mcp-server.git"
37
+ },
38
+ "homepage": "https://github.com/promptpartner/bexio-mcp-server#readme",
39
+ "bugs": {
40
+ "url": "https://github.com/promptpartner/bexio-mcp-server/issues"
41
+ },
42
+ "keywords": [
43
+ "mcp",
44
+ "bexio",
45
+ "api",
46
+ "typescript",
47
+ "model-context-protocol",
48
+ "claude",
49
+ "accounting",
50
+ "invoices",
51
+ "swiss"
52
+ ],
53
+ "license": "MIT",
54
+ "dependencies": {
55
+ "@modelcontextprotocol/sdk": "^1.25.2",
56
+ "@modelcontextprotocol/ext-apps": "^1.0.1",
57
+ "axios": "^1.7.0",
58
+ "zod": "3.25.76",
59
+ "dotenv": "^16.3.0",
60
+ "fastify": "^4.28.0",
61
+ "@fastify/cors": "^9.0.0"
62
+ },
63
+ "devDependencies": {
64
+ "@types/node": "^20.8.0",
65
+ "typescript": "^5.5.0",
66
+ "tsx": "^4.0.0",
67
+ "vitest": "^2.0.0",
68
+ "vite": "^6.0.0",
69
+ "vite-plugin-singlefile": "^2.3.0",
70
+ "concurrently": "^8.0.0"
71
+ },
72
+ "engines": {
73
+ "node": ">=18.0.0"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public"
77
+ }
78
+ }