quantix-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of quantix-mcp might be problematic. Click here for more details.

Files changed (148) hide show
  1. package/.github/agents/copilot-instructions.md +32 -0
  2. package/.github/agents/speckit.analyze.agent.md +184 -0
  3. package/.github/agents/speckit.checklist.agent.md +294 -0
  4. package/.github/agents/speckit.clarify.agent.md +181 -0
  5. package/.github/agents/speckit.constitution.agent.md +82 -0
  6. package/.github/agents/speckit.implement.agent.md +135 -0
  7. package/.github/agents/speckit.plan.agent.md +89 -0
  8. package/.github/agents/speckit.specify.agent.md +258 -0
  9. package/.github/agents/speckit.tasks.agent.md +137 -0
  10. package/.github/agents/speckit.taskstoissues.agent.md +30 -0
  11. package/.github/copilot-instructions.md +17 -0
  12. package/.github/prompts/speckit.analyze.prompt.md +3 -0
  13. package/.github/prompts/speckit.checklist.prompt.md +3 -0
  14. package/.github/prompts/speckit.clarify.prompt.md +3 -0
  15. package/.github/prompts/speckit.constitution.prompt.md +3 -0
  16. package/.github/prompts/speckit.implement.prompt.md +3 -0
  17. package/.github/prompts/speckit.plan.prompt.md +3 -0
  18. package/.github/prompts/speckit.specify.prompt.md +3 -0
  19. package/.github/prompts/speckit.tasks.prompt.md +3 -0
  20. package/.github/prompts/speckit.taskstoissues.prompt.md +3 -0
  21. package/.github/workflows/publish.yaml +28 -0
  22. package/.opencode/command/speckit.analyze.md +184 -0
  23. package/.opencode/command/speckit.checklist.md +294 -0
  24. package/.opencode/command/speckit.clarify.md +181 -0
  25. package/.opencode/command/speckit.constitution.md +84 -0
  26. package/.opencode/command/speckit.implement.md +135 -0
  27. package/.opencode/command/speckit.plan.md +89 -0
  28. package/.opencode/command/speckit.specify.md +258 -0
  29. package/.opencode/command/speckit.tasks.md +137 -0
  30. package/.opencode/command/speckit.taskstoissues.md +30 -0
  31. package/.specify/memory/constitution.md +58 -0
  32. package/.specify/scripts/powershell/check-prerequisites.ps1 +148 -0
  33. package/.specify/scripts/powershell/common.ps1 +137 -0
  34. package/.specify/scripts/powershell/create-new-feature.ps1 +283 -0
  35. package/.specify/scripts/powershell/setup-plan.ps1 +61 -0
  36. package/.specify/scripts/powershell/update-agent-context.ps1 +448 -0
  37. package/.specify/templates/agent-file-template.md +28 -0
  38. package/.specify/templates/checklist-template.md +40 -0
  39. package/.specify/templates/constitution-template.md +50 -0
  40. package/.specify/templates/plan-template.md +104 -0
  41. package/.specify/templates/spec-template.md +115 -0
  42. package/.specify/templates/tasks-template.md +251 -0
  43. package/.vscode/launch.json +14 -0
  44. package/.vscode/settings.json +14 -0
  45. package/.vscode/tasks.json +15 -0
  46. package/README.md +151 -0
  47. package/dist/config.d.ts +8 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +31 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/index.d.ts +6 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +48 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/services/apiClient.d.ts +14 -0
  56. package/dist/services/apiClient.d.ts.map +1 -0
  57. package/dist/services/apiClient.js +41 -0
  58. package/dist/services/apiClient.js.map +1 -0
  59. package/dist/tools/accounts.d.ts +3 -0
  60. package/dist/tools/accounts.d.ts.map +1 -0
  61. package/dist/tools/accounts.js +77 -0
  62. package/dist/tools/accounts.js.map +1 -0
  63. package/dist/tools/categories.d.ts +3 -0
  64. package/dist/tools/categories.d.ts.map +1 -0
  65. package/dist/tools/categories.js +57 -0
  66. package/dist/tools/categories.js.map +1 -0
  67. package/dist/tools/credit-cards.d.ts +3 -0
  68. package/dist/tools/credit-cards.d.ts.map +1 -0
  69. package/dist/tools/credit-cards.js +93 -0
  70. package/dist/tools/credit-cards.js.map +1 -0
  71. package/dist/tools/settings.d.ts +3 -0
  72. package/dist/tools/settings.d.ts.map +1 -0
  73. package/dist/tools/settings.js +37 -0
  74. package/dist/tools/settings.js.map +1 -0
  75. package/dist/tools/summary.d.ts +3 -0
  76. package/dist/tools/summary.d.ts.map +1 -0
  77. package/dist/tools/summary.js +16 -0
  78. package/dist/tools/summary.js.map +1 -0
  79. package/dist/tools/transactions.d.ts +3 -0
  80. package/dist/tools/transactions.d.ts.map +1 -0
  81. package/dist/tools/transactions.js +84 -0
  82. package/dist/tools/transactions.js.map +1 -0
  83. package/dist/types/schemas.d.ts +288 -0
  84. package/dist/types/schemas.d.ts.map +1 -0
  85. package/dist/types/schemas.js +170 -0
  86. package/dist/types/schemas.js.map +1 -0
  87. package/openapi.yaml +1443 -0
  88. package/package.json +41 -0
  89. package/specs/001-mcp-api-integration/checklists/requirements.md +34 -0
  90. package/specs/001-mcp-api-integration/contracts/openapi.yaml +636 -0
  91. package/specs/001-mcp-api-integration/data-model.md +106 -0
  92. package/specs/001-mcp-api-integration/plan.md +73 -0
  93. package/specs/001-mcp-api-integration/quickstart.md +74 -0
  94. package/specs/001-mcp-api-integration/research.md +58 -0
  95. package/specs/001-mcp-api-integration/spec.md +119 -0
  96. package/specs/001-mcp-api-integration/tasks.md +64 -0
  97. package/src/config.ts +36 -0
  98. package/src/index.ts +60 -0
  99. package/src/services/apiClient.ts +49 -0
  100. package/src/tools/accounts.ts +111 -0
  101. package/src/tools/categories.ts +81 -0
  102. package/src/tools/credit-cards.ts +132 -0
  103. package/src/tools/settings.ts +51 -0
  104. package/src/tools/summary.ts +20 -0
  105. package/src/tools/transactions.ts +118 -0
  106. package/src/types/schemas.ts +193 -0
  107. package/tests/benchmark.test.d.ts +2 -0
  108. package/tests/benchmark.test.d.ts.map +1 -0
  109. package/tests/benchmark.test.js +33 -0
  110. package/tests/benchmark.test.js.map +1 -0
  111. package/tests/benchmark.test.ts +38 -0
  112. package/tests/server.test.d.ts +2 -0
  113. package/tests/server.test.d.ts.map +1 -0
  114. package/tests/server.test.js +13 -0
  115. package/tests/server.test.js.map +1 -0
  116. package/tests/server.test.ts +14 -0
  117. package/tests/setup.d.ts +4 -0
  118. package/tests/setup.d.ts.map +1 -0
  119. package/tests/setup.js +17 -0
  120. package/tests/setup.js.map +1 -0
  121. package/tests/setup.ts +20 -0
  122. package/tests/tools/accounts.test.ts +118 -0
  123. package/tests/tools/categories.test.d.ts +2 -0
  124. package/tests/tools/categories.test.d.ts.map +1 -0
  125. package/tests/tools/categories.test.js +63 -0
  126. package/tests/tools/categories.test.js.map +1 -0
  127. package/tests/tools/categories.test.ts +78 -0
  128. package/tests/tools/credit-cards.test.d.ts +2 -0
  129. package/tests/tools/credit-cards.test.d.ts.map +1 -0
  130. package/tests/tools/credit-cards.test.js +71 -0
  131. package/tests/tools/credit-cards.test.js.map +1 -0
  132. package/tests/tools/credit-cards.test.ts +89 -0
  133. package/tests/tools/summary.test.d.ts +2 -0
  134. package/tests/tools/summary.test.d.ts.map +1 -0
  135. package/tests/tools/summary.test.js +36 -0
  136. package/tests/tools/summary.test.js.map +1 -0
  137. package/tests/tools/summary.test.ts +42 -0
  138. package/tests/tools/transactions.test.d.ts +2 -0
  139. package/tests/tools/transactions.test.d.ts.map +1 -0
  140. package/tests/tools/transactions.test.js +67 -0
  141. package/tests/tools/transactions.test.js.map +1 -0
  142. package/tests/tools/transactions.test.ts +82 -0
  143. package/tsconfig.json +52 -0
  144. package/vitest.config.d.ts +3 -0
  145. package/vitest.config.d.ts.map +1 -0
  146. package/vitest.config.js +14 -0
  147. package/vitest.config.js.map +1 -0
  148. package/vitest.config.ts +14 -0
@@ -0,0 +1,193 @@
1
+ import { z } from 'zod';
2
+
3
+ // --- Domain Entities ---
4
+
5
+ export const CategorySchema = z.object({
6
+ id: z.string(),
7
+ name: z.string(),
8
+ type: z.enum(["INCOME", "EXPENSE"]),
9
+ color: z.string().optional(),
10
+ createdAt: z.string().datetime().optional()
11
+ });
12
+
13
+ export const TransactionSchema = z.object({
14
+ id: z.string(),
15
+ type: z.enum(["INCOME", "EXPENSE"]),
16
+ name: z.string(),
17
+ amount: z.number().min(0),
18
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid date format YYYY-MM-DD"),
19
+ categoryId: z.string().optional(),
20
+ paymentMethod: z.enum(["CASH", "PIX", "DEBIT", "CREDIT"]).optional(),
21
+ creditCardId: z.string().optional(),
22
+ installmentGroupId: z.string().optional(),
23
+ installmentNumber: z.number().int().optional(),
24
+ installmentTotal: z.number().int().optional(),
25
+ recurrenceRuleId: z.string().optional(),
26
+ accountId: z.string().optional(),
27
+ paid: z.boolean().default(false),
28
+ createdAt: z.string().datetime().optional()
29
+ });
30
+
31
+ export const CreditCardSchema = z.object({
32
+ id: z.string(),
33
+ name: z.string(),
34
+ brand: z.string().optional(),
35
+ limitAmount: z.number().min(0),
36
+ closingDay: z.number().int().min(1).max(31),
37
+ dueDay: z.number().int().min(1).max(31),
38
+ createdAt: z.string().datetime().optional()
39
+ });
40
+
41
+ export const AccountSchema = z.object({
42
+ id: z.string(),
43
+ name: z.string(),
44
+ type: z.enum(["BANK_ACCOUNT", "WALLET", "SAVINGS_ACCOUNT", "INVESTMENT_ACCOUNT", "OTHER"]),
45
+ initialBalance: z.number(),
46
+ currentBalance: z.number().optional(),
47
+ createdAt: z.string().datetime().optional(),
48
+ updatedAt: z.string().datetime().optional()
49
+ });
50
+
51
+ export const AccountBalanceSchema = z.object({
52
+ accountId: z.string(),
53
+ currentBalance: z.number(),
54
+ calculatedAt: z.string().datetime()
55
+ });
56
+
57
+ export const StatementSchema = z.object({
58
+ cardId: z.string(),
59
+ periodStart: z.string(),
60
+ periodEnd: z.string(),
61
+ dueDate: z.string(),
62
+ transactions: z.array(TransactionSchema).optional(),
63
+ total: z.number(),
64
+ availableLimit: z.number()
65
+ });
66
+
67
+ export const StatementStatusSchema = z.object({
68
+ cardId: z.string(),
69
+ month: z.string(),
70
+ isPaid: z.boolean()
71
+ });
72
+
73
+ export const SummarySchema = z.object({
74
+ month: z.string(),
75
+ income: z.number(),
76
+ expenses: z.number(),
77
+ balance: z.number(),
78
+ creditCardStatements: z.array(z.any()).optional()
79
+ });
80
+
81
+ export const SettingsSchema = z.object({
82
+ userName: z.string(),
83
+ language: z.enum(["pt-BR", "en-US"]),
84
+ currency: z.enum(["BRL", "USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF"]),
85
+ createdAt: z.string().datetime().optional(),
86
+ updatedAt: z.string().datetime().optional()
87
+ });
88
+
89
+ // --- Tool Inputs ---
90
+
91
+ export const CreateCategoryInput = z.object({
92
+ name: z.string(),
93
+ type: z.enum(["INCOME", "EXPENSE"]),
94
+ color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color").optional()
95
+ });
96
+
97
+ export const UpdateCategoryInput = z.object({
98
+ id: z.string(),
99
+ name: z.string().optional(),
100
+ color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color").optional()
101
+ });
102
+
103
+ export const CreateCreditCardInput = z.object({
104
+ name: z.string(),
105
+ brand: z.string().optional(),
106
+ limitAmount: z.number().min(0),
107
+ closingDay: z.number().int().min(1).max(31),
108
+ dueDay: z.number().int().min(1).max(31)
109
+ });
110
+
111
+ export const UpdateCreditCardInput = z.object({
112
+ id: z.string(),
113
+ name: z.string().optional(),
114
+ brand: z.string().optional(),
115
+ limitAmount: z.number().min(0).optional(),
116
+ closingDay: z.number().int().min(1).max(31).optional(),
117
+ dueDay: z.number().int().min(1).max(31).optional()
118
+ });
119
+
120
+ export const CreateTransactionInput = z.object({
121
+ type: z.enum(["INCOME", "EXPENSE"]),
122
+ name: z.string(),
123
+ amount: z.number().positive(),
124
+ date: z.string().describe("ISO date string YYYY-MM-DD"),
125
+ categoryId: z.string().optional(),
126
+ paymentMethod: z.enum(["CASH", "PIX", "DEBIT", "CREDIT"]).optional(),
127
+ creditCardId: z.string().optional(),
128
+ accountId: z.string().optional(),
129
+ installments: z.number().int().min(1).optional(),
130
+ targetDueMonth: z.string().regex(/^\d{4}-\d{2}$/).optional(),
131
+ recurrence: z.object({
132
+ frequency: z.enum(["MONTHLY", "WEEKLY", "YEARLY"]),
133
+ interval: z.number().int().min(1).optional(),
134
+ endDate: z.string().optional()
135
+ }).optional()
136
+ });
137
+
138
+ export const UpdateTransactionInput = z.object({
139
+ id: z.string(),
140
+ mode: z.enum(["SINGLE", "PENDING", "ALL"]).default("SINGLE").optional(),
141
+ type: z.enum(["INCOME", "EXPENSE"]).optional(),
142
+ name: z.string().optional(),
143
+ amount: z.number().positive().optional(),
144
+ date: z.string().describe("ISO date string YYYY-MM-DD").optional(),
145
+ categoryId: z.string().optional(),
146
+ paymentMethod: z.enum(["CASH", "PIX", "DEBIT", "CREDIT"]).optional(),
147
+ creditCardId: z.string().optional(),
148
+ accountId: z.string().optional(),
149
+ targetDueMonth: z.string().regex(/^\d{4}-\d{2}$/).optional(),
150
+ recurrence: z.object({
151
+ frequency: z.enum(["MONTHLY", "WEEKLY", "YEARLY"]).optional(),
152
+ interval: z.number().int().min(1).optional(),
153
+ endDate: z.string().optional()
154
+ }).optional()
155
+ });
156
+
157
+ export const CreateAccountInput = z.object({
158
+ name: z.string(),
159
+ type: z.enum(["BANK_ACCOUNT", "WALLET", "SAVINGS_ACCOUNT", "INVESTMENT_ACCOUNT", "OTHER"]),
160
+ initialBalance: z.number()
161
+ });
162
+
163
+ export const UpdateAccountInput = z.object({
164
+ id: z.string(),
165
+ name: z.string().optional(),
166
+ type: z.enum(["BANK_ACCOUNT", "WALLET", "SAVINGS_ACCOUNT", "INVESTMENT_ACCOUNT", "OTHER"]).optional()
167
+ });
168
+
169
+ export const GetTransactionsInput = z.object({
170
+ month: z.string().regex(/^\d{4}-\d{2}$/, "Format: YYYY-MM").describe("Format: YYYY-MM").optional()
171
+ });
172
+
173
+ export const PayStatementInput = z.object({
174
+ cardId: z.string(),
175
+ month: z.string().regex(/^\d{4}-\d{2}$/, "Format: YYYY-MM"),
176
+ paymentAccountId: z.string()
177
+ });
178
+
179
+ export const GetSummaryInput = z.object({
180
+ month: z.string().regex(/^\d{4}-\d{2}$/, "Format: YYYY-MM").describe("Format: YYYY-MM")
181
+ });
182
+
183
+ export const CreateSettingsInput = z.object({
184
+ userName: z.string(),
185
+ language: z.enum(["pt-BR", "en-US"]),
186
+ currency: z.enum(["BRL", "USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF"])
187
+ });
188
+
189
+ export const UpdateSettingsInput = z.object({
190
+ userName: z.string().optional(),
191
+ language: z.enum(["pt-BR", "en-US"]).optional(),
192
+ currency: z.enum(["BRL", "USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF"]).optional()
193
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=benchmark.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark.test.d.ts","sourceRoot":"","sources":["benchmark.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { registerCategoryTools } from '../src/tools/categories.js';
3
+ import { apiClient } from '../src/services/apiClient.js';
4
+ vi.mock('../src/services/apiClient.js', () => ({
5
+ apiClient: {
6
+ get: vi.fn(),
7
+ }
8
+ }));
9
+ describe('Performance Benchmark', () => {
10
+ // This is a rough benchmark, mostly verifying it's not super slow due to overhead
11
+ it('should execute tool handler with low overhead (<20ms)', async () => {
12
+ const registeredTools = {};
13
+ const mockServer = {
14
+ registerTool: (name, def, handler) => {
15
+ registeredTools[name] = handler;
16
+ }
17
+ };
18
+ // Setup
19
+ registerCategoryTools(mockServer);
20
+ const handler = registeredTools['get_categories'];
21
+ apiClient.get.mockResolvedValue([]);
22
+ // Warmup
23
+ await handler({});
24
+ // Measure
25
+ const start = performance.now();
26
+ await handler({});
27
+ const end = performance.now();
28
+ const duration = end - start;
29
+ console.log(`Tool execution overhead: ${duration.toFixed(3)}ms`);
30
+ expect(duration).toBeLessThan(20);
31
+ });
32
+ });
33
+ //# sourceMappingURL=benchmark.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark.test.js","sourceRoot":"","sources":["benchmark.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7C,SAAS,EAAE;QACT,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;KACb;CACF,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACnC,kFAAkF;IAClF,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,eAAe,GAA6B,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG;YACf,YAAY,EAAE,CAAC,IAAY,EAAE,GAAQ,EAAE,OAAiB,EAAE,EAAE;gBACxD,eAAe,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YACpC,CAAC;SACJ,CAAC;QAEF,QAAQ;QACR,qBAAqB,CAAC,UAAiB,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;QACjD,SAAS,CAAC,GAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAE7C,SAAS;QACT,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QAElB,UAAU;QACV,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,GAAG,KAAK,CAAC;QAE7B,OAAO,CAAC,GAAG,CAAC,4BAA4B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { registerCategoryTools } from '../src/tools/categories.js';
3
+ import { apiClient } from '../src/services/apiClient.js';
4
+
5
+ vi.mock('../src/services/apiClient.js', () => ({
6
+ apiClient: {
7
+ get: vi.fn(),
8
+ }
9
+ }));
10
+
11
+ describe('Performance Benchmark', () => {
12
+ // This is a rough benchmark, mostly verifying it's not super slow due to overhead
13
+ it('should execute tool handler with low overhead (<20ms)', async () => {
14
+ const registeredTools: Record<string, Function> = {};
15
+ const mockServer = {
16
+ registerTool: (name: string, def: any, handler: Function) => {
17
+ registeredTools[name] = handler;
18
+ }
19
+ };
20
+
21
+ // Setup
22
+ registerCategoryTools(mockServer as any);
23
+ const handler = registeredTools['get_categories'];
24
+ (apiClient.get as any).mockResolvedValue([]);
25
+
26
+ // Warmup
27
+ await handler({});
28
+
29
+ // Measure
30
+ const start = performance.now();
31
+ await handler({});
32
+ const end = performance.now();
33
+ const duration = end - start;
34
+
35
+ console.log(`Tool execution overhead: ${duration.toFixed(3)}ms`);
36
+ expect(duration).toBeLessThan(20);
37
+ });
38
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["server.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { getServer } from '../src/index.js';
3
+ describe('Server Startup', () => {
4
+ it('should initialize McpServer', () => {
5
+ const server = getServer();
6
+ expect(server).toBeDefined();
7
+ // expect(server.server.name).toBe('quantix_mcp_server');
8
+ });
9
+ // Since we can't easily inspect registered tools without private access or running it,
10
+ // we'll mainly check it doesn't crash on init.
11
+ // With McpServer from SDK, we might be able to check capabilities or similar if exposed.
12
+ });
13
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,0DAA0D;IAC5D,CAAC,CAAC,CAAC;IAEH,wFAAwF;IACxF,+CAA+C;IAC/C,yFAAyF;AAC3F,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { getServer } from '../src/index.js';
3
+
4
+ describe('Server Startup', () => {
5
+ it('should initialize McpServer', () => {
6
+ const server = getServer();
7
+ expect(server).toBeDefined();
8
+ // expect(server.server.name).toBe('quantix_mcp_server');
9
+ });
10
+
11
+ // Since we can't easily inspect registered tools without private access or running it,
12
+ // we'll mainly check it doesn't crash on init.
13
+ // With McpServer from SDK, we might be able to check capabilities or similar if exposed.
14
+ });
@@ -0,0 +1,4 @@
1
+ import { vi } from 'vitest';
2
+ export declare const mockFetch: ReturnType<typeof vi.fn>;
3
+ export declare function resetMocks(): void;
4
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAK5B,eAAO,MAAM,SAAS,EAA8B,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAE7E,wBAAgB,UAAU,SAEzB"}
package/tests/setup.js ADDED
@@ -0,0 +1,17 @@
1
+ import { vi } from 'vitest';
2
+ // Define the global fetch if not already (Vitest/Node should have it, but for explicit typing)
3
+ global.fetch = vi.fn();
4
+ export const mockFetch = global.fetch;
5
+ export function resetMocks() {
6
+ mockFetch.mockReset();
7
+ }
8
+ // Basic mocks for config to ensure tests don't fail on missing env
9
+ vi.mock('../src/config.js', () => ({
10
+ config: {
11
+ QUANTIX_API_URL: 'https://test-api.quantix.com',
12
+ QUANTIX_API_KEY: 'test-key',
13
+ MCPPORT: '3000',
14
+ NODE_ENV: 'test'
15
+ }
16
+ }));
17
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,+FAA+F;AAC/F,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAEvB,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,KAA4C,CAAC;AAE7E,MAAM,UAAU,UAAU;IACxB,SAAS,CAAC,SAAS,EAAE,CAAC;AACxB,CAAC;AAED,mEAAmE;AACnE,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,MAAM,EAAE;QACN,eAAe,EAAE,8BAA8B;QAC/C,eAAe,EAAE,UAAU;QAC3B,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;KACjB;CACF,CAAC,CAAC,CAAC"}
package/tests/setup.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { vi } from 'vitest';
2
+
3
+ // Define the global fetch if not already (Vitest/Node should have it, but for explicit typing)
4
+ global.fetch = vi.fn();
5
+
6
+ export const mockFetch = global.fetch as unknown as ReturnType<typeof vi.fn>;
7
+
8
+ export function resetMocks() {
9
+ mockFetch.mockReset();
10
+ }
11
+
12
+ // Basic mocks for config to ensure tests don't fail on missing env
13
+ vi.mock('../src/config.js', () => ({
14
+ config: {
15
+ QUANTIX_API_URL: 'https://test-api.quantix.com',
16
+ QUANTIX_API_KEY: 'test-key',
17
+ MCPPORT: '3000',
18
+ NODE_ENV: 'test'
19
+ }
20
+ }));
@@ -0,0 +1,118 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { registerAccountTools } from '../../src/tools/accounts.js';
3
+ import { apiClient } from '../../src/services/apiClient.js';
4
+
5
+ vi.mock('../../src/services/apiClient.js', () => ({
6
+ apiClient: {
7
+ get: vi.fn(),
8
+ post: vi.fn(),
9
+ patch: vi.fn(),
10
+ delete: vi.fn(),
11
+ }
12
+ }));
13
+
14
+ describe('Account Tools', () => {
15
+ let mockServer: any;
16
+ let registeredTools: Record<string, Function> = {};
17
+
18
+ beforeEach(() => {
19
+ registeredTools = {};
20
+ mockServer = {
21
+ registerTool: vi.fn((name, def, handler) => {
22
+ registeredTools[name] = handler;
23
+ })
24
+ };
25
+ vi.clearAllMocks();
26
+ });
27
+
28
+ it('should register all account tools', () => {
29
+ registerAccountTools(mockServer);
30
+ expect(mockServer.registerTool).toHaveBeenCalledTimes(6);
31
+ expect(registeredTools['create_account']).toBeDefined();
32
+ expect(registeredTools['get_accounts']).toBeDefined();
33
+ expect(registeredTools['get_account']).toBeDefined();
34
+ expect(registeredTools['update_account']).toBeDefined();
35
+ expect(registeredTools['delete_account']).toBeDefined();
36
+ expect(registeredTools['get_account_balance']).toBeDefined();
37
+ });
38
+
39
+ describe('create_account', () => {
40
+ it('should post new account data', async () => {
41
+ registerAccountTools(mockServer);
42
+ const handler = registeredTools['create_account'];
43
+ (apiClient.post as any).mockResolvedValue({ id: 'acc_1', name: 'My Bank' });
44
+
45
+ const input = { name: 'My Bank', type: 'BANK_ACCOUNT', initialBalance: 1000 };
46
+ const result = await handler(input);
47
+
48
+ expect(apiClient.post).toHaveBeenCalledWith('/accounts', input);
49
+ expect(result.content[0].text).toContain('My Bank');
50
+ });
51
+ });
52
+
53
+ describe('get_accounts', () => {
54
+ it('should list accounts', async () => {
55
+ registerAccountTools(mockServer);
56
+ const handler = registeredTools['get_accounts'];
57
+ (apiClient.get as any).mockResolvedValue([{ id: 'acc_1', name: 'My Bank' }]);
58
+
59
+ const result = await handler({});
60
+
61
+ expect(apiClient.get).toHaveBeenCalledWith('/accounts');
62
+ expect(result.content[0].text).toContain('My Bank');
63
+ });
64
+ });
65
+
66
+ describe('get_account', () => {
67
+ it('should get account details', async () => {
68
+ registerAccountTools(mockServer);
69
+ const handler = registeredTools['get_account'];
70
+ (apiClient.get as any).mockResolvedValue({ id: 'acc_1', name: 'My Bank' });
71
+
72
+ const result = await handler({ id: 'acc_1' });
73
+
74
+ expect(apiClient.get).toHaveBeenCalledWith('/accounts/acc_1');
75
+ expect(result.content[0].text).toContain('My Bank');
76
+ });
77
+ });
78
+
79
+ describe('update_account', () => {
80
+ it('should update account', async () => {
81
+ registerAccountTools(mockServer);
82
+ const handler = registeredTools['update_account'];
83
+ (apiClient.patch as any).mockResolvedValue({ id: 'acc_1', name: 'Updated Name' });
84
+
85
+ const input = { id: 'acc_1', name: 'Updated Name' };
86
+ const result = await handler(input);
87
+
88
+ expect(apiClient.patch).toHaveBeenCalledWith('/accounts/acc_1', { name: 'Updated Name' });
89
+ expect(result.content[0].text).toContain('Updated Name');
90
+ });
91
+ });
92
+
93
+ describe('delete_account', () => {
94
+ it('should delete account', async () => {
95
+ registerAccountTools(mockServer);
96
+ const handler = registeredTools['delete_account'];
97
+ (apiClient.delete as any).mockResolvedValue({});
98
+
99
+ const result = await handler({ id: 'acc_1' });
100
+
101
+ expect(apiClient.delete).toHaveBeenCalledWith('/accounts/acc_1');
102
+ expect(result.content[0].text).toContain('deleted successfully');
103
+ });
104
+ });
105
+
106
+ describe('get_account_balance', () => {
107
+ it('should get account balance', async () => {
108
+ registerAccountTools(mockServer);
109
+ const handler = registeredTools['get_account_balance'];
110
+ (apiClient.get as any).mockResolvedValue({ accountId: 'acc_1', currentBalance: 500 });
111
+
112
+ const result = await handler({ id: 'acc_1' });
113
+
114
+ expect(apiClient.get).toHaveBeenCalledWith('/accounts/acc_1/balance');
115
+ expect(result.content[0].text).toContain('500');
116
+ });
117
+ });
118
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=categories.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories.test.d.ts","sourceRoot":"","sources":["categories.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { registerCategoryTools } from '../../src/tools/categories.js';
3
+ import { apiClient } from '../../src/services/apiClient.js';
4
+ // Mock apiClient
5
+ vi.mock('../../src/services/apiClient.js', () => ({
6
+ apiClient: {
7
+ get: vi.fn(),
8
+ post: vi.fn(),
9
+ delete: vi.fn(),
10
+ }
11
+ }));
12
+ describe('Category Tools', () => {
13
+ let mockServer;
14
+ let registeredTools = {};
15
+ beforeEach(() => {
16
+ registeredTools = {};
17
+ mockServer = {
18
+ registerTool: vi.fn((name, def, handler) => {
19
+ registeredTools[name] = handler;
20
+ })
21
+ };
22
+ vi.clearAllMocks();
23
+ });
24
+ it('should register category tools', () => {
25
+ registerCategoryTools(mockServer);
26
+ expect(mockServer.registerTool).toHaveBeenCalledTimes(3);
27
+ expect(registeredTools['create_category']).toBeDefined();
28
+ expect(registeredTools['get_categories']).toBeDefined();
29
+ expect(registeredTools['delete_category']).toBeDefined();
30
+ });
31
+ describe('create_category', () => {
32
+ it('should call api.post with correct data', async () => {
33
+ registerCategoryTools(mockServer);
34
+ const handler = registeredTools['create_category'];
35
+ apiClient.post.mockResolvedValue({ id: 'cat_1', name: 'Test' });
36
+ const result = await handler({ name: 'Test', type: 'EXPENSE' });
37
+ expect(apiClient.post).toHaveBeenCalledWith('/categories', { name: 'Test', type: 'EXPENSE' });
38
+ expect(result.content[0].text).toContain('Category created');
39
+ expect(result.content[0].text).toContain('Test');
40
+ });
41
+ });
42
+ describe('get_categories', () => {
43
+ it('should call api.get', async () => {
44
+ registerCategoryTools(mockServer);
45
+ const handler = registeredTools['get_categories'];
46
+ apiClient.get.mockResolvedValue([{ id: 'cat_1', name: 'Test' }]);
47
+ const result = await handler({});
48
+ expect(apiClient.get).toHaveBeenCalledWith('/categories');
49
+ expect(result.content[0].text).toContain('Test');
50
+ });
51
+ });
52
+ describe('delete_category', () => {
53
+ it('should call api.delete', async () => {
54
+ registerCategoryTools(mockServer);
55
+ const handler = registeredTools['delete_category'];
56
+ apiClient.delete.mockResolvedValue({});
57
+ const result = await handler({ id: 'cat_1' });
58
+ expect(apiClient.delete).toHaveBeenCalledWith('/categories/cat_1');
59
+ expect(result.content[0].text).toContain('Category deleted');
60
+ });
61
+ });
62
+ });
63
+ //# sourceMappingURL=categories.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories.test.js","sourceRoot":"","sources":["categories.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAE5D,iBAAiB;AACjB,EAAE,CAAC,IAAI,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,SAAS,EAAE;QACT,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;QACZ,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;KAChB;CACF,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,UAAe,CAAC;IACpB,IAAI,eAAe,GAA6B,EAAE,CAAC;IAEnD,UAAU,CAAC,GAAG,EAAE;QACd,eAAe,GAAG,EAAE,CAAC;QACrB,UAAU,GAAG;YACX,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;gBACzC,eAAe,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YAClC,CAAC,CAAC;SACH,CAAC;QACF,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACzD,MAAM,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACxD,MAAM,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;YAElD,SAAS,CAAC,IAAY,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAEzE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAEhE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC9F,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACnC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;YAEjD,SAAS,CAAC,GAAW,CAAC,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAE1E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;YAEjC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACtC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;YAElD,SAAS,CAAC,MAAc,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAEhD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAE9C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;YACnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { registerCategoryTools } from '../../src/tools/categories.js';
3
+ import { apiClient } from '../../src/services/apiClient.js';
4
+
5
+ // Mock apiClient
6
+ vi.mock('../../src/services/apiClient.js', () => ({
7
+ apiClient: {
8
+ get: vi.fn(),
9
+ post: vi.fn(),
10
+ delete: vi.fn(),
11
+ }
12
+ }));
13
+
14
+ describe('Category Tools', () => {
15
+ let mockServer: any;
16
+ let registeredTools: Record<string, Function> = {};
17
+
18
+ beforeEach(() => {
19
+ registeredTools = {};
20
+ mockServer = {
21
+ registerTool: vi.fn((name, def, handler) => {
22
+ registeredTools[name] = handler;
23
+ })
24
+ };
25
+ vi.clearAllMocks();
26
+ });
27
+
28
+ it('should register category tools', () => {
29
+ registerCategoryTools(mockServer);
30
+ expect(mockServer.registerTool).toHaveBeenCalledTimes(3);
31
+ expect(registeredTools['create_category']).toBeDefined();
32
+ expect(registeredTools['get_categories']).toBeDefined();
33
+ expect(registeredTools['delete_category']).toBeDefined();
34
+ });
35
+
36
+ describe('create_category', () => {
37
+ it('should call api.post with correct data', async () => {
38
+ registerCategoryTools(mockServer);
39
+ const handler = registeredTools['create_category'];
40
+
41
+ (apiClient.post as any).mockResolvedValue({ id: 'cat_1', name: 'Test' });
42
+
43
+ const result = await handler({ name: 'Test', type: 'EXPENSE' });
44
+
45
+ expect(apiClient.post).toHaveBeenCalledWith('/categories', { name: 'Test', type: 'EXPENSE' });
46
+ expect(result.content[0].text).toContain('Category created');
47
+ expect(result.content[0].text).toContain('Test');
48
+ });
49
+ });
50
+
51
+ describe('get_categories', () => {
52
+ it('should call api.get', async () => {
53
+ registerCategoryTools(mockServer);
54
+ const handler = registeredTools['get_categories'];
55
+
56
+ (apiClient.get as any).mockResolvedValue([{ id: 'cat_1', name: 'Test' }]);
57
+
58
+ const result = await handler({});
59
+
60
+ expect(apiClient.get).toHaveBeenCalledWith('/categories');
61
+ expect(result.content[0].text).toContain('Test');
62
+ });
63
+ });
64
+
65
+ describe('delete_category', () => {
66
+ it('should call api.delete', async () => {
67
+ registerCategoryTools(mockServer);
68
+ const handler = registeredTools['delete_category'];
69
+
70
+ (apiClient.delete as any).mockResolvedValue({});
71
+
72
+ const result = await handler({ id: 'cat_1' });
73
+
74
+ expect(apiClient.delete).toHaveBeenCalledWith('/categories/cat_1');
75
+ expect(result.content[0].text).toContain('Category deleted');
76
+ });
77
+ });
78
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=credit-cards.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit-cards.test.d.ts","sourceRoot":"","sources":["credit-cards.test.ts"],"names":[],"mappings":""}