@frihet/mcp-server 1.16.3 → 1.16.4

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 (203) hide show
  1. package/README.md +1 -1
  2. package/dist/openai-profile.js +1 -1
  3. package/package.json +7 -4
  4. package/scripts/postinstall.js +30 -8
  5. package/dist/__tests__/audit-server-version.test.d.ts +0 -13
  6. package/dist/__tests__/audit-server-version.test.d.ts.map +0 -1
  7. package/dist/__tests__/audit-server-version.test.js +0 -96
  8. package/dist/__tests__/audit-server-version.test.js.map +0 -1
  9. package/dist/__tests__/banking-client-contract.test.d.ts +0 -20
  10. package/dist/__tests__/banking-client-contract.test.d.ts.map +0 -1
  11. package/dist/__tests__/banking-client-contract.test.js +0 -133
  12. package/dist/__tests__/banking-client-contract.test.js.map +0 -1
  13. package/dist/__tests__/banking-tools.test.d.ts +0 -18
  14. package/dist/__tests__/banking-tools.test.d.ts.map +0 -1
  15. package/dist/__tests__/banking-tools.test.js +0 -252
  16. package/dist/__tests__/banking-tools.test.js.map +0 -1
  17. package/dist/__tests__/contract.test.d.ts +0 -33
  18. package/dist/__tests__/contract.test.d.ts.map +0 -1
  19. package/dist/__tests__/contract.test.js +0 -208
  20. package/dist/__tests__/contract.test.js.map +0 -1
  21. package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.d.ts +0 -13
  22. package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.d.ts.map +0 -1
  23. package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.js +0 -420
  24. package/dist/__tests__/d4b-hr-payroll-onboarding-tools.test.js.map +0 -1
  25. package/dist/__tests__/demo-mode.test.d.ts +0 -11
  26. package/dist/__tests__/demo-mode.test.d.ts.map +0 -1
  27. package/dist/__tests__/demo-mode.test.js +0 -119
  28. package/dist/__tests__/demo-mode.test.js.map +0 -1
  29. package/dist/__tests__/einvoice-day4-tools.test.d.ts +0 -16
  30. package/dist/__tests__/einvoice-day4-tools.test.d.ts.map +0 -1
  31. package/dist/__tests__/einvoice-day4-tools.test.js +0 -421
  32. package/dist/__tests__/einvoice-day4-tools.test.js.map +0 -1
  33. package/dist/__tests__/einvoice-integration.test.d.ts +0 -24
  34. package/dist/__tests__/einvoice-integration.test.d.ts.map +0 -1
  35. package/dist/__tests__/einvoice-integration.test.js +0 -142
  36. package/dist/__tests__/einvoice-integration.test.js.map +0 -1
  37. package/dist/__tests__/einvoice-tools.test.d.ts +0 -16
  38. package/dist/__tests__/einvoice-tools.test.d.ts.map +0 -1
  39. package/dist/__tests__/einvoice-tools.test.js +0 -411
  40. package/dist/__tests__/einvoice-tools.test.js.map +0 -1
  41. package/dist/__tests__/fiscal-tools.test.d.ts +0 -21
  42. package/dist/__tests__/fiscal-tools.test.d.ts.map +0 -1
  43. package/dist/__tests__/fiscal-tools.test.js +0 -271
  44. package/dist/__tests__/fiscal-tools.test.js.map +0 -1
  45. package/dist/__tests__/get-envelope-unwrap-regression.test.d.ts +0 -27
  46. package/dist/__tests__/get-envelope-unwrap-regression.test.d.ts.map +0 -1
  47. package/dist/__tests__/get-envelope-unwrap-regression.test.js +0 -223
  48. package/dist/__tests__/get-envelope-unwrap-regression.test.js.map +0 -1
  49. package/dist/__tests__/intelligence-duplicate-invoice.test.d.ts +0 -14
  50. package/dist/__tests__/intelligence-duplicate-invoice.test.d.ts.map +0 -1
  51. package/dist/__tests__/intelligence-duplicate-invoice.test.js +0 -108
  52. package/dist/__tests__/intelligence-duplicate-invoice.test.js.map +0 -1
  53. package/dist/__tests__/kitchen-tools.test.d.ts +0 -18
  54. package/dist/__tests__/kitchen-tools.test.d.ts.map +0 -1
  55. package/dist/__tests__/kitchen-tools.test.js +0 -399
  56. package/dist/__tests__/kitchen-tools.test.js.map +0 -1
  57. package/dist/__tests__/mutation-unwrap-and-schema-regression.test.d.ts +0 -30
  58. package/dist/__tests__/mutation-unwrap-and-schema-regression.test.d.ts.map +0 -1
  59. package/dist/__tests__/mutation-unwrap-and-schema-regression.test.js +0 -164
  60. package/dist/__tests__/mutation-unwrap-and-schema-regression.test.js.map +0 -1
  61. package/dist/__tests__/observability-redaction.test.d.ts +0 -13
  62. package/dist/__tests__/observability-redaction.test.d.ts.map +0 -1
  63. package/dist/__tests__/observability-redaction.test.js +0 -94
  64. package/dist/__tests__/observability-redaction.test.js.map +0 -1
  65. package/dist/__tests__/openai-grouped-compose.test.d.ts +0 -26
  66. package/dist/__tests__/openai-grouped-compose.test.d.ts.map +0 -1
  67. package/dist/__tests__/openai-grouped-compose.test.js +0 -245
  68. package/dist/__tests__/openai-grouped-compose.test.js.map +0 -1
  69. package/dist/__tests__/openai-profile.test.d.ts +0 -10
  70. package/dist/__tests__/openai-profile.test.d.ts.map +0 -1
  71. package/dist/__tests__/openai-profile.test.js +0 -168
  72. package/dist/__tests__/openai-profile.test.js.map +0 -1
  73. package/dist/__tests__/pagination-cursor-param.test.d.ts +0 -27
  74. package/dist/__tests__/pagination-cursor-param.test.d.ts.map +0 -1
  75. package/dist/__tests__/pagination-cursor-param.test.js +0 -96
  76. package/dist/__tests__/pagination-cursor-param.test.js.map +0 -1
  77. package/dist/__tests__/pos-tools.test.d.ts +0 -16
  78. package/dist/__tests__/pos-tools.test.d.ts.map +0 -1
  79. package/dist/__tests__/pos-tools.test.js +0 -244
  80. package/dist/__tests__/pos-tools.test.js.map +0 -1
  81. package/dist/__tests__/recurring-tools.test.d.ts +0 -23
  82. package/dist/__tests__/recurring-tools.test.d.ts.map +0 -1
  83. package/dist/__tests__/recurring-tools.test.js +0 -352
  84. package/dist/__tests__/recurring-tools.test.js.map +0 -1
  85. package/dist/__tests__/schema-envelope-guard.test.d.ts +0 -18
  86. package/dist/__tests__/schema-envelope-guard.test.d.ts.map +0 -1
  87. package/dist/__tests__/schema-envelope-guard.test.js +0 -56
  88. package/dist/__tests__/schema-envelope-guard.test.js.map +0 -1
  89. package/dist/__tests__/stay-tools.test.d.ts +0 -17
  90. package/dist/__tests__/stay-tools.test.d.ts.map +0 -1
  91. package/dist/__tests__/stay-tools.test.js +0 -259
  92. package/dist/__tests__/stay-tools.test.js.map +0 -1
  93. package/dist/__tests__/team-tools.test.d.ts +0 -18
  94. package/dist/__tests__/team-tools.test.d.ts.map +0 -1
  95. package/dist/__tests__/team-tools.test.js +0 -228
  96. package/dist/__tests__/team-tools.test.js.map +0 -1
  97. package/dist/__tests__/time-tools.test.d.ts +0 -19
  98. package/dist/__tests__/time-tools.test.d.ts.map +0 -1
  99. package/dist/__tests__/time-tools.test.js +0 -286
  100. package/dist/__tests__/time-tools.test.js.map +0 -1
  101. package/dist/__tests__/tool-exposure.test.d.ts +0 -11
  102. package/dist/__tests__/tool-exposure.test.d.ts.map +0 -1
  103. package/dist/__tests__/tool-exposure.test.js +0 -264
  104. package/dist/__tests__/tool-exposure.test.js.map +0 -1
  105. package/dist/client-interface.d.ts.map +0 -1
  106. package/dist/client-interface.js.map +0 -1
  107. package/dist/client.d.ts.map +0 -1
  108. package/dist/client.js.map +0 -1
  109. package/dist/demo-client.d.ts.map +0 -1
  110. package/dist/demo-client.js.map +0 -1
  111. package/dist/demo-fixtures.d.ts.map +0 -1
  112. package/dist/demo-fixtures.js.map +0 -1
  113. package/dist/index.d.ts.map +0 -1
  114. package/dist/index.js.map +0 -1
  115. package/dist/logger.d.ts.map +0 -1
  116. package/dist/logger.js.map +0 -1
  117. package/dist/metrics.d.ts.map +0 -1
  118. package/dist/metrics.js.map +0 -1
  119. package/dist/observability.d.ts.map +0 -1
  120. package/dist/observability.js.map +0 -1
  121. package/dist/openai-profile.d.ts.map +0 -1
  122. package/dist/openai-profile.js.map +0 -1
  123. package/dist/prompts/register-all.d.ts.map +0 -1
  124. package/dist/prompts/register-all.js.map +0 -1
  125. package/dist/redaction.d.ts.map +0 -1
  126. package/dist/redaction.js.map +0 -1
  127. package/dist/resources/register-all.d.ts.map +0 -1
  128. package/dist/resources/register-all.js.map +0 -1
  129. package/dist/tool-exposure.d.ts.map +0 -1
  130. package/dist/tool-exposure.js.map +0 -1
  131. package/dist/tools/accountingClose.d.ts.map +0 -1
  132. package/dist/tools/accountingClose.js.map +0 -1
  133. package/dist/tools/audit_gl.d.ts.map +0 -1
  134. package/dist/tools/audit_gl.js.map +0 -1
  135. package/dist/tools/backend-availability.d.ts.map +0 -1
  136. package/dist/tools/backend-availability.js.map +0 -1
  137. package/dist/tools/bank_rules.d.ts.map +0 -1
  138. package/dist/tools/bank_rules.js.map +0 -1
  139. package/dist/tools/banking.d.ts.map +0 -1
  140. package/dist/tools/banking.js.map +0 -1
  141. package/dist/tools/clients.d.ts.map +0 -1
  142. package/dist/tools/clients.js.map +0 -1
  143. package/dist/tools/crm.d.ts.map +0 -1
  144. package/dist/tools/crm.js.map +0 -1
  145. package/dist/tools/deposits.d.ts.map +0 -1
  146. package/dist/tools/deposits.js.map +0 -1
  147. package/dist/tools/einvoice.d.ts.map +0 -1
  148. package/dist/tools/einvoice.js.map +0 -1
  149. package/dist/tools/expenses.d.ts.map +0 -1
  150. package/dist/tools/expenses.js.map +0 -1
  151. package/dist/tools/fiscal.d.ts.map +0 -1
  152. package/dist/tools/fiscal.js.map +0 -1
  153. package/dist/tools/gestoria.d.ts.map +0 -1
  154. package/dist/tools/gestoria.js.map +0 -1
  155. package/dist/tools/hr.d.ts.map +0 -1
  156. package/dist/tools/hr.js.map +0 -1
  157. package/dist/tools/igic.d.ts.map +0 -1
  158. package/dist/tools/igic.js.map +0 -1
  159. package/dist/tools/impuesto_sociedades.d.ts.map +0 -1
  160. package/dist/tools/impuesto_sociedades.js.map +0 -1
  161. package/dist/tools/intelligence.d.ts.map +0 -1
  162. package/dist/tools/intelligence.js.map +0 -1
  163. package/dist/tools/invoices.d.ts.map +0 -1
  164. package/dist/tools/invoices.js.map +0 -1
  165. package/dist/tools/kitchen.d.ts.map +0 -1
  166. package/dist/tools/kitchen.js.map +0 -1
  167. package/dist/tools/onboard_vies.d.ts.map +0 -1
  168. package/dist/tools/onboard_vies.js.map +0 -1
  169. package/dist/tools/onboarding.d.ts.map +0 -1
  170. package/dist/tools/onboarding.js.map +0 -1
  171. package/dist/tools/payroll.d.ts.map +0 -1
  172. package/dist/tools/payroll.js.map +0 -1
  173. package/dist/tools/permissions.d.ts.map +0 -1
  174. package/dist/tools/permissions.js.map +0 -1
  175. package/dist/tools/portal_domain.d.ts.map +0 -1
  176. package/dist/tools/portal_domain.js.map +0 -1
  177. package/dist/tools/pos.d.ts.map +0 -1
  178. package/dist/tools/pos.js.map +0 -1
  179. package/dist/tools/products.d.ts.map +0 -1
  180. package/dist/tools/products.js.map +0 -1
  181. package/dist/tools/quotes.d.ts.map +0 -1
  182. package/dist/tools/quotes.js.map +0 -1
  183. package/dist/tools/recurring.d.ts.map +0 -1
  184. package/dist/tools/recurring.js.map +0 -1
  185. package/dist/tools/register-all.d.ts.map +0 -1
  186. package/dist/tools/register-all.js.map +0 -1
  187. package/dist/tools/shared.d.ts.map +0 -1
  188. package/dist/tools/shared.js.map +0 -1
  189. package/dist/tools/stay.d.ts.map +0 -1
  190. package/dist/tools/stay.js.map +0 -1
  191. package/dist/tools/team.d.ts.map +0 -1
  192. package/dist/tools/team.js.map +0 -1
  193. package/dist/tools/time.d.ts.map +0 -1
  194. package/dist/tools/time.js.map +0 -1
  195. package/dist/tools/vendors.d.ts.map +0 -1
  196. package/dist/tools/vendors.js.map +0 -1
  197. package/dist/tools/webhooks.d.ts.map +0 -1
  198. package/dist/tools/webhooks.js.map +0 -1
  199. package/dist/types.d.ts.map +0 -1
  200. package/dist/types.js.map +0 -1
  201. package/scripts/audit-mcp-refs.mjs +0 -402
  202. package/scripts/no-public-leak.sh +0 -60
  203. package/scripts/test-openai-grouped-compose.mjs +0 -173
@@ -1,168 +0,0 @@
1
- /**
2
- * Tests for the OpenAI-safe MCP profile.
3
- *
4
- * The public ChatGPT app intentionally exposes a narrower tool surface than
5
- * the full MCP server. This prevents regulated or sensitive workflows added
6
- * to the general MCP server from becoming part of the OpenAI submission by
7
- * accident.
8
- */
9
- import { describe, test } from "node:test";
10
- import assert from "node:assert/strict";
11
- import { applyOpenAIProfile } from "../openai-profile.js";
12
- import { SENSITIVE_FIELD_NAMES } from "../redaction.js";
13
- import { registerAllTools } from "../tools/register-all.js";
14
- import { registerAllPrompts } from "../prompts/register-all.js";
15
- import { registerAllResources } from "../resources/register-all.js";
16
- class StubMcpServer {
17
- tools = new Map();
18
- prompts = [];
19
- resources = [];
20
- registerTool(name, config, handler) {
21
- this.tools.set(name, { name, config, handler });
22
- }
23
- registerPrompt(name) {
24
- this.prompts.push(name);
25
- }
26
- registerResource(name) {
27
- this.resources.push(name);
28
- }
29
- }
30
- function makeClient() {
31
- return new Proxy({}, {
32
- get: (_target, prop) => async (input) => {
33
- if (prop === "createClient") {
34
- return {
35
- id: "cli_openai",
36
- name: "OpenAI Test Corp",
37
- email: "test@example.com",
38
- taxId: "B12345678",
39
- secret: "should-not-leak",
40
- };
41
- }
42
- return {
43
- data: [],
44
- total: 0,
45
- limit: 10,
46
- offset: 0,
47
- input,
48
- };
49
- },
50
- });
51
- }
52
- function makeOpenAIServer() {
53
- const server = new StubMcpServer();
54
- applyOpenAIProfile(server);
55
- registerAllTools(server, makeClient());
56
- registerAllResources(server);
57
- registerAllPrompts(server);
58
- return server;
59
- }
60
- describe("OpenAI profile", () => {
61
- test("exposes exactly the reviewed 53-tool surface", () => {
62
- const server = makeOpenAIServer();
63
- assert.equal(server.tools.size, 53);
64
- assert.equal(server.prompts.length, 0);
65
- assert.equal(server.resources.length, 0);
66
- for (const hiddenTool of [
67
- "get_quarterly_taxes",
68
- "get_invoice_einvoice",
69
- "send_einvoice",
70
- "validate_einvoice_xml",
71
- "frihet_tax_id_vies_lookup",
72
- "create_reservation",
73
- "payroll_export",
74
- "invite_team_member",
75
- ]) {
76
- assert.equal(server.tools.has(hiddenTool), false, `${hiddenTool} must not be exposed in OpenAI mode`);
77
- }
78
- });
79
- test("keeps only reviewed open-world tools marked openWorldHint=true", () => {
80
- const server = makeOpenAIServer();
81
- const openWorldTools = [...server.tools.values()]
82
- .filter((tool) => tool.config.annotations?.["openWorldHint"] === true)
83
- .map((tool) => tool.name)
84
- .sort();
85
- assert.deepEqual(openWorldTools, [
86
- "create_webhook",
87
- "send_invoice",
88
- "send_quote",
89
- "update_webhook",
90
- ]);
91
- });
92
- test("removes restricted input fields from OpenAI-visible schemas", () => {
93
- const server = makeOpenAIServer();
94
- for (const name of ["create_client", "update_client", "create_vendor", "update_vendor"]) {
95
- const tool = server.tools.get(name);
96
- assert.ok(tool, `${name} should be visible`);
97
- assert.equal("taxId" in (tool.config.inputSchema ?? {}), false);
98
- }
99
- for (const name of ["send_invoice", "send_quote"]) {
100
- const tool = server.tools.get(name);
101
- assert.ok(tool, `${name} should be visible`);
102
- assert.equal("to" in (tool.config.inputSchema ?? {}), false);
103
- }
104
- for (const name of ["create_webhook", "update_webhook"]) {
105
- const tool = server.tools.get(name);
106
- assert.ok(tool, `${name} should be visible`);
107
- assert.equal("secret" in (tool.config.inputSchema ?? {}), false);
108
- }
109
- });
110
- test("every reviewed tool states an explicit openWorldHint rationale", () => {
111
- const server = makeOpenAIServer();
112
- for (const tool of server.tools.values()) {
113
- // OpenAI review: openWorldHint must be explicit (not null) AND justified per tool.
114
- assert.equal(typeof tool.config.annotations?.["openWorldHint"], "boolean", `${tool.name} must have an explicit boolean openWorldHint`);
115
- assert.ok(tool.config.description.includes("openWorldHint"), `${tool.name} description must state an openWorldHint rationale`);
116
- }
117
- // Closed-world read tool carries the closed-world rationale.
118
- assert.match(server.tools.get("list_invoices").config.description, /openWorldHint: false/);
119
- // Open-world tool keeps its bespoke true rationale (not double-appended).
120
- const sendInvoiceDesc = server.tools.get("send_invoice").config.description;
121
- assert.match(sendInvoiceDesc, /openWorldHint: true/);
122
- assert.doesNotMatch(sendInvoiceDesc, /openWorldHint: false/);
123
- });
124
- test("redacts restricted output fields from structured content and text", async () => {
125
- const server = makeOpenAIServer();
126
- const tool = server.tools.get("create_client");
127
- assert.ok(tool, "create_client should be visible");
128
- const result = await tool.handler({ name: "OpenAI Test Corp" });
129
- const serialized = JSON.stringify(result);
130
- assert.equal(serialized.includes("taxId"), false);
131
- assert.equal(serialized.includes("B12345678"), false);
132
- assert.equal(serialized.includes("secret"), false);
133
- assert.equal(serialized.includes("should-not-leak"), false);
134
- });
135
- test("no reviewed tool DECLARES a sensitive field in its outputSchema", () => {
136
- const server = makeOpenAIServer();
137
- // Recursively collect every object key declared by a Zod output schema.
138
- const collectKeys = (schema, acc) => {
139
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
- const def = schema?._def;
141
- const typeName = def?.typeName;
142
- if (typeName === "ZodObject") {
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
- for (const [key, value] of Object.entries(schema.shape)) {
145
- acc.add(key);
146
- collectKeys(value, acc);
147
- }
148
- }
149
- else if (typeName === "ZodArray") {
150
- collectKeys(def.type, acc);
151
- }
152
- else if (typeName === "ZodOptional" || typeName === "ZodNullable") {
153
- collectKeys(def.innerType, acc);
154
- }
155
- return acc;
156
- };
157
- for (const tool of server.tools.values()) {
158
- const out = tool.config.outputSchema;
159
- if (!out)
160
- continue;
161
- const keys = collectKeys(out, new Set());
162
- for (const field of SENSITIVE_FIELD_NAMES) {
163
- assert.equal(keys.has(field), false, `${tool.name} outputSchema must not declare sensitive field "${field}"`);
164
- }
165
- }
166
- });
167
- });
168
- //# sourceMappingURL=openai-profile.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai-profile.test.js","sourceRoot":"","sources":["../../src/__tests__/openai-profile.test.ts"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- /**
2
- * Pagination cursor wire-param contract.
3
- *
4
- * Bug (verified live): the client built the cursor-pagination query as
5
- * `after: params?.after`, but the ERP backend reads `req.query.cursor`
6
- * (functions/src/publicApi.ts:6472 in Frihet-ERP) and returns `nextCursor`.
7
- * The cursor token therefore never reached the backend, every "next page"
8
- * request fell back to offset=0, and cursor-based pagination looped on
9
- * page 1 forever.
10
- *
11
- * Current state (post-fix): `after` remains the caller-facing param name on
12
- * every public list/search method below — tools/*.ts and other callers keep
13
- * passing `{ after }` unchanged, it's a naming alias only. The wire query
14
- * key actually sent to the backend is `cursor` (see the doc comment atop
15
- * `FrihetClient` in src/client.ts); `after` itself is never sent.
16
- *
17
- * This spins up a local node:http server (acting as the ERP backend), points
18
- * a REAL FrihetClient at it, and asserts — for EVERY paginated public method
19
- * that accepts `after` (the 16 call sites in src/client.ts where the wire
20
- * query builder has `cursor: params?.after`) — that the captured query
21
- * string contains `cursor=<token>` and NOT `after=<token>` when a pagination
22
- * token is passed.
23
- *
24
- * Run: npm test (after build)
25
- */
26
- export {};
27
- //# sourceMappingURL=pagination-cursor-param.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pagination-cursor-param.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pagination-cursor-param.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
@@ -1,96 +0,0 @@
1
- /**
2
- * Pagination cursor wire-param contract.
3
- *
4
- * Bug (verified live): the client built the cursor-pagination query as
5
- * `after: params?.after`, but the ERP backend reads `req.query.cursor`
6
- * (functions/src/publicApi.ts:6472 in Frihet-ERP) and returns `nextCursor`.
7
- * The cursor token therefore never reached the backend, every "next page"
8
- * request fell back to offset=0, and cursor-based pagination looped on
9
- * page 1 forever.
10
- *
11
- * Current state (post-fix): `after` remains the caller-facing param name on
12
- * every public list/search method below — tools/*.ts and other callers keep
13
- * passing `{ after }` unchanged, it's a naming alias only. The wire query
14
- * key actually sent to the backend is `cursor` (see the doc comment atop
15
- * `FrihetClient` in src/client.ts); `after` itself is never sent.
16
- *
17
- * This spins up a local node:http server (acting as the ERP backend), points
18
- * a REAL FrihetClient at it, and asserts — for EVERY paginated public method
19
- * that accepts `after` (the 16 call sites in src/client.ts where the wire
20
- * query builder has `cursor: params?.after`) — that the captured query
21
- * string contains `cursor=<token>` and NOT `after=<token>` when a pagination
22
- * token is passed.
23
- *
24
- * Run: npm test (after build)
25
- */
26
- import { test, describe, before, after } from "node:test";
27
- import assert from "node:assert/strict";
28
- import { createServer } from "node:http";
29
- import { FrihetClient } from "../client.js";
30
- const captured = [];
31
- let server;
32
- let baseUrl;
33
- before(async () => {
34
- server = createServer((req, res) => {
35
- const url = new URL(req.url ?? "/", "http://localhost");
36
- captured.push({
37
- method: req.method ?? "",
38
- path: url.pathname,
39
- query: url.searchParams,
40
- });
41
- res.setHeader("Content-Type", "application/json");
42
- res.end(JSON.stringify({ data: [], total: 0, limit: 20, offset: 0 }));
43
- });
44
- await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
45
- const { port } = server.address();
46
- baseUrl = `http://127.0.0.1:${port}`;
47
- });
48
- after(async () => {
49
- await new Promise((resolve) => server.close(() => resolve()));
50
- });
51
- function makeClient() {
52
- return new FrihetClient("fri_test_key", baseUrl);
53
- }
54
- function lastRequest() {
55
- return captured[captured.length - 1];
56
- }
57
- const CURSOR_TOKEN = "eyJpZCI6Imludl8xMjMifQ"; // opaque base64url-ish token, matches backend shape
58
- /**
59
- * Every public FrihetClient method whose wire-query builder in src/client.ts
60
- * sends `cursor: params?.after` — i.e. every method that accepts a
61
- * caller-facing `after` pagination token. Verified via
62
- * `grep -n "cursor: params?.after" src/client.ts` (16 call sites as of the
63
- * `cursor` rename in PR #71). Each entry drives the real method with
64
- * `{ after: CURSOR_TOKEN }` the same way a real caller (or tools/*.ts) would.
65
- * Add new paginated methods here as they ship so coverage stays exhaustive.
66
- */
67
- const PAGINATED_ENDPOINTS = [
68
- { method: "listInvoices", invoke: (c) => c.listInvoices({ after: CURSOR_TOKEN, limit: 20 }) },
69
- { method: "searchInvoices", invoke: (c) => c.searchInvoices("acme", { after: CURSOR_TOKEN }) },
70
- { method: "listExpenses", invoke: (c) => c.listExpenses({ after: CURSOR_TOKEN }) },
71
- { method: "listClients", invoke: (c) => c.listClients({ after: CURSOR_TOKEN }) },
72
- { method: "listProducts", invoke: (c) => c.listProducts({ after: CURSOR_TOKEN }) },
73
- { method: "listQuotes", invoke: (c) => c.listQuotes({ after: CURSOR_TOKEN }) },
74
- { method: "listVendors", invoke: (c) => c.listVendors({ after: CURSOR_TOKEN }) },
75
- { method: "listDeposits", invoke: (c) => c.listDeposits({ after: CURSOR_TOKEN }) },
76
- { method: "listReservations", invoke: (c) => c.listReservations({ after: CURSOR_TOKEN }) },
77
- { method: "listProperties", invoke: (c) => c.listProperties({ after: CURSOR_TOKEN }) },
78
- { method: "listSales", invoke: (c) => c.listSales({ after: CURSOR_TOKEN }) },
79
- { method: "listKitchenTickets", invoke: (c) => c.listKitchenTickets({ after: CURSOR_TOKEN }) },
80
- { method: "listMenuItems", invoke: (c) => c.listMenuItems({ after: CURSOR_TOKEN }) },
81
- { method: "listTransactions", invoke: (c) => c.listTransactions({ after: CURSOR_TOKEN }) },
82
- { method: "listTimeEntries", invoke: (c) => c.listTimeEntries({ after: CURSOR_TOKEN }) },
83
- { method: "listLeaves", invoke: (c) => c.listLeaves({ after: CURSOR_TOKEN }) },
84
- ];
85
- describe("Pagination cursor wire param — every list/search method must send `cursor`, not `after`", () => {
86
- for (const { method, invoke } of PAGINATED_ENDPOINTS) {
87
- test(`${method}({ after: token }) → query string has cursor=token, no after param`, async () => {
88
- const client = makeClient();
89
- await invoke(client);
90
- const req = lastRequest();
91
- assert.equal(req.query.get("cursor"), CURSOR_TOKEN, `${method}: backend reads req.query.cursor — token must land there`);
92
- assert.equal(req.query.get("after"), null, `${method}: the \`after\` param is not read by the backend and must not be sent`);
93
- });
94
- }
95
- });
96
- //# sourceMappingURL=pagination-cursor-param.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pagination-cursor-param.test.js","sourceRoot":"","sources":["../../src/__tests__/pagination-cursor-param.test.ts"],"names":[],"mappings":"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"}
@@ -1,16 +0,0 @@
1
- /**
2
- * Tests for POS MCP tools — Wave 5 (4 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 4 tools registered on McpServer
9
- * 2. list_terminals — success path + structuredContent shape
10
- * 3. get_sale — success path + structuredContent shape
11
- * 4. list_sales — success path + structuredContent shape
12
- * 5. refund_sale — confirm=false blocked, confirm=true succeeds
13
- * 6. API error path — 404 propagated through handleToolError
14
- */
15
- export {};
16
- //# sourceMappingURL=pos-tools.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pos-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pos-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -1,244 +0,0 @@
1
- /**
2
- * Tests for POS MCP tools — Wave 5 (4 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 4 tools registered on McpServer
9
- * 2. list_terminals — success path + structuredContent shape
10
- * 3. get_sale — success path + structuredContent shape
11
- * 4. list_sales — success path + structuredContent shape
12
- * 5. refund_sale — confirm=false blocked, confirm=true succeeds
13
- * 6. API error path — 404 propagated through handleToolError
14
- */
15
- import { test, describe, beforeEach } from "node:test";
16
- import assert from "node:assert/strict";
17
- class StubMcpServer {
18
- tools = new Map();
19
- registerTool(name, config, handler) {
20
- this.tools.set(name, { name, config, handler });
21
- }
22
- }
23
- // ── Client stubs ─────────────────────────────────────────────────────────────
24
- const MOCK_TERMINAL = {
25
- id: "term_001",
26
- label: "Front Desk",
27
- deviceType: "bbpos_wisepos_e",
28
- locationId: "loc_tenerife",
29
- status: "online",
30
- stripeReaderId: "tmr_xxxx",
31
- createdAt: "2026-01-01T00:00:00Z",
32
- updatedAt: "2026-01-01T00:00:00Z",
33
- };
34
- const MOCK_TERMINALS_LIST = {
35
- data: [MOCK_TERMINAL],
36
- total: 1,
37
- limit: 20,
38
- offset: 0,
39
- };
40
- const MOCK_SALE = {
41
- id: "sale_abc123",
42
- terminalId: "term_001",
43
- status: "succeeded",
44
- amountCents: 4200,
45
- currency: "EUR",
46
- paymentMethod: "card_present",
47
- items: [
48
- { description: "Menu del dia", quantity: 2, unitPriceCents: 1200 },
49
- { description: "Agua", quantity: 2, unitPriceCents: 150 },
50
- ],
51
- refundedAmountCents: 0,
52
- createdAt: "2026-05-10T12:30:00Z",
53
- updatedAt: "2026-05-10T12:30:00Z",
54
- };
55
- const MOCK_SALES_LIST = {
56
- data: [MOCK_SALE],
57
- total: 1,
58
- limit: 20,
59
- offset: 0,
60
- };
61
- const MOCK_REFUND = {
62
- id: "ref_xyz789",
63
- saleId: "sale_abc123",
64
- status: "succeeded",
65
- amountCents: 4200,
66
- currency: "EUR",
67
- reason: "requested_by_customer",
68
- createdAt: "2026-05-10T13:00:00Z",
69
- };
70
- function makeSuccessClient() {
71
- return {
72
- listTerminals: async () => MOCK_TERMINALS_LIST,
73
- getSale: async (_id) => MOCK_SALE,
74
- listSales: async () => MOCK_SALES_LIST,
75
- refundSale: async (_id, _data) => MOCK_REFUND,
76
- };
77
- }
78
- function make404Client() {
79
- const notFound = () => {
80
- const err = Object.assign(new Error("Not Found"), { statusCode: 404, errorCode: "not_found" });
81
- return Promise.reject(err);
82
- };
83
- return {
84
- listTerminals: notFound,
85
- getSale: notFound,
86
- listSales: notFound,
87
- refundSale: notFound,
88
- };
89
- }
90
- // ── Helper ───────────────────────────────────────────────────────────────────
91
- async function makeServer(clientFn) {
92
- const server = new StubMcpServer();
93
- const { registerPosTools } = await import("../tools/pos.js");
94
- registerPosTools(server, clientFn());
95
- return server;
96
- }
97
- // ── Registration tests ───────────────────────────────────────────────────────
98
- describe("POS Tools — Registration", () => {
99
- let server;
100
- beforeEach(async () => {
101
- server = await makeServer(makeSuccessClient);
102
- });
103
- test("registers exactly 4 POS tools", () => {
104
- assert.equal(server.tools.size, 4);
105
- });
106
- test("registers list_terminals", () => {
107
- assert.ok(server.tools.has("list_terminals"), "list_terminals not registered");
108
- });
109
- test("registers get_sale", () => {
110
- assert.ok(server.tools.has("get_sale"), "get_sale not registered");
111
- });
112
- test("registers list_sales", () => {
113
- assert.ok(server.tools.has("list_sales"), "list_sales not registered");
114
- });
115
- test("registers refund_sale", () => {
116
- assert.ok(server.tools.has("refund_sale"), "refund_sale not registered");
117
- });
118
- });
119
- // ── list_terminals ───────────────────────────────────────────────────────────
120
- describe("list_terminals — success path", () => {
121
- test("returns structuredContent with data array", async () => {
122
- const server = await makeServer(makeSuccessClient);
123
- const tool = server.tools.get("list_terminals");
124
- const result = await tool.handler({});
125
- assert.ok(!result.isError);
126
- const sc = result.structuredContent;
127
- assert.ok(Array.isArray(sc["data"]));
128
- assert.equal(sc["data"].length, 1);
129
- assert.equal(sc["total"], 1);
130
- });
131
- test("first terminal has expected fields", async () => {
132
- const server = await makeServer(makeSuccessClient);
133
- const tool = server.tools.get("list_terminals");
134
- const result = await tool.handler({});
135
- const first = result.structuredContent["data"][0];
136
- assert.equal(first["id"], "term_001");
137
- assert.equal(first["label"], "Front Desk");
138
- assert.equal(first["status"], "online");
139
- assert.equal(first["deviceType"], "bbpos_wisepos_e");
140
- });
141
- test("content block has type text", async () => {
142
- const server = await makeServer(makeSuccessClient);
143
- const tool = server.tools.get("list_terminals");
144
- const result = await tool.handler({});
145
- assert.equal(result.content[0].type, "text");
146
- assert.ok(result.content[0].text.includes("terminals"));
147
- });
148
- });
149
- // ── get_sale ─────────────────────────────────────────────────────────────────
150
- describe("get_sale — success path", () => {
151
- test("returns sale by ID", async () => {
152
- const server = await makeServer(makeSuccessClient);
153
- const tool = server.tools.get("get_sale");
154
- const result = await tool.handler({ id: "sale_abc123" });
155
- assert.ok(!result.isError);
156
- const sc = result.structuredContent;
157
- assert.equal(sc["id"], "sale_abc123");
158
- assert.equal(sc["status"], "succeeded");
159
- assert.equal(sc["amountCents"], 4200);
160
- assert.equal(sc["currency"], "EUR");
161
- });
162
- test("items array present", async () => {
163
- const server = await makeServer(makeSuccessClient);
164
- const tool = server.tools.get("get_sale");
165
- const result = await tool.handler({ id: "sale_abc123" });
166
- const sc = result.structuredContent;
167
- assert.ok(Array.isArray(sc["items"]));
168
- assert.equal(sc["items"].length, 2);
169
- });
170
- test("404 error propagates as isError=true", async () => {
171
- const server = await makeServer(make404Client);
172
- const tool = server.tools.get("get_sale");
173
- const result = await tool.handler({ id: "sale_missing" });
174
- assert.ok(result.isError, "should be an error on 404");
175
- assert.ok(result.content[0].text.includes("Error:"));
176
- });
177
- });
178
- // ── list_sales ───────────────────────────────────────────────────────────────
179
- describe("list_sales — success path", () => {
180
- test("returns sales list with total", async () => {
181
- const server = await makeServer(makeSuccessClient);
182
- const tool = server.tools.get("list_sales");
183
- const result = await tool.handler({});
184
- assert.ok(!result.isError);
185
- const sc = result.structuredContent;
186
- assert.ok(Array.isArray(sc["data"]));
187
- assert.equal(sc["total"], 1);
188
- });
189
- test("filters accepted without error", async () => {
190
- const server = await makeServer(makeSuccessClient);
191
- const tool = server.tools.get("list_sales");
192
- const result = await tool.handler({
193
- terminalId: "term_001",
194
- status: "succeeded",
195
- from: "2026-05-01",
196
- to: "2026-05-31",
197
- limit: 10,
198
- offset: 0,
199
- });
200
- assert.ok(!result.isError);
201
- });
202
- });
203
- // ── refund_sale ──────────────────────────────────────────────────────────────
204
- describe("refund_sale — Trust Area confirmation gate", () => {
205
- test("confirm=false returns isError=true without calling API", async () => {
206
- const server = await makeServer(makeSuccessClient);
207
- const tool = server.tools.get("refund_sale");
208
- const result = await tool.handler({ id: "sale_abc123", confirm: false });
209
- assert.ok(result.isError, "should be an error when confirm=false");
210
- assert.ok(result.content[0].text.includes("confirm=true"), "error message should mention confirm=true requirement");
211
- });
212
- test("confirm=true proceeds and returns refund data", async () => {
213
- const server = await makeServer(makeSuccessClient);
214
- const tool = server.tools.get("refund_sale");
215
- const result = await tool.handler({
216
- id: "sale_abc123",
217
- confirm: true,
218
- reason: "requested_by_customer",
219
- });
220
- assert.ok(!result.isError, "should succeed with confirm=true");
221
- const sc = result.structuredContent;
222
- assert.equal(sc["saleId"], "sale_abc123");
223
- assert.equal(sc["status"], "succeeded");
224
- assert.equal(sc["amountCents"], 4200);
225
- });
226
- test("partial refund with amountCents", async () => {
227
- const server = await makeServer(makeSuccessClient);
228
- const tool = server.tools.get("refund_sale");
229
- const result = await tool.handler({
230
- id: "sale_abc123",
231
- confirm: true,
232
- amountCents: 1200,
233
- reason: "duplicate",
234
- });
235
- assert.ok(!result.isError, "partial refund should succeed");
236
- });
237
- test("404 on refund propagates as isError=true", async () => {
238
- const server = await makeServer(make404Client);
239
- const tool = server.tools.get("refund_sale");
240
- const result = await tool.handler({ id: "sale_gone", confirm: true });
241
- assert.ok(result.isError, "should be an error on 404");
242
- });
243
- });
244
- //# sourceMappingURL=pos-tools.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pos-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/pos-tools.test.ts"],"names":[],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Tests for Recurring Invoice MCP tools — Wave Mature 3 (8 tools: 2 original + 6 new).
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 8 recurring tools registered
9
- * 2. list_recurring_invoices — success path + structuredContent shape
10
- * 3. list_recurring_invoices — status filter accepted
11
- * 4. get_recurring_invoice — success path
12
- * 5. create_recurring_invoice — success path
13
- * 6. update_recurring_invoice — success path + partial update
14
- * 7. pause_recurring_invoice — success path
15
- * 8. resume_recurring_invoice — success path
16
- * 9. delete_recurring_invoice — confirm=false gate
17
- * 10. delete_recurring_invoice — confirm=true success path
18
- * 11. run_recurring_now — success path (default draftOnly=true)
19
- * 12. run_recurring_now — draftOnly=false passes through
20
- * 13. API error — 404 propagated as isError=true
21
- */
22
- export {};
23
- //# sourceMappingURL=recurring-tools.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"recurring-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/recurring-tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}