@frihet/mcp-server 1.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +271 -0
  3. package/dist/client.d.ts +71 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +225 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/index.d.ts +12 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +52 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/tools/clients.d.ts +7 -0
  12. package/dist/tools/clients.d.ts.map +1 -0
  13. package/dist/tools/clients.js +128 -0
  14. package/dist/tools/clients.js.map +1 -0
  15. package/dist/tools/expenses.d.ts +7 -0
  16. package/dist/tools/expenses.d.ts.map +1 -0
  17. package/dist/tools/expenses.js +126 -0
  18. package/dist/tools/expenses.js.map +1 -0
  19. package/dist/tools/invoices.d.ts +7 -0
  20. package/dist/tools/invoices.d.ts.map +1 -0
  21. package/dist/tools/invoices.js +185 -0
  22. package/dist/tools/invoices.js.map +1 -0
  23. package/dist/tools/products.d.ts +7 -0
  24. package/dist/tools/products.d.ts.map +1 -0
  25. package/dist/tools/products.js +127 -0
  26. package/dist/tools/products.js.map +1 -0
  27. package/dist/tools/quotes.d.ts +7 -0
  28. package/dist/tools/quotes.d.ts.map +1 -0
  29. package/dist/tools/quotes.js +134 -0
  30. package/dist/tools/quotes.js.map +1 -0
  31. package/dist/tools/shared.d.ts +23 -0
  32. package/dist/tools/shared.d.ts.map +1 -0
  33. package/dist/tools/shared.js +60 -0
  34. package/dist/tools/shared.js.map +1 -0
  35. package/dist/tools/webhooks.d.ts +7 -0
  36. package/dist/tools/webhooks.d.ts.map +1 -0
  37. package/dist/tools/webhooks.js +123 -0
  38. package/dist/tools/webhooks.js.map +1 -0
  39. package/dist/types.d.ts +110 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +5 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +60 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.js","sourceRoot":"","sources":["../../src/tools/products.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Quote tools for the Frihet MCP server.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { FrihetClient } from "../client.js";
6
+ export declare function registerQuoteTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=quotes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../../src/tools/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AASjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAuJhF"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Quote tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ const quoteItemSchema = z.object({
7
+ description: z.string().describe("Description of the line item / Descripcion del concepto"),
8
+ quantity: z.number().describe("Quantity / Cantidad"),
9
+ unitPrice: z.number().describe("Unit price in EUR / Precio unitario en EUR"),
10
+ });
11
+ export function registerQuoteTools(server, client) {
12
+ // -- list_quotes --
13
+ server.registerTool("list_quotes", {
14
+ title: "List Quotes",
15
+ description: "List all quotes/estimates with optional pagination. " +
16
+ "Quotes are proposals sent to clients before they become invoices. " +
17
+ "/ Lista todos los presupuestos con paginacion opcional. " +
18
+ "Los presupuestos son propuestas enviadas a clientes antes de facturar.",
19
+ inputSchema: {
20
+ limit: z.number().int().min(1).max(100).optional().describe("Max results (1-100) / Resultados maximos"),
21
+ offset: z.number().int().min(0).optional().describe("Offset / Desplazamiento"),
22
+ },
23
+ }, async ({ limit, offset }) => {
24
+ try {
25
+ const result = await client.listQuotes({ limit, offset });
26
+ return {
27
+ content: [{ type: "text", text: formatPaginatedResponse("quotes", result) }],
28
+ };
29
+ }
30
+ catch (error) {
31
+ return handleToolError(error);
32
+ }
33
+ });
34
+ // -- get_quote --
35
+ server.registerTool("get_quote", {
36
+ title: "Get Quote",
37
+ description: "Get a single quote/estimate by its ID. Returns the full quote with line items and totals. " +
38
+ "/ Obtiene un presupuesto por su ID. Devuelve el presupuesto completo con conceptos y totales.",
39
+ inputSchema: {
40
+ id: z.string().describe("Quote ID / ID del presupuesto"),
41
+ },
42
+ }, async ({ id }) => {
43
+ try {
44
+ const result = await client.getQuote(id);
45
+ return {
46
+ content: [{ type: "text", text: formatRecord("Quote", result) }],
47
+ };
48
+ }
49
+ catch (error) {
50
+ return handleToolError(error);
51
+ }
52
+ });
53
+ // -- create_quote --
54
+ server.registerTool("create_quote", {
55
+ title: "Create Quote",
56
+ description: "Create a new quote/estimate for a client. Requires client name and at least one line item. " +
57
+ "Quotes can later be converted to invoices. " +
58
+ "/ Crea un nuevo presupuesto para un cliente. Requiere nombre del cliente y al menos un concepto. " +
59
+ "Los presupuestos se pueden convertir en facturas despues.",
60
+ inputSchema: {
61
+ clientName: z.string().describe("Client name / Nombre del cliente"),
62
+ items: z
63
+ .array(quoteItemSchema)
64
+ .min(1)
65
+ .describe("Line items / Conceptos del presupuesto"),
66
+ validUntil: z
67
+ .string()
68
+ .optional()
69
+ .describe("Expiry date in ISO 8601 (YYYY-MM-DD) / Fecha de validez"),
70
+ notes: z.string().optional().describe("Additional notes / Notas adicionales"),
71
+ status: z
72
+ .enum(["draft", "sent", "accepted", "rejected", "expired"])
73
+ .optional()
74
+ .describe("Quote status (default: draft) / Estado del presupuesto"),
75
+ },
76
+ }, async (input) => {
77
+ try {
78
+ const result = await client.createQuote(input);
79
+ return {
80
+ content: [{ type: "text", text: formatRecord("Quote created", result) }],
81
+ };
82
+ }
83
+ catch (error) {
84
+ return handleToolError(error);
85
+ }
86
+ });
87
+ // -- update_quote --
88
+ server.registerTool("update_quote", {
89
+ title: "Update Quote",
90
+ description: "Update an existing quote. Only the provided fields will be changed. " +
91
+ "/ Actualiza un presupuesto existente. Solo se modifican los campos proporcionados.",
92
+ inputSchema: {
93
+ id: z.string().describe("Quote ID / ID del presupuesto"),
94
+ clientName: z.string().optional().describe("Client name / Nombre del cliente"),
95
+ items: z.array(quoteItemSchema).min(1).optional().describe("Line items / Conceptos"),
96
+ validUntil: z.string().optional().describe("Expiry date / Fecha de validez"),
97
+ notes: z.string().optional().describe("Notes / Notas"),
98
+ status: z
99
+ .enum(["draft", "sent", "accepted", "rejected", "expired"])
100
+ .optional()
101
+ .describe("Status / Estado"),
102
+ },
103
+ }, async ({ id, ...data }) => {
104
+ try {
105
+ const result = await client.updateQuote(id, data);
106
+ return {
107
+ content: [{ type: "text", text: formatRecord("Quote updated", result) }],
108
+ };
109
+ }
110
+ catch (error) {
111
+ return handleToolError(error);
112
+ }
113
+ });
114
+ // -- delete_quote --
115
+ server.registerTool("delete_quote", {
116
+ title: "Delete Quote",
117
+ description: "Permanently delete a quote by its ID. This action cannot be undone. " +
118
+ "/ Elimina permanentemente un presupuesto por su ID. Esta accion no se puede deshacer.",
119
+ inputSchema: {
120
+ id: z.string().describe("Quote ID / ID del presupuesto"),
121
+ },
122
+ }, async ({ id }) => {
123
+ try {
124
+ await client.deleteQuote(id);
125
+ return {
126
+ content: [{ type: "text", text: `Quote ${id} deleted successfully. / Presupuesto ${id} eliminado correctamente.` }],
127
+ };
128
+ }
129
+ catch (error) {
130
+ return handleToolError(error);
131
+ }
132
+ });
133
+ }
134
+ //# sourceMappingURL=quotes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quotes.js","sourceRoot":"","sources":["../../src/tools/quotes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared utilities for MCP tool handlers.
3
+ */
4
+ import type { PaginatedResponse } from "../types.js";
5
+ /**
6
+ * Maps an error to a user-friendly MCP tool response.
7
+ */
8
+ export declare function handleToolError(error: unknown): {
9
+ content: Array<{
10
+ type: "text";
11
+ text: string;
12
+ }>;
13
+ isError: true;
14
+ };
15
+ /**
16
+ * Formats a paginated API response into readable text.
17
+ */
18
+ export declare function formatPaginatedResponse(resourceName: string, response: PaginatedResponse<Record<string, unknown>>): string;
19
+ /**
20
+ * Formats a single record for display.
21
+ */
22
+ export declare function formatRecord(label: string, record: Record<string, unknown>): string;
23
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAC/C,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,IAAI,CAAC;CACf,CAkCA;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACnD,MAAM,CAkBR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAER"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared utilities for MCP tool handlers.
3
+ */
4
+ import { FrihetApiError } from "../client.js";
5
+ /**
6
+ * Maps an error to a user-friendly MCP tool response.
7
+ */
8
+ export function handleToolError(error) {
9
+ if (error instanceof FrihetApiError) {
10
+ const messages = {
11
+ 400: "Bad request. Check your input parameters. / Solicitud incorrecta. Revisa los parametros.",
12
+ 401: "Authentication failed. Check your API key. / Autenticacion fallida. Revisa tu API key.",
13
+ 403: "Access denied. Your API key does not have permission for this action. / Acceso denegado.",
14
+ 404: "Resource not found. / Recurso no encontrado.",
15
+ 405: "Method not allowed. / Metodo no permitido.",
16
+ 413: "Request body too large (max 1MB). / Cuerpo de la solicitud demasiado grande (max 1MB).",
17
+ 429: "Rate limit exceeded. Try again later. / Limite de peticiones excedido. Intenta mas tarde.",
18
+ 500: "Internal server error. Try again later. / Error interno del servidor.",
19
+ };
20
+ const friendlyMessage = messages[error.statusCode] ?? `API error ${error.statusCode}: ${error.message}`;
21
+ return {
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: `Error: ${friendlyMessage}${error.message ? `\nDetails: ${error.message}` : ""}`,
26
+ },
27
+ ],
28
+ isError: true,
29
+ };
30
+ }
31
+ const message = error instanceof Error ? error.message : "An unexpected error occurred.";
32
+ return {
33
+ content: [{ type: "text", text: `Error: ${message}` }],
34
+ isError: true,
35
+ };
36
+ }
37
+ /**
38
+ * Formats a paginated API response into readable text.
39
+ */
40
+ export function formatPaginatedResponse(resourceName, response) {
41
+ const lines = [
42
+ `Found ${response.total} ${resourceName} (showing ${response.data.length}, offset ${response.offset}):`,
43
+ "",
44
+ ];
45
+ for (const item of response.data) {
46
+ lines.push(JSON.stringify(item, null, 2));
47
+ lines.push("---");
48
+ }
49
+ if (response.total > response.offset + response.data.length) {
50
+ lines.push(`More results available. Use offset=${response.offset + response.data.length} to see the next page.`);
51
+ }
52
+ return lines.join("\n");
53
+ }
54
+ /**
55
+ * Formats a single record for display.
56
+ */
57
+ export function formatRecord(label, record) {
58
+ return `${label}:\n${JSON.stringify(record, null, 2)}`;
59
+ }
60
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAI5C,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,MAAM,QAAQ,GAA2B;YACvC,GAAG,EAAE,0FAA0F;YAC/F,GAAG,EAAE,wFAAwF;YAC7F,GAAG,EAAE,0FAA0F;YAC/F,GAAG,EAAE,8CAA8C;YACnD,GAAG,EAAE,4CAA4C;YACjD,GAAG,EAAE,wFAAwF;YAC7F,GAAG,EAAE,2FAA2F;YAChG,GAAG,EAAE,uEAAuE;SAC7E,CAAC;QAEF,MAAM,eAAe,GACnB,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,aAAa,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QAElF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,UAAU,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;iBACvF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC;IAE3E,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QACtD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAoB,EACpB,QAAoD;IAEpD,MAAM,KAAK,GAAa;QACtB,SAAS,QAAQ,CAAC,KAAK,IAAI,YAAY,aAAa,QAAQ,CAAC,IAAI,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,IAAI;QACvG,EAAE;KACH,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5D,KAAK,CAAC,IAAI,CACR,sCAAsC,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,wBAAwB,CACrG,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,MAA+B;IAE/B,OAAO,GAAG,KAAK,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Webhook management tools for the Frihet MCP server.
3
+ */
4
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { FrihetClient } from "../client.js";
6
+ export declare function registerWebhookTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=webhooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqJlF"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Webhook management tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ export function registerWebhookTools(server, client) {
7
+ // -- list_webhooks --
8
+ server.registerTool("list_webhooks", {
9
+ title: "List Webhooks",
10
+ description: "List all configured webhooks. Webhooks send HTTP POST notifications when events occur in Frihet. " +
11
+ "/ Lista todos los webhooks configurados. Los webhooks envian notificaciones HTTP POST cuando ocurren eventos en Frihet.",
12
+ inputSchema: {
13
+ limit: z.number().int().min(1).max(100).optional().describe("Max results (1-100) / Resultados maximos"),
14
+ offset: z.number().int().min(0).optional().describe("Offset / Desplazamiento"),
15
+ },
16
+ }, async ({ limit, offset }) => {
17
+ try {
18
+ const result = await client.listWebhooks({ limit, offset });
19
+ return {
20
+ content: [{ type: "text", text: formatPaginatedResponse("webhooks", result) }],
21
+ };
22
+ }
23
+ catch (error) {
24
+ return handleToolError(error);
25
+ }
26
+ });
27
+ // -- get_webhook --
28
+ server.registerTool("get_webhook", {
29
+ title: "Get Webhook",
30
+ description: "Get a single webhook configuration by its ID. " +
31
+ "/ Obtiene la configuracion de un webhook por su ID.",
32
+ inputSchema: {
33
+ id: z.string().describe("Webhook ID / ID del webhook"),
34
+ },
35
+ }, async ({ id }) => {
36
+ try {
37
+ const result = await client.getWebhook(id);
38
+ return {
39
+ content: [{ type: "text", text: formatRecord("Webhook", result) }],
40
+ };
41
+ }
42
+ catch (error) {
43
+ return handleToolError(error);
44
+ }
45
+ });
46
+ // -- create_webhook --
47
+ server.registerTool("create_webhook", {
48
+ title: "Create Webhook",
49
+ description: "Register a new webhook endpoint. You must specify the URL to receive notifications " +
50
+ "and which events to subscribe to (e.g. 'invoice.created', 'invoice.paid', 'expense.created'). " +
51
+ "/ Registra un nuevo endpoint de webhook. Debes especificar la URL y los eventos " +
52
+ "a los que suscribirte (ej. 'invoice.created', 'invoice.paid', 'expense.created').",
53
+ inputSchema: {
54
+ url: z.string().url().describe("Webhook endpoint URL / URL del endpoint del webhook"),
55
+ events: z
56
+ .array(z.string())
57
+ .min(1)
58
+ .describe("Events to subscribe to (e.g. ['invoice.created', 'invoice.paid']) " +
59
+ "/ Eventos a suscribir"),
60
+ active: z
61
+ .boolean()
62
+ .optional()
63
+ .describe("Whether the webhook is active (default: true) / Si el webhook esta activo"),
64
+ secret: z
65
+ .string()
66
+ .optional()
67
+ .describe("Signing secret for payload verification / Secreto para verificar las notificaciones"),
68
+ },
69
+ }, async (input) => {
70
+ try {
71
+ const result = await client.createWebhook(input);
72
+ return {
73
+ content: [{ type: "text", text: formatRecord("Webhook created", result) }],
74
+ };
75
+ }
76
+ catch (error) {
77
+ return handleToolError(error);
78
+ }
79
+ });
80
+ // -- update_webhook --
81
+ server.registerTool("update_webhook", {
82
+ title: "Update Webhook",
83
+ description: "Update an existing webhook configuration. Only the provided fields will be changed. " +
84
+ "/ Actualiza la configuracion de un webhook. Solo se modifican los campos proporcionados.",
85
+ inputSchema: {
86
+ id: z.string().describe("Webhook ID / ID del webhook"),
87
+ url: z.string().url().optional().describe("Endpoint URL / URL"),
88
+ events: z.array(z.string()).min(1).optional().describe("Events / Eventos"),
89
+ active: z.boolean().optional().describe("Active / Activo"),
90
+ secret: z.string().optional().describe("Signing secret / Secreto"),
91
+ },
92
+ }, async ({ id, ...data }) => {
93
+ try {
94
+ const result = await client.updateWebhook(id, data);
95
+ return {
96
+ content: [{ type: "text", text: formatRecord("Webhook updated", result) }],
97
+ };
98
+ }
99
+ catch (error) {
100
+ return handleToolError(error);
101
+ }
102
+ });
103
+ // -- delete_webhook --
104
+ server.registerTool("delete_webhook", {
105
+ title: "Delete Webhook",
106
+ description: "Permanently delete a webhook by its ID. Notifications will stop immediately. " +
107
+ "/ Elimina permanentemente un webhook por su ID. Las notificaciones se detendran inmediatamente.",
108
+ inputSchema: {
109
+ id: z.string().describe("Webhook ID / ID del webhook"),
110
+ },
111
+ }, async ({ id }) => {
112
+ try {
113
+ await client.deleteWebhook(id);
114
+ return {
115
+ content: [{ type: "text", text: `Webhook ${id} deleted successfully. / Webhook ${id} eliminado correctamente.` }],
116
+ };
117
+ }
118
+ catch (error) {
119
+ return handleToolError(error);
120
+ }
121
+ });
122
+ }
123
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Shared types for the Frihet MCP server.
3
+ */
4
+ export interface PaginatedResponse<T> {
5
+ data: T[];
6
+ total: number;
7
+ limit: number;
8
+ offset: number;
9
+ }
10
+ export interface ApiError {
11
+ error: string;
12
+ message?: string;
13
+ }
14
+ export interface PaginationParams {
15
+ limit?: number;
16
+ offset?: number;
17
+ }
18
+ export interface Address {
19
+ street?: string;
20
+ city?: string;
21
+ postalCode?: string;
22
+ country?: string;
23
+ }
24
+ export interface InvoiceItem {
25
+ description: string;
26
+ quantity: number;
27
+ unitPrice: number;
28
+ }
29
+ export interface Invoice {
30
+ id: string;
31
+ clientName: string;
32
+ items: InvoiceItem[];
33
+ status?: string;
34
+ dueDate?: string;
35
+ notes?: string;
36
+ taxRate?: number;
37
+ total?: number;
38
+ createdAt?: string;
39
+ updatedAt?: string;
40
+ }
41
+ export type CreateInvoiceInput = Pick<Invoice, "clientName" | "items"> & Partial<Pick<Invoice, "status" | "dueDate" | "notes" | "taxRate">>;
42
+ export type UpdateInvoiceInput = Partial<CreateInvoiceInput>;
43
+ export interface Expense {
44
+ id: string;
45
+ description: string;
46
+ amount: number;
47
+ category?: string;
48
+ date?: string;
49
+ vendor?: string;
50
+ taxDeductible?: boolean;
51
+ createdAt?: string;
52
+ updatedAt?: string;
53
+ }
54
+ export type CreateExpenseInput = Pick<Expense, "description" | "amount"> & Partial<Pick<Expense, "category" | "date" | "vendor" | "taxDeductible">>;
55
+ export type UpdateExpenseInput = Partial<CreateExpenseInput>;
56
+ export interface Client {
57
+ id: string;
58
+ name: string;
59
+ email?: string;
60
+ phone?: string;
61
+ taxId?: string;
62
+ address?: Address;
63
+ createdAt?: string;
64
+ updatedAt?: string;
65
+ }
66
+ export type CreateClientInput = Pick<Client, "name"> & Partial<Pick<Client, "email" | "phone" | "taxId" | "address">>;
67
+ export type UpdateClientInput = Partial<CreateClientInput>;
68
+ export interface Product {
69
+ id: string;
70
+ name: string;
71
+ unitPrice: number;
72
+ description?: string;
73
+ unit?: string;
74
+ taxRate?: number;
75
+ sku?: string;
76
+ createdAt?: string;
77
+ updatedAt?: string;
78
+ }
79
+ export type CreateProductInput = Pick<Product, "name" | "unitPrice"> & Partial<Pick<Product, "description" | "unit" | "taxRate" | "sku">>;
80
+ export type UpdateProductInput = Partial<CreateProductInput>;
81
+ export interface QuoteItem {
82
+ description: string;
83
+ quantity: number;
84
+ unitPrice: number;
85
+ }
86
+ export interface Quote {
87
+ id: string;
88
+ clientName: string;
89
+ items: QuoteItem[];
90
+ validUntil?: string;
91
+ notes?: string;
92
+ status?: string;
93
+ total?: number;
94
+ createdAt?: string;
95
+ updatedAt?: string;
96
+ }
97
+ export type CreateQuoteInput = Pick<Quote, "clientName" | "items"> & Partial<Pick<Quote, "validUntil" | "notes" | "status">>;
98
+ export type UpdateQuoteInput = Partial<CreateQuoteInput>;
99
+ export interface Webhook {
100
+ id: string;
101
+ url: string;
102
+ events: string[];
103
+ active?: boolean;
104
+ secret?: string;
105
+ createdAt?: string;
106
+ updatedAt?: string;
107
+ }
108
+ export type CreateWebhookInput = Pick<Webhook, "url" | "events"> & Partial<Pick<Webhook, "active" | "secret">>;
109
+ export type UpdateWebhookInput = Partial<CreateWebhookInput>;
110
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared types for the Frihet MCP server.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@frihet/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Frihet ERP — manage invoices, expenses, clients, products and quotes with AI",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "frihet-mcp": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "erp",
18
+ "invoicing",
19
+ "frihet",
20
+ "ai",
21
+ "model-context-protocol",
22
+ "claude",
23
+ "cursor",
24
+ "windsurf"
25
+ ],
26
+ "author": "BRTHLS <viktor@brthls.com>",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/berthelius/frihet-mcp.git"
31
+ },
32
+ "homepage": "https://github.com/berthelius/frihet-mcp#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/berthelius/frihet-mcp/issues"
35
+ },
36
+ "engines": {
37
+ "node": ">=18"
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.26.0"
46
+ },
47
+ "peerDependencies": {
48
+ "zod": ">=3.25.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "zod": {
52
+ "optional": false
53
+ }
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^22.0.0",
57
+ "typescript": "^5.7.0",
58
+ "zod": "^3.25.0"
59
+ }
60
+ }