@frihet/mcp-server 1.6.1 → 1.9.0-beta.1

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 (77) hide show
  1. package/README.md +19 -6
  2. package/dist/__tests__/banking-tools.test.d.ts +18 -0
  3. package/dist/__tests__/banking-tools.test.d.ts.map +1 -0
  4. package/dist/__tests__/banking-tools.test.js +252 -0
  5. package/dist/__tests__/banking-tools.test.js.map +1 -0
  6. package/dist/__tests__/einvoice-integration.test.d.ts +24 -0
  7. package/dist/__tests__/einvoice-integration.test.d.ts.map +1 -0
  8. package/dist/__tests__/einvoice-integration.test.js +142 -0
  9. package/dist/__tests__/einvoice-integration.test.js.map +1 -0
  10. package/dist/__tests__/einvoice-tools.test.d.ts +16 -0
  11. package/dist/__tests__/einvoice-tools.test.d.ts.map +1 -0
  12. package/dist/__tests__/einvoice-tools.test.js +435 -0
  13. package/dist/__tests__/einvoice-tools.test.js.map +1 -0
  14. package/dist/__tests__/fiscal-tools.test.d.ts +20 -0
  15. package/dist/__tests__/fiscal-tools.test.d.ts.map +1 -0
  16. package/dist/__tests__/fiscal-tools.test.js +233 -0
  17. package/dist/__tests__/fiscal-tools.test.js.map +1 -0
  18. package/dist/__tests__/pos-tools.test.d.ts +16 -0
  19. package/dist/__tests__/pos-tools.test.d.ts.map +1 -0
  20. package/dist/__tests__/pos-tools.test.js +244 -0
  21. package/dist/__tests__/pos-tools.test.js.map +1 -0
  22. package/dist/__tests__/recurring-tools.test.d.ts +16 -0
  23. package/dist/__tests__/recurring-tools.test.d.ts.map +1 -0
  24. package/dist/__tests__/recurring-tools.test.js +166 -0
  25. package/dist/__tests__/recurring-tools.test.js.map +1 -0
  26. package/dist/__tests__/stay-tools.test.d.ts +17 -0
  27. package/dist/__tests__/stay-tools.test.d.ts.map +1 -0
  28. package/dist/__tests__/stay-tools.test.js +259 -0
  29. package/dist/__tests__/stay-tools.test.js.map +1 -0
  30. package/dist/__tests__/time-tools.test.d.ts +17 -0
  31. package/dist/__tests__/time-tools.test.d.ts.map +1 -0
  32. package/dist/__tests__/time-tools.test.js +199 -0
  33. package/dist/__tests__/time-tools.test.js.map +1 -0
  34. package/dist/client-interface.d.ts +131 -0
  35. package/dist/client-interface.d.ts.map +1 -1
  36. package/dist/client.d.ts +131 -0
  37. package/dist/client.d.ts.map +1 -1
  38. package/dist/client.js +159 -0
  39. package/dist/client.js.map +1 -1
  40. package/dist/index.js +0 -0
  41. package/dist/tools/banking.d.ts +19 -0
  42. package/dist/tools/banking.d.ts.map +1 -0
  43. package/dist/tools/banking.js +155 -0
  44. package/dist/tools/banking.js.map +1 -0
  45. package/dist/tools/einvoice.d.ts +92 -0
  46. package/dist/tools/einvoice.d.ts.map +1 -0
  47. package/dist/tools/einvoice.js +400 -0
  48. package/dist/tools/einvoice.js.map +1 -0
  49. package/dist/tools/fiscal.d.ts +22 -0
  50. package/dist/tools/fiscal.d.ts.map +1 -0
  51. package/dist/tools/fiscal.js +215 -0
  52. package/dist/tools/fiscal.js.map +1 -0
  53. package/dist/tools/pos.d.ts +15 -0
  54. package/dist/tools/pos.d.ts.map +1 -0
  55. package/dist/tools/pos.js +156 -0
  56. package/dist/tools/pos.js.map +1 -0
  57. package/dist/tools/recurring.d.ts +16 -0
  58. package/dist/tools/recurring.d.ts.map +1 -0
  59. package/dist/tools/recurring.js +67 -0
  60. package/dist/tools/recurring.js.map +1 -0
  61. package/dist/tools/register-all.d.ts +2 -2
  62. package/dist/tools/register-all.d.ts.map +1 -1
  63. package/dist/tools/register-all.js +16 -2
  64. package/dist/tools/register-all.js.map +1 -1
  65. package/dist/tools/shared.d.ts +169 -0
  66. package/dist/tools/shared.d.ts.map +1 -1
  67. package/dist/tools/shared.js +140 -0
  68. package/dist/tools/shared.js.map +1 -1
  69. package/dist/tools/stay.d.ts +6 -78
  70. package/dist/tools/stay.d.ts.map +1 -1
  71. package/dist/tools/stay.js +121 -343
  72. package/dist/tools/stay.js.map +1 -1
  73. package/dist/tools/time.d.ts +18 -0
  74. package/dist/tools/time.d.ts.map +1 -0
  75. package/dist/tools/time.js +134 -0
  76. package/dist/tools/time.js.map +1 -0
  77. package/package.json +3 -2
package/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
  <a href="https://smithery.ai/server/frihet/frihet-mcp"><img src="https://smithery.ai/badge/frihet/frihet-mcp" alt="Smithery installs"></a>
18
18
  <a href="https://registry.modelcontextprotocol.io/?q=io.frihet"><img src="https://img.shields.io/badge/MCP_Registry-io.frihet%2Ferp-4A90D9?style=flat&logo=anthropic&logoColor=white" alt="MCP Registry"></a>
19
19
  <a href="https://github.com/Frihet-io/frihet-mcp/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-18181b?style=flat&labelColor=09090b" alt="license"></a>
20
- <img src="https://img.shields.io/badge/tools-55-18181b?style=flat&labelColor=09090b" alt="55 tools">
20
+ <img src="https://img.shields.io/badge/tools-94-18181b?style=flat&labelColor=09090b" alt="94 tools">
21
21
  <img src="https://img.shields.io/badge/node-%3E%3D18-18181b?style=flat&labelColor=09090b" alt="node >=18">
22
22
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-18181b?style=flat&labelColor=09090b" alt="TypeScript"></a>
23
23
  </p>
@@ -33,7 +33,9 @@ You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/h
33
33
  Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
34
34
  ```
35
35
 
36
- 55 tools. 8 resources. 7 prompts. Structured output on every tool. Zero boilerplate.
36
+ 94 tools. 8 resources. 7 prompts. Structured output on every tool. Zero boilerplate.
37
+
38
+ <!-- v1.9.0-beta.1 — Wave Mature 1: Banking (5) + Fiscal (8) + Stay (5) + POS (4) + Time (4) + Recurring (2) = 94 tools total -->
37
39
 
38
40
  ---
39
41
 
@@ -161,7 +163,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
161
163
 
162
164
  ## What to expect
163
165
 
164
- This MCP is a **structured data interface** -- you describe what you want in natural language, and the AI creates, queries, or modifies business records in Frihet. All 55 tools are CRUD operations over the REST API.
166
+ This MCP is a **structured data interface** -- you describe what you want in natural language, and the AI creates, queries, or modifies business records in Frihet. All 94 tools are CRUD operations over the REST API.
165
167
 
166
168
  **Works great:**
167
169
 
@@ -188,7 +190,7 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
188
190
 
189
191
  ---
190
192
 
191
- ## Tools (55)
193
+ ## Tools (94)
192
194
 
193
195
  ### Invoices (6)
194
196
 
@@ -283,7 +285,18 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
283
285
  | `get_quarterly_taxes` | Quarterly tax prep: Modelo 303/130 fields, collected vs deductible, liability |
284
286
  | `duplicate_invoice` | Clone an invoice for recurring billing (copies items/client/tax, starts as draft) |
285
287
 
286
- All 55 tools return **structured output** via `outputSchema` -- typed JSON, not raw text. List tools return paginated results (`{ data, total, limit, offset }`).
288
+ ## E-Invoicing (4 new in v1.7 pre-release)
289
+
290
+ > **Status: beta — CF endpoints rolling out 2026-04-21 to 2026-04-28.** Tools call `api.frihet.io/v1/einvoice/*` directly. If an endpoint is not yet deployed (404), the tool falls back to `{ _stub: true, _note: "CF endpoint pending deploy", _plannedEndpoint: "..." }` so the server remains usable while transport ships.
291
+
292
+ | Tool | What it does |
293
+ |------|-------------|
294
+ | `send_einvoice` | Dispatch an invoice in 11 formats (XRechnung, Factur-X, FatturaPA, PEPPOL, Facturae, UBL, CII) via email / Chorus Pro / SDI / PEPPOL / download |
295
+ | `get_einvoice_status` | Poll Hatchet workflow run status until succeeded/failed — returns ackId, XML URL, PDF/A-3 URL |
296
+ | `validate_einvoice_xml` | Validate raw XML against format schema + schematron rules (KOSIT / Mustang / XSD / Schematron) |
297
+ | `export_datev` | Export accounting data as DATEV EXTF (Buchungsstapel / Debitoren / Kreditoren) in CP1252 encoding |
298
+
299
+ All 94 tools return **structured output** via `outputSchema` -- typed JSON, not raw text. List tools return paginated results (`{ data, total, limit, offset }`).
287
300
 
288
301
  ---
289
302
 
@@ -462,7 +475,7 @@ npm run build # must pass before submitting
462
475
 
463
476
  | Package | What it is |
464
477
  |---------|-----------|
465
- | [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (55 tools, 8 resources, 7 prompts) |
478
+ | [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (94 tools, 8 resources, 7 prompts) |
466
479
  | [`@frihet/sdk`](https://github.com/Frihet-io/frihet-sdk) | TypeScript SDK (`frihet.invoices.create()`) |
467
480
  | [`frihet`](https://www.npmjs.com/package/frihet) | CLI (`frihet invoices list --status overdue`) |
468
481
  | [`n8n-nodes-frihet`](https://www.npmjs.com/package/n8n-nodes-frihet) | n8n community node for workflow automation |
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Tests for Banking MCP tools — Wave 6 (5 tools).
3
+ *
4
+ * Uses Node.js built-in test runner (node:test + node:assert).
5
+ * Run: npm test (after build)
6
+ *
7
+ * Coverage:
8
+ * 1. Tool registration — all 5 banking tools registered
9
+ * 2. list_bank_accounts — success path + structuredContent shape
10
+ * 3. get_bank_account — success path
11
+ * 4. list_transactions — success path + filters
12
+ * 5. categorize_transaction — success path + update response
13
+ * 6. match_transaction_to_invoice — confirm=false gate
14
+ * 7. match_transaction_to_invoice — confirm=true success path
15
+ * 8. API error — 404 propagated as isError=true
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=banking-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banking-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/banking-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Tests for Banking MCP tools — Wave 6 (5 tools).
3
+ *
4
+ * Uses Node.js built-in test runner (node:test + node:assert).
5
+ * Run: npm test (after build)
6
+ *
7
+ * Coverage:
8
+ * 1. Tool registration — all 5 banking tools registered
9
+ * 2. list_bank_accounts — success path + structuredContent shape
10
+ * 3. get_bank_account — success path
11
+ * 4. list_transactions — success path + filters
12
+ * 5. categorize_transaction — success path + update response
13
+ * 6. match_transaction_to_invoice — confirm=false gate
14
+ * 7. match_transaction_to_invoice — confirm=true success path
15
+ * 8. API error — 404 propagated as isError=true
16
+ */
17
+ import { test, describe, beforeEach } from "node:test";
18
+ import assert from "node:assert/strict";
19
+ class StubMcpServer {
20
+ tools = new Map();
21
+ registerTool(name, config, handler) {
22
+ this.tools.set(name, { name, config, handler });
23
+ }
24
+ }
25
+ // ── Mock data ────────────────────────────────────────────────────────────────
26
+ const MOCK_ACCOUNT = {
27
+ id: "acct_001",
28
+ alias: "Cuenta corriente BRTHLS",
29
+ ibanLast4: "4321",
30
+ currency: "EUR",
31
+ balance: 12345.67,
32
+ lastSyncedAt: "2026-05-10T08:00:00Z",
33
+ createdAt: "2026-01-01T00:00:00Z",
34
+ };
35
+ const MOCK_ACCOUNTS_LIST = {
36
+ data: [MOCK_ACCOUNT],
37
+ total: 1,
38
+ limit: 20,
39
+ offset: 0,
40
+ };
41
+ const MOCK_TRANSACTION = {
42
+ id: "tx_abc123",
43
+ accountId: "acct_001",
44
+ amount: -250.0,
45
+ currency: "EUR",
46
+ description: "Pago proveedor Acme",
47
+ postedAt: "2026-05-09T14:23:00Z",
48
+ category: "supplies",
49
+ status: "posted",
50
+ matchedDocId: null,
51
+ };
52
+ const MOCK_TRANSACTIONS_LIST = {
53
+ data: [MOCK_TRANSACTION],
54
+ total: 1,
55
+ limit: 20,
56
+ offset: 0,
57
+ };
58
+ // ── Client stubs ─────────────────────────────────────────────────────────────
59
+ function makeSuccessClient() {
60
+ return {
61
+ listBankAccounts: async () => MOCK_ACCOUNTS_LIST,
62
+ getBankAccount: async (_id) => MOCK_ACCOUNT,
63
+ listTransactions: async () => MOCK_TRANSACTIONS_LIST,
64
+ categorizeTransaction: async (_id, data) => ({ ...MOCK_TRANSACTION, category: data["category"] }),
65
+ matchTransactionToDocument: async (_txId, data) => ({
66
+ ...MOCK_TRANSACTION,
67
+ matchedDocId: data["documentId"],
68
+ }),
69
+ };
70
+ }
71
+ function make404Client() {
72
+ const notFound = () => {
73
+ const err = Object.assign(new Error("Not Found"), { statusCode: 404, errorCode: "not_found" });
74
+ return Promise.reject(err);
75
+ };
76
+ return {
77
+ listBankAccounts: notFound,
78
+ getBankAccount: notFound,
79
+ listTransactions: notFound,
80
+ categorizeTransaction: notFound,
81
+ matchTransactionToDocument: notFound,
82
+ };
83
+ }
84
+ // ── Helper ───────────────────────────────────────────────────────────────────
85
+ async function makeServer(clientFn) {
86
+ const server = new StubMcpServer();
87
+ const { registerBankingTools } = await import("../tools/banking.js");
88
+ registerBankingTools(server, clientFn());
89
+ return server;
90
+ }
91
+ // ── Registration tests ───────────────────────────────────────────────────────
92
+ describe("Banking Tools — Registration", () => {
93
+ let server;
94
+ beforeEach(async () => {
95
+ server = await makeServer(makeSuccessClient);
96
+ });
97
+ test("registers exactly 5 banking tools", () => {
98
+ assert.equal(server.tools.size, 5);
99
+ });
100
+ test("registers list_bank_accounts", () => {
101
+ assert.ok(server.tools.has("list_bank_accounts"));
102
+ });
103
+ test("registers get_bank_account", () => {
104
+ assert.ok(server.tools.has("get_bank_account"));
105
+ });
106
+ test("registers list_transactions", () => {
107
+ assert.ok(server.tools.has("list_transactions"));
108
+ });
109
+ test("registers categorize_transaction", () => {
110
+ assert.ok(server.tools.has("categorize_transaction"));
111
+ });
112
+ test("registers match_transaction_to_invoice", () => {
113
+ assert.ok(server.tools.has("match_transaction_to_invoice"));
114
+ });
115
+ });
116
+ // ── list_bank_accounts ───────────────────────────────────────────────────────
117
+ describe("list_bank_accounts — success path", () => {
118
+ test("returns structuredContent with data array", async () => {
119
+ const server = await makeServer(makeSuccessClient);
120
+ const tool = server.tools.get("list_bank_accounts");
121
+ const result = await tool.handler({});
122
+ assert.ok(!result.isError);
123
+ assert.ok(result.structuredContent);
124
+ const sc = result.structuredContent;
125
+ assert.ok(Array.isArray(sc["data"]));
126
+ assert.equal(sc["data"].length, 1);
127
+ assert.equal(sc["total"], 1);
128
+ });
129
+ test("first account has IBAN last 4 and balance", async () => {
130
+ const server = await makeServer(makeSuccessClient);
131
+ const tool = server.tools.get("list_bank_accounts");
132
+ const result = await tool.handler({});
133
+ const first = result.structuredContent["data"][0];
134
+ assert.equal(first["id"], "acct_001");
135
+ assert.equal(first["ibanLast4"], "4321");
136
+ assert.equal(first["currency"], "EUR");
137
+ assert.equal(first["balance"], 12345.67);
138
+ });
139
+ test("content block has type text and mentions bank_accounts", async () => {
140
+ const server = await makeServer(makeSuccessClient);
141
+ const tool = server.tools.get("list_bank_accounts");
142
+ const result = await tool.handler({});
143
+ assert.equal(result.content[0].type, "text");
144
+ assert.ok(result.content[0].text.includes("bank_accounts"));
145
+ });
146
+ });
147
+ // ── get_bank_account ─────────────────────────────────────────────────────────
148
+ describe("get_bank_account — success path", () => {
149
+ test("returns single account by ID", async () => {
150
+ const server = await makeServer(makeSuccessClient);
151
+ const tool = server.tools.get("get_bank_account");
152
+ const result = await tool.handler({ id: "acct_001" });
153
+ assert.ok(!result.isError);
154
+ const sc = result.structuredContent;
155
+ assert.equal(sc["id"], "acct_001");
156
+ assert.equal(sc["alias"], "Cuenta corriente BRTHLS");
157
+ });
158
+ test("404 propagates as isError=true", async () => {
159
+ const server = await makeServer(make404Client);
160
+ const tool = server.tools.get("get_bank_account");
161
+ const result = await tool.handler({ id: "acct_missing" });
162
+ assert.ok(result.isError);
163
+ assert.ok(result.content[0].text.includes("Error:"));
164
+ });
165
+ });
166
+ // ── list_transactions ────────────────────────────────────────────────────────
167
+ describe("list_transactions — success path", () => {
168
+ test("returns transactions list", async () => {
169
+ const server = await makeServer(makeSuccessClient);
170
+ const tool = server.tools.get("list_transactions");
171
+ const result = await tool.handler({ accountId: "acct_001", from: "2026-05-01", to: "2026-05-31" });
172
+ assert.ok(!result.isError);
173
+ const sc = result.structuredContent;
174
+ assert.ok(Array.isArray(sc["data"]));
175
+ assert.equal(sc["total"], 1);
176
+ });
177
+ test("first transaction has expected fields", async () => {
178
+ const server = await makeServer(makeSuccessClient);
179
+ const tool = server.tools.get("list_transactions");
180
+ const result = await tool.handler({});
181
+ const first = result.structuredContent["data"][0];
182
+ assert.equal(first["id"], "tx_abc123");
183
+ assert.equal(first["amount"], -250.0);
184
+ assert.equal(first["status"], "posted");
185
+ assert.equal(first["category"], "supplies");
186
+ });
187
+ test("accepts status filter without error", async () => {
188
+ const server = await makeServer(makeSuccessClient);
189
+ const tool = server.tools.get("list_transactions");
190
+ const result = await tool.handler({ status: "posted" });
191
+ assert.ok(!result.isError);
192
+ });
193
+ });
194
+ // ── categorize_transaction ───────────────────────────────────────────────────
195
+ describe("categorize_transaction — success path", () => {
196
+ test("returns updated transaction with new category", async () => {
197
+ const server = await makeServer(makeSuccessClient);
198
+ const tool = server.tools.get("categorize_transaction");
199
+ const result = await tool.handler({ id: "tx_abc123", category: "travel" });
200
+ assert.ok(!result.isError);
201
+ const sc = result.structuredContent;
202
+ assert.equal(sc["id"], "tx_abc123");
203
+ assert.equal(sc["category"], "travel");
204
+ });
205
+ test("content block mentions categorized", async () => {
206
+ const server = await makeServer(makeSuccessClient);
207
+ const tool = server.tools.get("categorize_transaction");
208
+ const result = await tool.handler({ id: "tx_abc123", category: "software", notes: "SaaS Q2" });
209
+ assert.ok(result.content[0].text.includes("categorized"));
210
+ });
211
+ });
212
+ // ── match_transaction_to_invoice ─────────────────────────────────────────────
213
+ describe("match_transaction_to_invoice — trust area gate", () => {
214
+ test("confirm=false returns isError=true without calling API", async () => {
215
+ const server = await makeServer(makeSuccessClient);
216
+ const tool = server.tools.get("match_transaction_to_invoice");
217
+ const result = await tool.handler({
218
+ transactionId: "tx_abc123",
219
+ documentId: "inv_xyz",
220
+ documentType: "invoice",
221
+ confirm: false,
222
+ });
223
+ assert.ok(result.isError, "should be isError when confirm=false");
224
+ assert.ok(result.content[0].text.includes("confirm=true"));
225
+ });
226
+ test("confirm=true success path returns matched transaction", async () => {
227
+ const server = await makeServer(makeSuccessClient);
228
+ const tool = server.tools.get("match_transaction_to_invoice");
229
+ const result = await tool.handler({
230
+ transactionId: "tx_abc123",
231
+ documentId: "inv_xyz456",
232
+ documentType: "invoice",
233
+ confirm: true,
234
+ });
235
+ assert.ok(!result.isError);
236
+ const sc = result.structuredContent;
237
+ assert.equal(sc["id"], "tx_abc123");
238
+ assert.equal(sc["matchedDocId"], "inv_xyz456");
239
+ });
240
+ test("confirm=true with expense type works", async () => {
241
+ const server = await makeServer(makeSuccessClient);
242
+ const tool = server.tools.get("match_transaction_to_invoice");
243
+ const result = await tool.handler({
244
+ transactionId: "tx_abc123",
245
+ documentId: "exp_abc",
246
+ documentType: "expense",
247
+ confirm: true,
248
+ });
249
+ assert.ok(!result.isError);
250
+ });
251
+ });
252
+ //# sourceMappingURL=banking-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banking-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/banking-tools.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Integration tests for e-invoice MCP tools against live api.frihet.io.
3
+ *
4
+ * Skipped by default. Runs only when MCP_LIVE_TEST=true.
5
+ *
6
+ * Usage:
7
+ * MCP_LIVE_TEST=true FRIHET_API_KEY=fri_your_key npm test
8
+ *
9
+ * Manual QA path:
10
+ * 1. Set env vars above.
11
+ * 2. Run: npm run build && MCP_LIVE_TEST=true FRIHET_API_KEY=fri_xxx node --test dist/__tests__/einvoice-integration.test.js
12
+ * 3. Verify: each tool returns real data (no _stub flag) OR 404-fallback stub if CF endpoint is pending.
13
+ * 4. For send_einvoice: poll get_einvoice_status with the returned workflowRunId every 5s.
14
+ * 5. For validate_einvoice_xml: pass a minimal valid XRechnung CII document.
15
+ * 6. For export_datev: check the fileUrl is a signed URL valid for 24h.
16
+ *
17
+ * CF endpoint rollout schedule:
18
+ * - /v1/einvoice/send → 2026-04-21
19
+ * - /v1/einvoice/status/:id → 2026-04-21
20
+ * - /v1/einvoice/validate → 2026-04-24
21
+ * - /v1/einvoice/export-datev → 2026-04-28
22
+ */
23
+ export {};
24
+ //# sourceMappingURL=einvoice-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"einvoice-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/einvoice-integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Integration tests for e-invoice MCP tools against live api.frihet.io.
3
+ *
4
+ * Skipped by default. Runs only when MCP_LIVE_TEST=true.
5
+ *
6
+ * Usage:
7
+ * MCP_LIVE_TEST=true FRIHET_API_KEY=fri_your_key npm test
8
+ *
9
+ * Manual QA path:
10
+ * 1. Set env vars above.
11
+ * 2. Run: npm run build && MCP_LIVE_TEST=true FRIHET_API_KEY=fri_xxx node --test dist/__tests__/einvoice-integration.test.js
12
+ * 3. Verify: each tool returns real data (no _stub flag) OR 404-fallback stub if CF endpoint is pending.
13
+ * 4. For send_einvoice: poll get_einvoice_status with the returned workflowRunId every 5s.
14
+ * 5. For validate_einvoice_xml: pass a minimal valid XRechnung CII document.
15
+ * 6. For export_datev: check the fileUrl is a signed URL valid for 24h.
16
+ *
17
+ * CF endpoint rollout schedule:
18
+ * - /v1/einvoice/send → 2026-04-21
19
+ * - /v1/einvoice/status/:id → 2026-04-21
20
+ * - /v1/einvoice/validate → 2026-04-24
21
+ * - /v1/einvoice/export-datev → 2026-04-28
22
+ */
23
+ import { test, describe, before } from "node:test";
24
+ import assert from "node:assert/strict";
25
+ const LIVE = process.env["MCP_LIVE_TEST"] === "true";
26
+ const API_KEY = process.env["FRIHET_API_KEY"] ?? "";
27
+ const skip = (name, fn) => {
28
+ if (!LIVE) {
29
+ test(`[SKIPPED — set MCP_LIVE_TEST=true] ${name}`, () => {
30
+ // intentionally skipped
31
+ });
32
+ return;
33
+ }
34
+ test(name, fn);
35
+ };
36
+ class StubMcpServer {
37
+ tools = new Map();
38
+ registerTool(name, config, handler) {
39
+ this.tools.set(name, { name, config, handler });
40
+ }
41
+ }
42
+ // ── Setup ────────────────────────────────────────────────────────────────────
43
+ describe("E-Invoice Integration Tests — live api.frihet.io", () => {
44
+ let tools;
45
+ before(async () => {
46
+ if (!LIVE)
47
+ return;
48
+ if (!API_KEY)
49
+ throw new Error("FRIHET_API_KEY env var required for live tests");
50
+ const { FrihetClient } = await import("../client.js");
51
+ const { registerEInvoiceTools } = await import("../tools/einvoice.js");
52
+ const client = new FrihetClient(API_KEY);
53
+ const server = new StubMcpServer();
54
+ registerEInvoiceTools(server, client);
55
+ tools = server.tools;
56
+ });
57
+ // ── send_einvoice ──
58
+ skip("send_einvoice — dispatches invoice or returns 404-fallback stub", async () => {
59
+ const tool = tools.get("send_einvoice");
60
+ // Use a known test invoice ID from your Frihet sandbox
61
+ const result = await tool.handler({
62
+ invoiceId: process.env["TEST_INVOICE_ID"] ?? "inv_test_integration",
63
+ format: "xrechnung-cii",
64
+ dispatchMode: "download",
65
+ });
66
+ const sc = result.structuredContent;
67
+ if (sc["_stub"]) {
68
+ // CF endpoint not yet deployed — fallback is correct
69
+ assert.equal(sc["_note"], "CF endpoint pending deploy");
70
+ assert.ok(typeof sc["_plannedEndpoint"] === "string");
71
+ console.log("send_einvoice: 404-fallback stub (CF not yet deployed)");
72
+ }
73
+ else {
74
+ // Live response
75
+ assert.ok(typeof sc["workflowRunId"] === "string", "workflowRunId should be string");
76
+ assert.equal(sc["status"], "queued");
77
+ assert.ok(typeof sc["estimatedCompletionSec"] === "number");
78
+ console.log(`send_einvoice: queued workflowRunId=${sc["workflowRunId"]}`);
79
+ }
80
+ });
81
+ // ── get_einvoice_status ──
82
+ skip("get_einvoice_status — polls status or returns 404-fallback stub", async () => {
83
+ const tool = tools.get("get_einvoice_status");
84
+ const result = await tool.handler({
85
+ workflowRunId: process.env["TEST_WORKFLOW_RUN_ID"] ?? "wfr_test_integration",
86
+ });
87
+ const sc = result.structuredContent;
88
+ if (sc["_stub"]) {
89
+ assert.equal(sc["_note"], "CF endpoint pending deploy");
90
+ console.log("get_einvoice_status: 404-fallback stub (CF not yet deployed)");
91
+ }
92
+ else {
93
+ const validStatuses = ["queued", "running", "succeeded", "failed", "cancelled"];
94
+ assert.ok(validStatuses.includes(sc["status"]), `unexpected status: ${sc["status"]}`);
95
+ console.log(`get_einvoice_status: status=${sc["status"]} step=${sc["step"]}`);
96
+ }
97
+ });
98
+ // ── validate_einvoice_xml ──
99
+ skip("validate_einvoice_xml — validates XML or returns 404-fallback stub", async () => {
100
+ const tool = tools.get("validate_einvoice_xml");
101
+ // Minimal XRechnung CII document (intentionally invalid to test error reporting)
102
+ const minimalXml = `<?xml version="1.0" encoding="UTF-8"?>
103
+ <rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100">
104
+ <rsm:ExchangedDocumentContext/>
105
+ <rsm:ExchangedDocument/>
106
+ <rsm:SupplyChainTradeTransaction/>
107
+ </rsm:CrossIndustryInvoice>`;
108
+ const result = await tool.handler({ xml: minimalXml, format: "xrechnung-cii" });
109
+ const sc = result.structuredContent;
110
+ if (sc["_stub"]) {
111
+ assert.equal(sc["_note"], "CF endpoint pending deploy");
112
+ console.log("validate_einvoice_xml: 404-fallback stub (CF not yet deployed)");
113
+ }
114
+ else {
115
+ assert.ok(typeof sc["valid"] === "boolean");
116
+ assert.ok(Array.isArray(sc["errors"]));
117
+ assert.ok(typeof sc["durationMs"] === "number");
118
+ console.log(`validate_einvoice_xml: valid=${sc["valid"]} errors=${sc["errors"].length} durationMs=${sc["durationMs"]}`);
119
+ }
120
+ });
121
+ // ── export_datev ──
122
+ skip("export_datev — exports DATEV EXTF or returns 404-fallback stub", async () => {
123
+ const tool = tools.get("export_datev");
124
+ const result = await tool.handler({
125
+ periodStart: "2026-01-01",
126
+ periodEnd: "2026-01-31",
127
+ format: "extf-buchungsstapel",
128
+ });
129
+ const sc = result.structuredContent;
130
+ if (sc["_stub"]) {
131
+ assert.equal(sc["_note"], "CF endpoint pending deploy");
132
+ console.log("export_datev: 404-fallback stub (CF not yet deployed)");
133
+ }
134
+ else {
135
+ assert.ok(typeof sc["fileUrl"] === "string" && sc["fileUrl"].startsWith("https://"));
136
+ assert.equal(sc["encoding"], "cp1252");
137
+ assert.ok(typeof sc["rowCount"] === "number");
138
+ console.log(`export_datev: filename=${sc["filename"]} rowCount=${sc["rowCount"]} fileUrl=${sc["fileUrl"]}`);
139
+ }
140
+ });
141
+ });
142
+ //# sourceMappingURL=einvoice-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"einvoice-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/einvoice-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Tests for e-invoice MCP tools — wired to api.frihet.io with 404-fallback stubs.
3
+ *
4
+ * Uses Node.js built-in test runner (node:test + node:assert) — no extra deps.
5
+ * Run: node --experimental-strip-types --test src/__tests__/einvoice-tools.test.ts
6
+ * Or via: npm test (after build: node --test dist/__tests__/einvoice-tools.test.js)
7
+ *
8
+ * Coverage:
9
+ * 1. Tool registration — all 4 tools registered on McpServer (62→66)
10
+ * 2. 404-fallback path — when CF endpoint returns 404, stub fallback fires
11
+ * 3. Success path — when CF endpoint returns real data, it is passed through
12
+ * 4. Stub response shape — matches declared outputSchema (via fallback)
13
+ * 5. Langfuse wrapper confirmed invoked via traceMCPTool patch
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=einvoice-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"einvoice-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/einvoice-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}