@frihet/mcp-server 1.7.0-beta.1 → 1.12.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.
- package/README.md +262 -12
- package/dist/__tests__/banking-tools.test.d.ts +18 -0
- package/dist/__tests__/banking-tools.test.d.ts.map +1 -0
- package/dist/__tests__/banking-tools.test.js +252 -0
- package/dist/__tests__/banking-tools.test.js.map +1 -0
- package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.d.ts +13 -0
- package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.d.ts.map +1 -0
- package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.js +420 -0
- package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.js.map +1 -0
- package/dist/__tests__/einvoice-day4-tools.test.d.ts +16 -0
- package/dist/__tests__/einvoice-day4-tools.test.d.ts.map +1 -0
- package/dist/__tests__/einvoice-day4-tools.test.js +377 -0
- package/dist/__tests__/einvoice-day4-tools.test.js.map +1 -0
- package/dist/__tests__/einvoice-tools.test.d.ts +1 -1
- package/dist/__tests__/einvoice-tools.test.js +25 -12
- package/dist/__tests__/einvoice-tools.test.js.map +1 -1
- package/dist/__tests__/fiscal-tools.test.d.ts +21 -0
- package/dist/__tests__/fiscal-tools.test.d.ts.map +1 -0
- package/dist/__tests__/fiscal-tools.test.js +215 -0
- package/dist/__tests__/fiscal-tools.test.js.map +1 -0
- package/dist/__tests__/pos-tools.test.d.ts +16 -0
- package/dist/__tests__/pos-tools.test.d.ts.map +1 -0
- package/dist/__tests__/pos-tools.test.js +244 -0
- package/dist/__tests__/pos-tools.test.js.map +1 -0
- package/dist/__tests__/recurring-tools.test.d.ts +23 -0
- package/dist/__tests__/recurring-tools.test.d.ts.map +1 -0
- package/dist/__tests__/recurring-tools.test.js +352 -0
- package/dist/__tests__/recurring-tools.test.js.map +1 -0
- package/dist/__tests__/stay-tools.test.d.ts +17 -0
- package/dist/__tests__/stay-tools.test.d.ts.map +1 -0
- package/dist/__tests__/stay-tools.test.js +259 -0
- package/dist/__tests__/stay-tools.test.js.map +1 -0
- package/dist/__tests__/team-tools.test.d.ts +18 -0
- package/dist/__tests__/team-tools.test.d.ts.map +1 -0
- package/dist/__tests__/team-tools.test.js +228 -0
- package/dist/__tests__/team-tools.test.js.map +1 -0
- package/dist/__tests__/time-tools.test.d.ts +19 -0
- package/dist/__tests__/time-tools.test.d.ts.map +1 -0
- package/dist/__tests__/time-tools.test.js +286 -0
- package/dist/__tests__/time-tools.test.js.map +1 -0
- package/dist/client-interface.d.ts +325 -0
- package/dist/client-interface.d.ts.map +1 -1
- package/dist/client.d.ts +325 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +404 -0
- package/dist/client.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/tools/accountingClose.d.ts +20 -0
- package/dist/tools/accountingClose.d.ts.map +1 -0
- package/dist/tools/accountingClose.js +119 -0
- package/dist/tools/accountingClose.js.map +1 -0
- package/dist/tools/audit_gl.d.ts +19 -0
- package/dist/tools/audit_gl.d.ts.map +1 -0
- package/dist/tools/audit_gl.js +86 -0
- package/dist/tools/audit_gl.js.map +1 -0
- package/dist/tools/bank_rules.d.ts +23 -0
- package/dist/tools/bank_rules.d.ts.map +1 -0
- package/dist/tools/bank_rules.js +96 -0
- package/dist/tools/bank_rules.js.map +1 -0
- package/dist/tools/banking.d.ts +19 -0
- package/dist/tools/banking.d.ts.map +1 -0
- package/dist/tools/banking.js +155 -0
- package/dist/tools/banking.js.map +1 -0
- package/dist/tools/einvoice.d.ts +70 -3
- package/dist/tools/einvoice.d.ts.map +1 -1
- package/dist/tools/einvoice.js +421 -3
- package/dist/tools/einvoice.js.map +1 -1
- package/dist/tools/fiscal.d.ts +23 -0
- package/dist/tools/fiscal.d.ts.map +1 -0
- package/dist/tools/fiscal.js +197 -0
- package/dist/tools/fiscal.js.map +1 -0
- package/dist/tools/gestoria.d.ts +28 -0
- package/dist/tools/gestoria.d.ts.map +1 -0
- package/dist/tools/gestoria.js +248 -0
- package/dist/tools/gestoria.js.map +1 -0
- package/dist/tools/hr.d.ts +24 -0
- package/dist/tools/hr.d.ts.map +1 -0
- package/dist/tools/hr.js +219 -0
- package/dist/tools/hr.js.map +1 -0
- package/dist/tools/igic.d.ts +19 -0
- package/dist/tools/igic.d.ts.map +1 -0
- package/dist/tools/igic.js +102 -0
- package/dist/tools/igic.js.map +1 -0
- package/dist/tools/impuesto_sociedades.d.ts +18 -0
- package/dist/tools/impuesto_sociedades.d.ts.map +1 -0
- package/dist/tools/impuesto_sociedades.js +64 -0
- package/dist/tools/impuesto_sociedades.js.map +1 -0
- package/dist/tools/onboard_vies.d.ts +22 -0
- package/dist/tools/onboard_vies.d.ts.map +1 -0
- package/dist/tools/onboard_vies.js +74 -0
- package/dist/tools/onboard_vies.js.map +1 -0
- package/dist/tools/onboarding.d.ts +19 -0
- package/dist/tools/onboarding.d.ts.map +1 -0
- package/dist/tools/onboarding.js +63 -0
- package/dist/tools/onboarding.js.map +1 -0
- package/dist/tools/payroll.d.ts +20 -0
- package/dist/tools/payroll.d.ts.map +1 -0
- package/dist/tools/payroll.js +73 -0
- package/dist/tools/payroll.js.map +1 -0
- package/dist/tools/permissions.d.ts +19 -0
- package/dist/tools/permissions.d.ts.map +1 -0
- package/dist/tools/permissions.js +52 -0
- package/dist/tools/permissions.js.map +1 -0
- package/dist/tools/portal_domain.d.ts +19 -0
- package/dist/tools/portal_domain.d.ts.map +1 -0
- package/dist/tools/portal_domain.js +85 -0
- package/dist/tools/portal_domain.js.map +1 -0
- package/dist/tools/pos.d.ts +15 -0
- package/dist/tools/pos.d.ts.map +1 -0
- package/dist/tools/pos.js +156 -0
- package/dist/tools/pos.js.map +1 -0
- package/dist/tools/recurring.d.ts +21 -0
- package/dist/tools/recurring.d.ts.map +1 -0
- package/dist/tools/recurring.js +239 -0
- package/dist/tools/recurring.js.map +1 -0
- package/dist/tools/register-all.d.ts +2 -2
- package/dist/tools/register-all.d.ts.map +1 -1
- package/dist/tools/register-all.js +53 -3
- package/dist/tools/register-all.js.map +1 -1
- package/dist/tools/shared.d.ts +481 -0
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +396 -0
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/stay.d.ts +6 -78
- package/dist/tools/stay.d.ts.map +1 -1
- package/dist/tools/stay.js +121 -343
- package/dist/tools/stay.js.map +1 -1
- package/dist/tools/team.d.ts +17 -0
- package/dist/tools/team.d.ts.map +1 -0
- package/dist/tools/team.js +141 -0
- package/dist/tools/team.js.map +1 -0
- package/dist/tools/time.d.ts +19 -0
- package/dist/tools/time.d.ts.map +1 -0
- package/dist/tools/time.js +179 -0
- package/dist/tools/time.js.map +1 -0
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +27 -1
- package/dist/tools/webhooks.js.map +1 -1
- package/package.json +12 -5
- package/scripts/audit-mcp-refs.mjs +331 -0
package/README.md
CHANGED
|
@@ -17,13 +17,30 @@
|
|
|
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-
|
|
20
|
+
<img src="https://img.shields.io/badge/tools-151-18181b?style=flat&labelColor=09090b" alt="151 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>
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
+
## Distribution
|
|
28
|
+
|
|
29
|
+
| Channel | Status | Install |
|
|
30
|
+
|---------|--------|---------|
|
|
31
|
+
| **npm** | Live | `npx @frihet/mcp-server` |
|
|
32
|
+
| **Remote endpoint** | Live | `https://mcp.frihet.io/mcp` (zero install, OAuth or API key) |
|
|
33
|
+
| **Smithery** | Live | [smithery.ai/server/frihet/frihet-mcp](https://smithery.ai/server/frihet/frihet-mcp) |
|
|
34
|
+
| **MCP Registry** | Live | [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io/?q=io.frihet) |
|
|
35
|
+
| **Glama** | Pending submission | [glama.ai/mcp/servers](https://glama.ai/mcp/servers) — `glama.json` ready |
|
|
36
|
+
| **mcp.so** | Pending submission | [mcp.so](https://mcp.so) — indexed from npm + GitHub |
|
|
37
|
+
| **PulseMCP** | Pending submission | [pulsemcp.com](https://pulsemcp.com) — indexed from npm + GitHub |
|
|
38
|
+
| **Cursor Marketplace** | Coming soon | [cursor.com/marketplace](https://cursor.com/marketplace) |
|
|
39
|
+
| **ChatGPT Apps** | Coming soon | [chatgpt.com](https://chatgpt.com) |
|
|
40
|
+
| **Anthropic Claude Directory** | Coming soon | [claude.ai/settings/connectors](https://claude.ai/settings/connectors) |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
27
44
|
## What is this
|
|
28
45
|
|
|
29
46
|
An MCP server that connects your AI assistant to [Frihet](https://frihet.io). Create invoices by talking. Query expenses in natural language. Manage your entire business from your IDE.
|
|
@@ -33,7 +50,9 @@ You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/h
|
|
|
33
50
|
Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
|
|
34
51
|
```
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
151 tools. 8 resources. 7 prompts. Structured output on every tool. Zero boilerplate.
|
|
54
|
+
|
|
55
|
+
<!-- v1.12.0-beta.1 — D4-B megasprint: HR (9), payroll (2), onboarding (2), permissions (2), period close (3), webhook test (1) = +19 = 152 raw → deduped ticketbai_status → 151 tools -->
|
|
37
56
|
|
|
38
57
|
---
|
|
39
58
|
|
|
@@ -161,7 +180,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
161
180
|
|
|
162
181
|
## What to expect
|
|
163
182
|
|
|
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
|
|
183
|
+
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 151 tools are CRUD operations over the REST API.
|
|
165
184
|
|
|
166
185
|
**Works great:**
|
|
167
186
|
|
|
@@ -188,9 +207,9 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
188
207
|
|
|
189
208
|
---
|
|
190
209
|
|
|
191
|
-
## Tools (
|
|
210
|
+
## Tools (151)
|
|
192
211
|
|
|
193
|
-
### Invoices (
|
|
212
|
+
### Invoices (12)
|
|
194
213
|
|
|
195
214
|
| Tool | What it does |
|
|
196
215
|
|------|-------------|
|
|
@@ -199,7 +218,13 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
199
218
|
| `create_invoice` | Create a new invoice with line items |
|
|
200
219
|
| `update_invoice` | Update any invoice field |
|
|
201
220
|
| `delete_invoice` | Permanently delete an invoice |
|
|
202
|
-
| `search_invoices` | Find invoices by client name |
|
|
221
|
+
| `search_invoices` | Find invoices by client name, date, or status |
|
|
222
|
+
| `send_invoice` | Email invoice to client (PDF attachment) |
|
|
223
|
+
| `mark_invoice_paid` | Mark an invoice as paid with optional payment date |
|
|
224
|
+
| `get_invoice_pdf` | Get a download URL for the invoice PDF |
|
|
225
|
+
| `get_invoice_einvoice` | Get the e-invoice XML for a given invoice ID |
|
|
226
|
+
| `create_credit_note` | Create a credit note linked to an existing invoice |
|
|
227
|
+
| `apply_late_fee` | Apply a late payment fee to an overdue invoice |
|
|
203
228
|
|
|
204
229
|
### Expenses (5)
|
|
205
230
|
|
|
@@ -254,7 +279,7 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
254
279
|
| `update_product` | Update pricing or details |
|
|
255
280
|
| `delete_product` | Remove a product |
|
|
256
281
|
|
|
257
|
-
### Quotes (
|
|
282
|
+
### Quotes (6)
|
|
258
283
|
|
|
259
284
|
| Tool | What it does |
|
|
260
285
|
|------|-------------|
|
|
@@ -263,8 +288,9 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
263
288
|
| `create_quote` | Draft a new quote |
|
|
264
289
|
| `update_quote` | Modify a quote |
|
|
265
290
|
| `delete_quote` | Delete a quote |
|
|
291
|
+
| `send_quote` | Email quote to client for acceptance |
|
|
266
292
|
|
|
267
|
-
### Webhooks (
|
|
293
|
+
### Webhooks (6)
|
|
268
294
|
|
|
269
295
|
| Tool | What it does |
|
|
270
296
|
|------|-------------|
|
|
@@ -273,6 +299,7 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
273
299
|
| `create_webhook` | Register a new webhook endpoint |
|
|
274
300
|
| `update_webhook` | Modify events or URL |
|
|
275
301
|
| `delete_webhook` | Remove a webhook |
|
|
302
|
+
| `test_webhook` | Send a test payload to a configured webhook endpoint |
|
|
276
303
|
|
|
277
304
|
### Intelligence (4)
|
|
278
305
|
|
|
@@ -283,9 +310,9 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
283
310
|
| `get_quarterly_taxes` | Quarterly tax prep: Modelo 303/130 fields, collected vs deductible, liability |
|
|
284
311
|
| `duplicate_invoice` | Clone an invoice for recurring billing (copies items/client/tax, starts as draft) |
|
|
285
312
|
|
|
286
|
-
|
|
313
|
+
### E-Invoicing (10)
|
|
287
314
|
|
|
288
|
-
> **Status: beta
|
|
315
|
+
> **Status: beta.** 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.
|
|
289
316
|
|
|
290
317
|
| Tool | What it does |
|
|
291
318
|
|------|-------------|
|
|
@@ -293,8 +320,230 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
293
320
|
| `get_einvoice_status` | Poll Hatchet workflow run status until succeeded/failed — returns ackId, XML URL, PDF/A-3 URL |
|
|
294
321
|
| `validate_einvoice_xml` | Validate raw XML against format schema + schematron rules (KOSIT / Mustang / XSD / Schematron) |
|
|
295
322
|
| `export_datev` | Export accounting data as DATEV EXTF (Buchungsstapel / Debitoren / Kreditoren) in CP1252 encoding |
|
|
323
|
+
| `einvoice_export` | Export e-invoice data in machine-readable formats (JSON/XML) for archival or integration |
|
|
324
|
+
| `face_submit` | Submit invoice to FACe (Spain B2G government e-invoicing platform) |
|
|
325
|
+
| `face_status` | Poll submission status from FACe for a submitted invoice |
|
|
326
|
+
| `ticketbai_submit` | Submit TicketBAI fiscal record to Basque Country tax authority (Hacienda) |
|
|
327
|
+
| `ticketbai_status` | Poll TicketBAI submission status from the Basque tax authority |
|
|
328
|
+
| `ksef_submit` | Submit invoice to KSeF (Poland national e-invoicing system — stub) |
|
|
329
|
+
|
|
330
|
+
### Time Tracking (6)
|
|
331
|
+
|
|
332
|
+
> **Status: stub** — `/v1/time/*` endpoints planned. Tools surface 404 until backend ships.
|
|
333
|
+
|
|
334
|
+
| Tool | What it does |
|
|
335
|
+
|------|-------------|
|
|
336
|
+
| `list_time_entries` | List time entries with filter by user, project, date range, billable status |
|
|
337
|
+
| `get_time_entry` | Get full details of a single time entry by ID |
|
|
338
|
+
| `create_time_entry` | Log hours for a project (billable flag, description, date) |
|
|
339
|
+
| `update_time_entry` | Update any field on an existing time entry (PATCH semantics) |
|
|
340
|
+
| `delete_time_entry` | Soft-delete a time entry (confirm=true required) |
|
|
341
|
+
| `get_time_summary` | Aggregate total/billable/non-billable hours for a period, with optional groupBy (user/project/day) |
|
|
342
|
+
|
|
343
|
+
### Recurring Invoices (8)
|
|
344
|
+
|
|
345
|
+
> **Status: stub** — `/v1/recurring/*` endpoints planned. Tools surface 404 until backend ships.
|
|
346
|
+
|
|
347
|
+
| Tool | What it does |
|
|
348
|
+
|------|-------------|
|
|
349
|
+
| `list_recurring_invoices` | List all recurring invoice templates (filter by active/paused) |
|
|
350
|
+
| `get_recurring_invoice` | Get full details of a recurring template by ID |
|
|
351
|
+
| `create_recurring_invoice` | Create a new recurring invoice template (daily/weekly/monthly/quarterly/yearly) |
|
|
352
|
+
| `update_recurring_invoice` | Update template fields — affects future generated invoices only |
|
|
353
|
+
| `pause_recurring_invoice` | Pause an active template — no invoices generated while paused |
|
|
354
|
+
| `resume_recurring_invoice` | Resume a paused template — next invoice on next scheduled cycle |
|
|
355
|
+
| `delete_recurring_invoice` | Permanently delete a template (confirm=true required) |
|
|
356
|
+
| `run_recurring_now` | Manually trigger immediate generation of the next invoice instance |
|
|
357
|
+
|
|
358
|
+
### Team Management (4)
|
|
359
|
+
|
|
360
|
+
> **Status: stub** — `/v1/team/*` endpoints planned. Tools surface 404 until backend ships.
|
|
361
|
+
|
|
362
|
+
| Tool | What it does |
|
|
363
|
+
|------|-------------|
|
|
364
|
+
| `list_team_members` | List all workspace members with role and invite status |
|
|
365
|
+
| `invite_team_member` | Invite a new member by email with role (admin/member/viewer) |
|
|
366
|
+
| `update_team_member_role` | Change an existing member's role |
|
|
367
|
+
| `remove_team_member` | Remove a member from the workspace (confirm=true required) |
|
|
368
|
+
|
|
369
|
+
### Gestoria — Accountants (5)
|
|
370
|
+
|
|
371
|
+
> **Status: stub** — `/v1/gestoria/*` REST surface lands with Wave Fase 1 closure (PRs #383 bulk send, #384 aging, #385 messaging). Tools surface 404 until the backend ships.
|
|
372
|
+
|
|
373
|
+
| Tool | What it does |
|
|
374
|
+
|------|-------------|
|
|
375
|
+
| `gestoria_message_send` | Send a message in a contextual thread (documentRequest / filingItem / obligation) |
|
|
376
|
+
| `gestoria_messages_list` | List messages in a thread, newest first; paginate backwards with `before` |
|
|
377
|
+
| `gestoria_template_create` | Create a reusable document request template with variables + due-date offset |
|
|
378
|
+
| `gestoria_template_bulk_send` | Bulk send a template to up to 500 client workspaces in one call |
|
|
379
|
+
| `gestoria_aging_consolidated` | Cross-client AR aging report (buckets, per-workspace breakdown, top overdue) |
|
|
380
|
+
|
|
381
|
+
### Audit GL (3)
|
|
382
|
+
|
|
383
|
+
> **Status: stub** — `/v1/gl/*` proxies callables `approveGLEntry`, `rejectGLEntry`, `getGLEntryAuditLog` (PR #395). Tools surface 404 until backend ships.
|
|
384
|
+
|
|
385
|
+
| Tool | What it does |
|
|
386
|
+
|------|-------------|
|
|
387
|
+
| `frihet_gl_entry_approve` | Approve a GL journal entry (gestor/admin only — TRUST AREA) |
|
|
388
|
+
| `frihet_gl_entry_reject` | Reject a GL entry with a mandatory reason (TRUST AREA) |
|
|
389
|
+
| `frihet_gl_entry_audit_log` | Retrieve full audit trail for a GL entry |
|
|
390
|
+
|
|
391
|
+
### White-label Portal Domain (3)
|
|
392
|
+
|
|
393
|
+
> **Status: stub** — `/v1/portal/domain/*` proxies callables `addCustomPortalDomain`, `verifyCustomPortalDomain`, `removeCustomPortalDomain` (PR #397).
|
|
394
|
+
|
|
395
|
+
| Tool | What it does |
|
|
396
|
+
|------|-------------|
|
|
397
|
+
| `frihet_portal_domain_add` | Add a custom domain to the client portal (returns DNS CNAME records) |
|
|
398
|
+
| `frihet_portal_domain_verify` | Verify DNS propagation for a custom portal domain |
|
|
399
|
+
| `frihet_portal_domain_remove` | Remove a custom portal domain (reverts to default Frihet subdomain) |
|
|
400
|
+
|
|
401
|
+
### Self-onboard & VIES (2)
|
|
402
|
+
|
|
403
|
+
> **Status: stub** — `/v1/portal/onboard/*` proxies callables `generatePortalOnboardLink`, `lookupTaxIdViaVIES` (PR #398). Public portal flows excluded from MCP.
|
|
404
|
+
|
|
405
|
+
| Tool | What it does |
|
|
406
|
+
|------|-------------|
|
|
407
|
+
| `frihet_portal_onboard_link_generate` | Generate a time-limited self-onboard link for a prospective client |
|
|
408
|
+
| `frihet_tax_id_vies_lookup` | Validate an EU VAT number (CIF intracomunitario) via VIES |
|
|
409
|
+
|
|
410
|
+
### IGIC — Canary Islands Indirect Tax (4)
|
|
411
|
+
|
|
412
|
+
> **Status: stub** — `/v1/igic/*` service-layer reads (PR #390). ATC SOAP excluded (internal infra).
|
|
413
|
+
|
|
414
|
+
| Tool | What it does |
|
|
415
|
+
|------|-------------|
|
|
416
|
+
| `frihet_modelo_415_summary` | M415 annual operations >€3,005 (Canarias equivalent of M347) |
|
|
417
|
+
| `frihet_modelo_425_summary` | M425 annual IGIC recap for Canary Islands businesses |
|
|
418
|
+
| `frihet_modelo_418_summary` | M418 monthly IGIC return for large enterprises (grandes empresas) |
|
|
419
|
+
| `frihet_aiem_calculate` | Calculate AIEM (Arbitrio Importación) for imported/produced goods in Canarias |
|
|
420
|
+
|
|
421
|
+
### Impuesto sobre Sociedades — Corporate Tax (2)
|
|
422
|
+
|
|
423
|
+
> **Status: stub** — `/v1/is/*` service-layer reads for Spanish SLs/SAs (PR #392).
|
|
424
|
+
|
|
425
|
+
| Tool | What it does |
|
|
426
|
+
|------|-------------|
|
|
427
|
+
| `frihet_modelo_200_summary` | Modelo 200 annual IS return (taxable base, deductions, net payable) |
|
|
428
|
+
| `frihet_modelo_202_summary` | Modelo 202 installment payments (1P April, 2P October, 3P December) |
|
|
429
|
+
|
|
430
|
+
### Bank Categorization Rules (2)
|
|
431
|
+
|
|
432
|
+
> **Status: stub** — `/v1/banking/rules` Q3-flagged (PR #394). Webhook handlers excluded.
|
|
433
|
+
|
|
434
|
+
| Tool | What it does |
|
|
435
|
+
|------|-------------|
|
|
436
|
+
| `frihet_bank_rules_list` | List all bank auto-categorization rules (conditions + actions + status) |
|
|
437
|
+
| `frihet_bank_rule_create` | Create a new rule to auto-categorize transactions by description, amount, counterparty |
|
|
438
|
+
|
|
439
|
+
### Deposits (7)
|
|
440
|
+
|
|
441
|
+
| Tool | What it does |
|
|
442
|
+
|------|-------------|
|
|
443
|
+
| `list_deposits` | List deposits with pagination |
|
|
444
|
+
| `get_deposit` | Get deposit details by ID |
|
|
445
|
+
| `create_deposit` | Record a new client deposit |
|
|
446
|
+
| `update_deposit` | Update deposit fields |
|
|
447
|
+
| `delete_deposit` | Delete a deposit (confirm=true required) |
|
|
448
|
+
| `apply_deposit` | Apply a deposit balance against an invoice |
|
|
449
|
+
| `refund_deposit` | Issue a refund for a deposit |
|
|
450
|
+
|
|
451
|
+
### Vendors (5)
|
|
452
|
+
|
|
453
|
+
| Tool | What it does |
|
|
454
|
+
|------|-------------|
|
|
455
|
+
| `list_vendors` | List all vendors/suppliers |
|
|
456
|
+
| `get_vendor` | Get vendor details |
|
|
457
|
+
| `create_vendor` | Add a new vendor |
|
|
458
|
+
| `update_vendor` | Update vendor info |
|
|
459
|
+
| `delete_vendor` | Remove a vendor |
|
|
460
|
+
|
|
461
|
+
### Banking (5)
|
|
462
|
+
|
|
463
|
+
| Tool | What it does |
|
|
464
|
+
|------|-------------|
|
|
465
|
+
| `list_bank_accounts` | List connected bank accounts |
|
|
466
|
+
| `get_bank_account` | Get details for a bank account |
|
|
467
|
+
| `list_transactions` | List bank transactions with filters |
|
|
468
|
+
| `categorize_transaction` | Assign a category and expense/income type to a transaction |
|
|
469
|
+
| `match_transaction_to_invoice` | Link a bank transaction to an existing invoice |
|
|
470
|
+
|
|
471
|
+
### Fiscal — Spanish Tax Models (8)
|
|
472
|
+
|
|
473
|
+
| Tool | What it does |
|
|
474
|
+
|------|-------------|
|
|
475
|
+
| `get_modelo_303_summary` | Quarterly IVA return (Modelo 303) — collected vs deductible, net payable |
|
|
476
|
+
| `get_modelo_130_summary` | Quarterly IRPF installment for self-employed (Modelo 130) |
|
|
477
|
+
| `get_modelo_390_summary` | Annual IVA summary (Modelo 390) |
|
|
478
|
+
| `get_modelo_180_summary` | Annual withholding summary for rentals (Modelo 180) |
|
|
479
|
+
| `get_modelo_347_summary` | Annual third-party transactions >€3,005 (Modelo 347) |
|
|
480
|
+
| `verifactu_status` | Get VeriFactu submission status for a fiscal record |
|
|
481
|
+
| `verifactu_resubmit` | Resubmit a rejected VeriFactu fiscal record |
|
|
482
|
+
| `ticketbai_status` | Poll TicketBAI submission status (also available in E-Invoicing section) |
|
|
483
|
+
|
|
484
|
+
### Vacation Rentals / Stay (5)
|
|
485
|
+
|
|
486
|
+
| Tool | What it does |
|
|
487
|
+
|------|-------------|
|
|
488
|
+
| `list_reservations` | List rental reservations with filters |
|
|
489
|
+
| `get_reservation` | Get reservation details |
|
|
490
|
+
| `create_reservation` | Create a new reservation |
|
|
491
|
+
| `list_properties` | List all rental properties |
|
|
492
|
+
| `sync_channel` | Trigger OTA channel sync (Airbnb, Booking.com, etc.) |
|
|
493
|
+
|
|
494
|
+
### POS — Point of Sale (4)
|
|
495
|
+
|
|
496
|
+
| Tool | What it does |
|
|
497
|
+
|------|-------------|
|
|
498
|
+
| `list_terminals` | List registered POS terminals |
|
|
499
|
+
| `get_sale` | Get details for a POS sale transaction |
|
|
500
|
+
| `list_sales` | List POS sales with pagination |
|
|
501
|
+
| `refund_sale` | Issue a refund for a POS sale |
|
|
502
|
+
|
|
503
|
+
### HR — Human Resources (9)
|
|
504
|
+
|
|
505
|
+
| Tool | What it does |
|
|
506
|
+
|------|-------------|
|
|
507
|
+
| `leave_request_create` | Create a leave request (vacation, sick, personal) |
|
|
508
|
+
| `leave_approve` | Approve a pending leave request |
|
|
509
|
+
| `leave_reject` | Reject a leave request with a reason |
|
|
510
|
+
| `leave_cancel` | Cancel an approved or pending leave request |
|
|
511
|
+
| `leave_list` | List leave requests with filters (user, status, date range) |
|
|
512
|
+
| `attendance_clock_in` | Record clock-in for an employee |
|
|
513
|
+
| `attendance_clock_out` | Record clock-out for an employee |
|
|
514
|
+
| `overtime_report` | Generate overtime report for a period |
|
|
515
|
+
| `anomaly_list` | List attendance anomalies (missing punches, excessive overtime) |
|
|
516
|
+
|
|
517
|
+
### Payroll (2)
|
|
518
|
+
|
|
519
|
+
| Tool | What it does |
|
|
520
|
+
|------|-------------|
|
|
521
|
+
| `payroll_export` | Export payroll data for a period (CSV/PDF for gestoría) |
|
|
522
|
+
| `payroll_checklist` | Generate pre-payroll checklist: pending leaves, anomalies, overtime |
|
|
523
|
+
|
|
524
|
+
### Onboarding (2)
|
|
525
|
+
|
|
526
|
+
| Tool | What it does |
|
|
527
|
+
|------|-------------|
|
|
528
|
+
| `onboarding_status` | Get onboarding completion status for the current workspace |
|
|
529
|
+
| `onboarding_persona_set` | Set or update the business persona (freelancer, SME, gestoría, etc.) |
|
|
530
|
+
|
|
531
|
+
### Permissions (2)
|
|
532
|
+
|
|
533
|
+
| Tool | What it does |
|
|
534
|
+
|------|-------------|
|
|
535
|
+
| `permissions_matrix` | Get the full permissions matrix for all roles in the workspace |
|
|
536
|
+
| `permissions_me` | Get the current API key's effective permissions |
|
|
537
|
+
|
|
538
|
+
### Period Close (3)
|
|
539
|
+
|
|
540
|
+
| Tool | What it does |
|
|
541
|
+
|------|-------------|
|
|
542
|
+
| `period_close_status` | Get the close status for an accounting period |
|
|
543
|
+
| `period_close` | Close an accounting period (gestor/admin only — TRUST AREA) |
|
|
544
|
+
| `period_reopen` | Reopen a closed period with a mandatory reason (TRUST AREA) |
|
|
296
545
|
|
|
297
|
-
All
|
|
546
|
+
All 151 tools return **structured output** via `outputSchema` -- typed JSON, not raw text. List tools return paginated results (`{ data, total, limit, offset }`).
|
|
298
547
|
|
|
299
548
|
---
|
|
300
549
|
|
|
@@ -473,7 +722,7 @@ npm run build # must pass before submitting
|
|
|
473
722
|
|
|
474
723
|
| Package | What it is |
|
|
475
724
|
|---------|-----------|
|
|
476
|
-
| [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (
|
|
725
|
+
| [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (151 tools, 8 resources, 7 prompts) |
|
|
477
726
|
| [`@frihet/sdk`](https://github.com/Frihet-io/frihet-sdk) | TypeScript SDK (`frihet.invoices.create()`) |
|
|
478
727
|
| [`frihet`](https://www.npmjs.com/package/frihet) | CLI (`frihet invoices list --status overdue`) |
|
|
479
728
|
| [`n8n-nodes-frihet`](https://www.npmjs.com/package/n8n-nodes-frihet) | n8n community node for workflow automation |
|
|
@@ -489,6 +738,7 @@ npm run build # must pass before submitting
|
|
|
489
738
|
- [MCP server docs](https://docs.frihet.io/desarrolladores/mcp-server) -- Setup guides, troubleshooting
|
|
490
739
|
- [npm](https://www.npmjs.com/package/@frihet/mcp-server) -- Package registry
|
|
491
740
|
- [Smithery](https://smithery.ai/server/frihet/frihet-mcp) -- Smithery marketplace
|
|
741
|
+
- [MCP Registry](https://registry.modelcontextprotocol.io/?q=io.frihet) -- Anthropic official registry
|
|
492
742
|
- [Remote endpoint](https://mcp.frihet.io) -- Hosted MCP server (Cloudflare Workers)
|
|
493
743
|
- [OpenAPI spec](https://api.frihet.io/openapi.yaml) -- Machine-readable API definition
|
|
494
744
|
|
|
@@ -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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"}
|