@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":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,SAAS,IAAI;IACX,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,2DAA2D;YACzD,kEAAkE;YAClE,YAAY;YACZ,mDAAmD,CACtD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,qBAAqB;IACrB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,8BAA8B;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;QAClC,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Client 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 registerClientTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=clients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/tools/clients.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAajD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA6IjF"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Client tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ const addressSchema = z
7
+ .object({
8
+ street: z.string().optional().describe("Street address / Direccion"),
9
+ city: z.string().optional().describe("City / Ciudad"),
10
+ postalCode: z.string().optional().describe("Postal code / Codigo postal"),
11
+ country: z.string().optional().describe("Country (ISO code) / Pais"),
12
+ })
13
+ .optional()
14
+ .describe("Client address / Direccion del cliente");
15
+ export function registerClientTools(server, client) {
16
+ // -- list_clients --
17
+ server.registerTool("list_clients", {
18
+ title: "List Clients",
19
+ description: "List all clients/customers with optional pagination. " +
20
+ "Returns contact info, tax IDs, and addresses. " +
21
+ "/ Lista todos los clientes con paginacion opcional. " +
22
+ "Devuelve informacion de contacto, NIF/CIF y direcciones.",
23
+ inputSchema: {
24
+ limit: z.number().int().min(1).max(100).optional().describe("Max results (1-100) / Resultados maximos"),
25
+ offset: z.number().int().min(0).optional().describe("Offset / Desplazamiento"),
26
+ },
27
+ }, async ({ limit, offset }) => {
28
+ try {
29
+ const result = await client.listClients({ limit, offset });
30
+ return {
31
+ content: [{ type: "text", text: formatPaginatedResponse("clients", result) }],
32
+ };
33
+ }
34
+ catch (error) {
35
+ return handleToolError(error);
36
+ }
37
+ });
38
+ // -- get_client --
39
+ server.registerTool("get_client", {
40
+ title: "Get Client",
41
+ description: "Get a single client by their ID. Returns full contact details. " +
42
+ "/ Obtiene un cliente por su ID. Devuelve todos los datos de contacto.",
43
+ inputSchema: {
44
+ id: z.string().describe("Client ID / ID del cliente"),
45
+ },
46
+ }, async ({ id }) => {
47
+ try {
48
+ const result = await client.getClient(id);
49
+ return {
50
+ content: [{ type: "text", text: formatRecord("Client", result) }],
51
+ };
52
+ }
53
+ catch (error) {
54
+ return handleToolError(error);
55
+ }
56
+ });
57
+ // -- create_client --
58
+ server.registerTool("create_client", {
59
+ title: "Create Client",
60
+ description: "Create a new client/customer. Requires at minimum a name. " +
61
+ "Clients are used when creating invoices and quotes. " +
62
+ "/ Crea un nuevo cliente. Requiere como minimo un nombre. " +
63
+ "Los clientes se usan al crear facturas y presupuestos.",
64
+ inputSchema: {
65
+ name: z.string().describe("Client/company name / Nombre del cliente o empresa"),
66
+ email: z.string().optional().describe("Email address / Correo electronico"),
67
+ phone: z.string().optional().describe("Phone number / Telefono"),
68
+ taxId: z.string().optional().describe("Tax ID (NIF/CIF/VAT) / NIF o CIF"),
69
+ address: addressSchema,
70
+ },
71
+ }, async (input) => {
72
+ try {
73
+ const result = await client.createClient(input);
74
+ return {
75
+ content: [{ type: "text", text: formatRecord("Client created", result) }],
76
+ };
77
+ }
78
+ catch (error) {
79
+ return handleToolError(error);
80
+ }
81
+ });
82
+ // -- update_client --
83
+ server.registerTool("update_client", {
84
+ title: "Update Client",
85
+ description: "Update an existing client. Only the provided fields will be changed. " +
86
+ "/ Actualiza un cliente existente. Solo se modifican los campos proporcionados.",
87
+ inputSchema: {
88
+ id: z.string().describe("Client ID / ID del cliente"),
89
+ name: z.string().optional().describe("Name / Nombre"),
90
+ email: z.string().optional().describe("Email / Correo"),
91
+ phone: z.string().optional().describe("Phone / Telefono"),
92
+ taxId: z.string().optional().describe("Tax ID / NIF/CIF"),
93
+ address: addressSchema,
94
+ },
95
+ }, async ({ id, ...data }) => {
96
+ try {
97
+ const result = await client.updateClient(id, data);
98
+ return {
99
+ content: [{ type: "text", text: formatRecord("Client updated", result) }],
100
+ };
101
+ }
102
+ catch (error) {
103
+ return handleToolError(error);
104
+ }
105
+ });
106
+ // -- delete_client --
107
+ server.registerTool("delete_client", {
108
+ title: "Delete Client",
109
+ description: "Permanently delete a client by their ID. This action cannot be undone. " +
110
+ "Warning: this may affect existing invoices and quotes referencing this client. " +
111
+ "/ Elimina permanentemente un cliente por su ID. Esta accion no se puede deshacer. " +
112
+ "Advertencia: puede afectar a facturas y presupuestos existentes.",
113
+ inputSchema: {
114
+ id: z.string().describe("Client ID / ID del cliente"),
115
+ },
116
+ }, async ({ id }) => {
117
+ try {
118
+ await client.deleteClient(id);
119
+ return {
120
+ content: [{ type: "text", text: `Client ${id} deleted successfully. / Cliente ${id} eliminado correctamente.` }],
121
+ };
122
+ }
123
+ catch (error) {
124
+ return handleToolError(error);
125
+ }
126
+ });
127
+ }
128
+ //# sourceMappingURL=clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/tools/clients.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Expense 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 registerExpenseTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=expenses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expenses.d.ts","sourceRoot":"","sources":["../../src/tools/expenses.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,CAoJlF"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Expense tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ export function registerExpenseTools(server, client) {
7
+ // -- list_expenses --
8
+ server.registerTool("list_expenses", {
9
+ title: "List Expenses",
10
+ description: "List all expenses with optional pagination. " +
11
+ "/ Lista todos los gastos con paginacion opcional.",
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.listExpenses({ limit, offset });
19
+ return {
20
+ content: [{ type: "text", text: formatPaginatedResponse("expenses", result) }],
21
+ };
22
+ }
23
+ catch (error) {
24
+ return handleToolError(error);
25
+ }
26
+ });
27
+ // -- get_expense --
28
+ server.registerTool("get_expense", {
29
+ title: "Get Expense",
30
+ description: "Get a single expense by its ID. " +
31
+ "/ Obtiene un gasto por su ID.",
32
+ inputSchema: {
33
+ id: z.string().describe("Expense ID / ID del gasto"),
34
+ },
35
+ }, async ({ id }) => {
36
+ try {
37
+ const result = await client.getExpense(id);
38
+ return {
39
+ content: [{ type: "text", text: formatRecord("Expense", result) }],
40
+ };
41
+ }
42
+ catch (error) {
43
+ return handleToolError(error);
44
+ }
45
+ });
46
+ // -- create_expense --
47
+ server.registerTool("create_expense", {
48
+ title: "Create Expense",
49
+ description: "Record a new expense. Requires a description and amount. " +
50
+ "Useful for tracking business costs, deductible expenses, and vendor payments. " +
51
+ "/ Registra un nuevo gasto. Requiere descripcion e importe. " +
52
+ "Util para seguimiento de costes, gastos deducibles y pagos a proveedores.",
53
+ inputSchema: {
54
+ description: z.string().describe("Expense description / Descripcion del gasto"),
55
+ amount: z.number().describe("Amount in EUR / Importe en EUR"),
56
+ category: z
57
+ .string()
58
+ .optional()
59
+ .describe("Expense category (e.g. 'office', 'travel', 'software') / Categoria"),
60
+ date: z
61
+ .string()
62
+ .optional()
63
+ .describe("Expense date in ISO 8601 (YYYY-MM-DD) / Fecha del gasto"),
64
+ vendor: z.string().optional().describe("Vendor/supplier name / Nombre del proveedor"),
65
+ taxDeductible: z
66
+ .boolean()
67
+ .optional()
68
+ .describe("Whether the expense is tax deductible / Si el gasto es deducible fiscalmente"),
69
+ },
70
+ }, async (input) => {
71
+ try {
72
+ const result = await client.createExpense(input);
73
+ return {
74
+ content: [{ type: "text", text: formatRecord("Expense created", result) }],
75
+ };
76
+ }
77
+ catch (error) {
78
+ return handleToolError(error);
79
+ }
80
+ });
81
+ // -- update_expense --
82
+ server.registerTool("update_expense", {
83
+ title: "Update Expense",
84
+ description: "Update an existing expense. Only the provided fields will be changed. " +
85
+ "/ Actualiza un gasto existente. Solo se modifican los campos proporcionados.",
86
+ inputSchema: {
87
+ id: z.string().describe("Expense ID / ID del gasto"),
88
+ description: z.string().optional().describe("Description / Descripcion"),
89
+ amount: z.number().optional().describe("Amount in EUR / Importe"),
90
+ category: z.string().optional().describe("Category / Categoria"),
91
+ date: z.string().optional().describe("Date (YYYY-MM-DD) / Fecha"),
92
+ vendor: z.string().optional().describe("Vendor / Proveedor"),
93
+ taxDeductible: z.boolean().optional().describe("Tax deductible / Deducible"),
94
+ },
95
+ }, async ({ id, ...data }) => {
96
+ try {
97
+ const result = await client.updateExpense(id, data);
98
+ return {
99
+ content: [{ type: "text", text: formatRecord("Expense updated", result) }],
100
+ };
101
+ }
102
+ catch (error) {
103
+ return handleToolError(error);
104
+ }
105
+ });
106
+ // -- delete_expense --
107
+ server.registerTool("delete_expense", {
108
+ title: "Delete Expense",
109
+ description: "Permanently delete an expense by its ID. This action cannot be undone. " +
110
+ "/ Elimina permanentemente un gasto por su ID. Esta accion no se puede deshacer.",
111
+ inputSchema: {
112
+ id: z.string().describe("Expense ID / ID del gasto"),
113
+ },
114
+ }, async ({ id }) => {
115
+ try {
116
+ await client.deleteExpense(id);
117
+ return {
118
+ content: [{ type: "text", text: `Expense ${id} deleted successfully. / Gasto ${id} eliminado correctamente.` }],
119
+ };
120
+ }
121
+ catch (error) {
122
+ return handleToolError(error);
123
+ }
124
+ });
125
+ }
126
+ //# sourceMappingURL=expenses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expenses.js","sourceRoot":"","sources":["../../src/tools/expenses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Invoice 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 registerInvoiceTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=invoices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoices.d.ts","sourceRoot":"","sources":["../../src/tools/invoices.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,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAgNlF"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Invoice tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ const invoiceItemSchema = 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 registerInvoiceTools(server, client) {
12
+ // -- list_invoices --
13
+ server.registerTool("list_invoices", {
14
+ title: "List Invoices",
15
+ description: "List all invoices with optional pagination. " +
16
+ "Returns a paginated list of invoices sorted by creation date. " +
17
+ "/ Lista todas las facturas con paginacion opcional. " +
18
+ "Devuelve una lista paginada de facturas ordenadas por fecha de creacion.",
19
+ inputSchema: {
20
+ limit: z
21
+ .number()
22
+ .int()
23
+ .min(1)
24
+ .max(100)
25
+ .optional()
26
+ .describe("Max results per page (1-100, default 50) / Resultados por pagina"),
27
+ offset: z
28
+ .number()
29
+ .int()
30
+ .min(0)
31
+ .optional()
32
+ .describe("Number of results to skip / Resultados a saltar"),
33
+ },
34
+ }, async ({ limit, offset }) => {
35
+ try {
36
+ const result = await client.listInvoices({ limit, offset });
37
+ return {
38
+ content: [{ type: "text", text: formatPaginatedResponse("invoices", result) }],
39
+ };
40
+ }
41
+ catch (error) {
42
+ return handleToolError(error);
43
+ }
44
+ });
45
+ // -- get_invoice --
46
+ server.registerTool("get_invoice", {
47
+ title: "Get Invoice",
48
+ description: "Get a single invoice by its ID. Returns the full invoice including line items, totals, and status. " +
49
+ "/ Obtiene una factura por su ID. Devuelve la factura completa con conceptos, totales y estado.",
50
+ inputSchema: {
51
+ id: z.string().describe("Invoice ID / ID de la factura"),
52
+ },
53
+ }, async ({ id }) => {
54
+ try {
55
+ const result = await client.getInvoice(id);
56
+ return {
57
+ content: [{ type: "text", text: formatRecord("Invoice", result) }],
58
+ };
59
+ }
60
+ catch (error) {
61
+ return handleToolError(error);
62
+ }
63
+ });
64
+ // -- create_invoice --
65
+ server.registerTool("create_invoice", {
66
+ title: "Create Invoice",
67
+ description: "Create a new invoice. Requires client name and at least one line item. " +
68
+ "The invoice number is auto-generated. " +
69
+ "/ Crea una nueva factura. Requiere nombre del cliente y al menos un concepto. " +
70
+ "El numero de factura se genera automaticamente.",
71
+ inputSchema: {
72
+ clientName: z.string().describe("Client/customer name / Nombre del cliente"),
73
+ items: z
74
+ .array(invoiceItemSchema)
75
+ .min(1)
76
+ .describe("Line items / Conceptos de la factura"),
77
+ status: z
78
+ .enum(["draft", "sent", "paid", "overdue", "cancelled"])
79
+ .optional()
80
+ .describe("Invoice status (default: draft) / Estado de la factura"),
81
+ dueDate: z
82
+ .string()
83
+ .optional()
84
+ .describe("Due date in ISO 8601 format (YYYY-MM-DD) / Fecha de vencimiento"),
85
+ notes: z
86
+ .string()
87
+ .optional()
88
+ .describe("Additional notes / Notas adicionales"),
89
+ taxRate: z
90
+ .number()
91
+ .min(0)
92
+ .max(100)
93
+ .optional()
94
+ .describe("Tax rate percentage (e.g. 21 for 21% IVA) / Porcentaje de impuesto"),
95
+ },
96
+ }, async (input) => {
97
+ try {
98
+ const result = await client.createInvoice(input);
99
+ return {
100
+ content: [{ type: "text", text: formatRecord("Invoice created", result) }],
101
+ };
102
+ }
103
+ catch (error) {
104
+ return handleToolError(error);
105
+ }
106
+ });
107
+ // -- update_invoice --
108
+ server.registerTool("update_invoice", {
109
+ title: "Update Invoice",
110
+ description: "Update an existing invoice. Only the provided fields will be changed. " +
111
+ "/ Actualiza una factura existente. Solo se modifican los campos proporcionados.",
112
+ inputSchema: {
113
+ id: z.string().describe("Invoice ID / ID de la factura"),
114
+ clientName: z.string().optional().describe("Client name / Nombre del cliente"),
115
+ items: z
116
+ .array(invoiceItemSchema)
117
+ .min(1)
118
+ .optional()
119
+ .describe("Line items / Conceptos"),
120
+ status: z
121
+ .enum(["draft", "sent", "paid", "overdue", "cancelled"])
122
+ .optional()
123
+ .describe("Invoice status / Estado"),
124
+ dueDate: z.string().optional().describe("Due date (YYYY-MM-DD) / Fecha de vencimiento"),
125
+ notes: z.string().optional().describe("Notes / Notas"),
126
+ taxRate: z.number().min(0).max(100).optional().describe("Tax rate % / IVA %"),
127
+ },
128
+ }, async ({ id, ...data }) => {
129
+ try {
130
+ const result = await client.updateInvoice(id, data);
131
+ return {
132
+ content: [{ type: "text", text: formatRecord("Invoice updated", result) }],
133
+ };
134
+ }
135
+ catch (error) {
136
+ return handleToolError(error);
137
+ }
138
+ });
139
+ // -- delete_invoice --
140
+ server.registerTool("delete_invoice", {
141
+ title: "Delete Invoice",
142
+ description: "Permanently delete an invoice by its ID. This action cannot be undone. " +
143
+ "/ Elimina permanentemente una factura por su ID. Esta accion no se puede deshacer.",
144
+ inputSchema: {
145
+ id: z.string().describe("Invoice ID / ID de la factura"),
146
+ },
147
+ }, async ({ id }) => {
148
+ try {
149
+ await client.deleteInvoice(id);
150
+ return {
151
+ content: [{ type: "text", text: `Invoice ${id} deleted successfully. / Factura ${id} eliminada correctamente.` }],
152
+ };
153
+ }
154
+ catch (error) {
155
+ return handleToolError(error);
156
+ }
157
+ });
158
+ // -- search_invoices --
159
+ server.registerTool("search_invoices", {
160
+ title: "Search Invoices",
161
+ description: "Search invoices by client name. Useful for finding all invoices for a specific client. " +
162
+ "/ Busca facturas por nombre de cliente. Util para encontrar todas las facturas de un cliente concreto.",
163
+ inputSchema: {
164
+ clientName: z.string().describe("Client name to search for / Nombre del cliente a buscar"),
165
+ limit: z.number().int().min(1).max(100).optional().describe("Max results / Resultados maximos"),
166
+ offset: z.number().int().min(0).optional().describe("Offset / Desplazamiento"),
167
+ },
168
+ }, async ({ clientName, limit, offset }) => {
169
+ try {
170
+ const result = await client.searchInvoices(clientName, { limit, offset });
171
+ return {
172
+ content: [
173
+ {
174
+ type: "text",
175
+ text: formatPaginatedResponse(`invoices matching "${clientName}"`, result),
176
+ },
177
+ ],
178
+ };
179
+ }
180
+ catch (error) {
181
+ return handleToolError(error);
182
+ }
183
+ });
184
+ }
185
+ //# sourceMappingURL=invoices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoices.js","sourceRoot":"","sources":["../../src/tools/invoices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Product 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 registerProductTools(server: McpServer, client: FrihetClient): void;
7
+ //# sourceMappingURL=products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../src/tools/products.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,127 @@
1
+ /**
2
+ * Product tools for the Frihet MCP server.
3
+ */
4
+ import { z } from "zod/v4";
5
+ import { handleToolError, formatPaginatedResponse, formatRecord } from "./shared.js";
6
+ export function registerProductTools(server, client) {
7
+ // -- list_products --
8
+ server.registerTool("list_products", {
9
+ title: "List Products",
10
+ description: "List all products/services with optional pagination. " +
11
+ "Products are reusable items that can be added to invoices and quotes. " +
12
+ "/ Lista todos los productos/servicios con paginacion opcional. " +
13
+ "Los productos son conceptos reutilizables para facturas y presupuestos.",
14
+ inputSchema: {
15
+ limit: z.number().int().min(1).max(100).optional().describe("Max results (1-100) / Resultados maximos"),
16
+ offset: z.number().int().min(0).optional().describe("Offset / Desplazamiento"),
17
+ },
18
+ }, async ({ limit, offset }) => {
19
+ try {
20
+ const result = await client.listProducts({ limit, offset });
21
+ return {
22
+ content: [{ type: "text", text: formatPaginatedResponse("products", result) }],
23
+ };
24
+ }
25
+ catch (error) {
26
+ return handleToolError(error);
27
+ }
28
+ });
29
+ // -- get_product --
30
+ server.registerTool("get_product", {
31
+ title: "Get Product",
32
+ description: "Get a single product/service by its ID. " +
33
+ "/ Obtiene un producto/servicio por su ID.",
34
+ inputSchema: {
35
+ id: z.string().describe("Product ID / ID del producto"),
36
+ },
37
+ }, async ({ id }) => {
38
+ try {
39
+ const result = await client.getProduct(id);
40
+ return {
41
+ content: [{ type: "text", text: formatRecord("Product", result) }],
42
+ };
43
+ }
44
+ catch (error) {
45
+ return handleToolError(error);
46
+ }
47
+ });
48
+ // -- create_product --
49
+ server.registerTool("create_product", {
50
+ title: "Create Product",
51
+ description: "Create a new product or service. Requires a name and unit price. " +
52
+ "Products can be referenced when creating invoices and quotes for faster data entry. " +
53
+ "/ Crea un nuevo producto o servicio. Requiere nombre y precio unitario. " +
54
+ "Los productos se pueden usar al crear facturas y presupuestos.",
55
+ inputSchema: {
56
+ name: z.string().describe("Product/service name / Nombre del producto o servicio"),
57
+ unitPrice: z.number().describe("Unit price in EUR / Precio unitario en EUR"),
58
+ description: z.string().optional().describe("Product description / Descripcion"),
59
+ unit: z
60
+ .string()
61
+ .optional()
62
+ .describe("Unit of measurement (e.g. 'hour', 'unit', 'kg') / Unidad de medida"),
63
+ taxRate: z
64
+ .number()
65
+ .min(0)
66
+ .max(100)
67
+ .optional()
68
+ .describe("Default tax rate % (e.g. 21 for 21% IVA) / IVA por defecto"),
69
+ sku: z.string().optional().describe("SKU / Reference code / Codigo de referencia"),
70
+ },
71
+ }, async (input) => {
72
+ try {
73
+ const result = await client.createProduct(input);
74
+ return {
75
+ content: [{ type: "text", text: formatRecord("Product created", result) }],
76
+ };
77
+ }
78
+ catch (error) {
79
+ return handleToolError(error);
80
+ }
81
+ });
82
+ // -- update_product --
83
+ server.registerTool("update_product", {
84
+ title: "Update Product",
85
+ description: "Update an existing product. Only the provided fields will be changed. " +
86
+ "/ Actualiza un producto existente. Solo se modifican los campos proporcionados.",
87
+ inputSchema: {
88
+ id: z.string().describe("Product ID / ID del producto"),
89
+ name: z.string().optional().describe("Name / Nombre"),
90
+ unitPrice: z.number().optional().describe("Unit price / Precio unitario"),
91
+ description: z.string().optional().describe("Description / Descripcion"),
92
+ unit: z.string().optional().describe("Unit / Unidad"),
93
+ taxRate: z.number().min(0).max(100).optional().describe("Tax rate % / IVA %"),
94
+ sku: z.string().optional().describe("SKU / Referencia"),
95
+ },
96
+ }, async ({ id, ...data }) => {
97
+ try {
98
+ const result = await client.updateProduct(id, data);
99
+ return {
100
+ content: [{ type: "text", text: formatRecord("Product updated", result) }],
101
+ };
102
+ }
103
+ catch (error) {
104
+ return handleToolError(error);
105
+ }
106
+ });
107
+ // -- delete_product --
108
+ server.registerTool("delete_product", {
109
+ title: "Delete Product",
110
+ description: "Permanently delete a product by its ID. This action cannot be undone. " +
111
+ "/ Elimina permanentemente un producto por su ID. Esta accion no se puede deshacer.",
112
+ inputSchema: {
113
+ id: z.string().describe("Product ID / ID del producto"),
114
+ },
115
+ }, async ({ id }) => {
116
+ try {
117
+ await client.deleteProduct(id);
118
+ return {
119
+ content: [{ type: "text", text: `Product ${id} deleted successfully. / Producto ${id} eliminado correctamente.` }],
120
+ };
121
+ }
122
+ catch (error) {
123
+ return handleToolError(error);
124
+ }
125
+ });
126
+ }
127
+ //# sourceMappingURL=products.js.map