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,106 @@
1
+ # Data Model & Schema Mapping
2
+
3
+ **Feature**: MCP Server for Quantix API Integration
4
+ **Source**: [contracts/openapi.yaml](./contracts/openapi.yaml)
5
+
6
+ ## Domain Entities
7
+
8
+ ### Category
9
+ - **Fields**:
10
+ - `id`: string (UUID)
11
+ - `name`: string
12
+ - `type`: enum ("INCOME", "EXPENSE")
13
+ - `createdAt`: datetime
14
+ - **Zod Schema**:
15
+ ```typescript
16
+ z.object({
17
+ id: z.string(),
18
+ name: z.string(),
19
+ type: z.enum(["INCOME", "EXPENSE"]),
20
+ createdAt: z.string().datetime()
21
+ })
22
+ ```
23
+
24
+ ### Transaction
25
+ - **Fields**:
26
+ - `id`: string
27
+ - `type`: enum ("INCOME", "EXPENSE")
28
+ - `name`: string
29
+ - `amount`: number (min 0)
30
+ - `date`: string (YYYY-MM-DD)
31
+ - `categoryId`: string (optional)
32
+ - `paymentMethod`: enum ("CASH", "PIX", "DEBIT", "CREDIT") (optional)
33
+ - `creditCardId`: string (optional, required if CREDIT)
34
+ - `paid`: boolean (default false)
35
+ - **Zod Schema**:
36
+ ```typescript
37
+ z.object({
38
+ id: z.string(),
39
+ type: z.enum(["INCOME", "EXPENSE"]),
40
+ name: z.string(),
41
+ amount: z.number().min(0),
42
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
43
+ categoryId: z.string().optional(),
44
+ paymentMethod: z.enum(["CASH", "PIX", "DEBIT", "CREDIT"]).optional(),
45
+ creditCardId: z.string().optional(),
46
+ paid: z.boolean().default(false)
47
+ })
48
+ ```
49
+
50
+ ### CreditCard
51
+ - **Fields**:
52
+ - `id`: string
53
+ - `name`: string
54
+ - `limitAmount`: number
55
+ - `closingDay`: integer (1-31)
56
+ - `dueDay`: integer (1-31)
57
+ - **Zod Schema**:
58
+ ```typescript
59
+ z.object({
60
+ id: z.string(),
61
+ name: z.string(),
62
+ limitAmount: z.number().min(0),
63
+ closingDay: z.number().int().min(1).max(31),
64
+ dueDay: z.number().int().min(1).max(31)
65
+ })
66
+ ```
67
+
68
+ ## Tool Input Schemas
69
+
70
+ These schemas define the arguments for the MCP tools.
71
+
72
+ ### `create_category`
73
+ ```typescript
74
+ z.object({
75
+ name: z.string(),
76
+ type: z.enum(["INCOME", "EXPENSE"])
77
+ })
78
+ ```
79
+
80
+ ### `create_transaction`
81
+ ```typescript
82
+ z.object({
83
+ type: z.enum(["INCOME", "EXPENSE"]),
84
+ name: z.string(),
85
+ amount: z.number().positive(),
86
+ date: z.string().describe("ISO date string YYYY-MM-DD"),
87
+ categoryId: z.string().optional(),
88
+ paymentMethod: z.enum(["CASH", "PIX", "DEBIT", "CREDIT"]).optional(),
89
+ creditCardId: z.string().optional()
90
+ })
91
+ ```
92
+
93
+ ### `get_transactions`
94
+ ```typescript
95
+ z.object({
96
+ month: z.string().regex(/^\d{4}-\d{2}$/).describe("Format: YYYY-MM")
97
+ })
98
+ ```
99
+
100
+ ### `pay_statement`
101
+ ```typescript
102
+ z.object({
103
+ cardId: z.string(),
104
+ month: z.string().regex(/^\d{4}-\d{2}$/)
105
+ })
106
+ ```
@@ -0,0 +1,73 @@
1
+ # Implementation Plan: MCP Server for Quantix API Integration
2
+
3
+ **Branch**: `001-mcp-api-integration` | **Date**: 2026-01-31 | **Spec**: [spec.md](spec.md)
4
+ **Input**: Feature specification from `/specs/001-mcp-api-integration/spec.md`
5
+
6
+ ## Summary
7
+
8
+ Implement 12 MCP tools to expose the Quantix Personal Finance Manager API capabilities (Categories, Credit Cards, Transactions, Summaries).
9
+ The solution will extend the existing Express-based MCP server in `src/index.ts`, adding Zod validation for all inputs and handling API authentication via `QUANTIX_API_KEY`.
10
+
11
+ ## Technical Context
12
+
13
+ **Language/Version**: TypeScript 5.9 (Node.js)
14
+ **Primary Dependencies**: `@modelcontextprotocol/sdk`, `express`, `zod`, `fetch` (native Node 18+)
15
+ **Storage**: N/A (Stateless proxy to external API)
16
+ **Testing**: Vitest (Proposed, currently missing in `package.json`)
17
+ **Target Platform**: MCP Clients (e.g., Claude Desktop) connecting via SSE/HTTP
18
+ **Project Type**: Backend / API Proxy
19
+ **Performance Goals**: Low latency proxy (adding <20ms overhead)
20
+ **Constraints**: Must match OpenAPI 3.0 schema strictly for tools.
21
+ **Scale/Scope**: 12 Tools, ~5-6 Service modules.
22
+
23
+ ## Constitution Check
24
+
25
+ *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
26
+
27
+ * **Principle 1 (Library-First)**: We will organize tools into modules (`src/tools/`) rather than a monolithic `index.ts`.
28
+ * **Principle 3 (Test-First)**: We need to introduce a testing framework (`vitest`) as none exists.
29
+ * **Principle 4 (Integration Testing)**: We will create tests that mock the external API to verify tool behavior.
30
+
31
+ **Governance**: The `constitution.md` appears to be a template. Proceeding with standard best practices.
32
+
33
+ ## Project Structure
34
+
35
+ ### Documentation (this feature)
36
+
37
+ ```text
38
+ specs/001-mcp-api-integration/
39
+ ├── plan.md # This file
40
+ ├── research.md # Phase 0 output
41
+ ├── data-model.md # Phase 1 output
42
+ ├── quickstart.md # Phase 1 output
43
+ └── contracts/ # Phase 1 output (Copy of openapi.yaml)
44
+ ```
45
+
46
+ ### Source Code (repository root)
47
+
48
+ ```text
49
+ src/
50
+ ├── index.ts # Entry point (server setup)
51
+ ├── config.ts # Env var loading
52
+ ├── tools/ # New directory for tool definitions
53
+ │ ├── categories.ts # Category tools
54
+ │ ├── credit-cards.ts # Credit Card tools
55
+ │ ├── transactions.ts # Transaction tools
56
+ │ └── summary.ts # Summary tools
57
+ ├── services/ # New directory for API client
58
+ │ └── apiClient.ts # Typed fetch wrapper for Quantix API
59
+ └── types/ # Shared types / Zod schemas
60
+ └── schemas.ts # Zod schemas matching OpenAPI
61
+
62
+ tests/ # New directory
63
+ ├── tools/
64
+ │ └── transactions.test.ts
65
+ └── services/
66
+ └── apiClient.test.ts
67
+ ```
68
+
69
+ **Structure Decision**: Modular approach separating Tool Registration (UI layer) from API Logic (Service layer) and Schemas (Model layer).
70
+
71
+ ## Complexity Tracking
72
+
73
+ N/A
@@ -0,0 +1,74 @@
1
+ # Quickstart: Quantix MCP Server
2
+
3
+ This guide explains how to configure and run the Quantix MCP server integration.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+
8
+ - A running instance of the Quantix API (or access to Staging/Prod)
9
+ - An API Key for Quantix
10
+
11
+ ## Installation
12
+
13
+ 1. Install dependencies:
14
+ ```bash
15
+ npm install
16
+ ```
17
+
18
+ 2. Build the project:
19
+ ```bash
20
+ npm run build
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ Set the following environment variables. You can add them to a `.env` file or export them in your shell.
26
+
27
+ | Variable | Description | Example |
28
+ |----------|-------------|---------|
29
+ | `QUANTIX_API_URL` | Base URL of the Quantix API | `https://api.quantix.example.com` |
30
+ | `QUANTIX_API_KEY` | Your authentication key | `sk_live_12345` |
31
+ | `MPC_PORT` | Port for the MCP server | `3001` (default) |
32
+
33
+ ## Running the Server
34
+
35
+ ### Development Mode
36
+ ```bash
37
+ # Windows (PowerShell)
38
+ $env:QUANTIX_API_URL="https://api.quantix.example.com"; $env:QUANTIX_API_KEY="test"; npm run dev
39
+
40
+ # Linux/Mac
41
+ QUANTIX_API_URL=https://api.quantix.example.com QUANTIX_API_KEY=test npm run dev
42
+ ```
43
+
44
+ ### Production
45
+ ```bash
46
+ node dist/index.js
47
+ ```
48
+
49
+ ## Using with Claude Desktop
50
+
51
+ Add the server config to your Claude Desktop configuration file:
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "quantix": {
57
+ "command": "node",
58
+ "args": ["path/to/morpheus-mcp/dist/index.js"],
59
+ "env": {
60
+ "QUANTIX_API_URL": "...",
61
+ "QUANTIX_API_KEY": "..."
62
+ }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ ## Verification
69
+
70
+ To verify the integration, use the MCP Inspector or curl the running server (since it's HTTP/SSE based):
71
+
72
+ ```bash
73
+ curl http://localhost:3001/mcp
74
+ ```
@@ -0,0 +1,58 @@
1
+ # Research & Decisions: MCP API Integration
2
+
3
+ **Feature**: [spec.md](./spec.md)
4
+ **Status**: Complete
5
+
6
+ ## Unknowns & Clarifications
7
+
8
+ ### 1. Project Structure for Scaling Tools
9
+ **Question**: How to manage 12+ tools without bloating `index.ts`?
10
+ **Context**: Current `index.ts` has tool definition inline.
11
+ **Finding**: The MCP SDK `server.registerTool` can be called from imported modules if we pass the `mcpServer` instance, or better yet, we can export `Tool` definitions (name, description, schema, handler) and register them in a loop.
12
+ **Decision**:
13
+ - Create a `registerTools(server: McpServer)` function in each tool module (e.g., `src/tools/categories.ts`).
14
+ - `src/index.ts` will import these registration functions and call them.
15
+
16
+ ### 2. Mocking `fetch` for Tests
17
+ **Question**: Best way to test without hitting real API?
18
+ **Context**: We generally want unit tests to be fast and isolated.
19
+ **Finding**: Since we are using native `fetch` (Node 18+), we can use `vitest` to spy on `global.fetch` or use a library like `msw` (Mock Service Worker). Given the simplicity, basic `vi.spyOn(global, 'fetch')` is sufficient.
20
+ **Decision**: Use `vitest` and spy on `global.fetch`.
21
+
22
+ ## Technology Choices
23
+
24
+ | Area | Choice | Rationale |
25
+ |------|--------|-----------|
26
+ | **Validation** | `zod` | Native support in MCP SDK, TypeScript native, easy to derive from OpenAPI. |
27
+ | **HTTP Client** | Native `fetch` | No extra dependency weight, fully supported in modern Node. |
28
+ | **Testing** | `vitest` | Fast, compatible with ESM (Type "module" in package.json), Jest-compatible API. |
29
+ | **Env Vars** | `process.env` | Simple standard. |
30
+
31
+ ## Design Patterns
32
+
33
+ ### API Client Wrapper
34
+ Instead of calling `fetch` in every tool, we will create `src/services/apiClient.ts`:
35
+ ```typescript
36
+ async function apiFetch<T>(endpoint: string, options: RequestInit): Promise<T> {
37
+ const url = `${process.env.QUANTIX_API_URL}${endpoint}`;
38
+ const response = await fetch(url, {
39
+ ...options,
40
+ headers: {
41
+ ...options.headers,
42
+ 'API-KEY': process.env.QUANTIX_API_KEY
43
+ }
44
+ });
45
+ // Error handling logic here
46
+ return response.json();
47
+ }
48
+ ```
49
+
50
+ ### Zod Schema Reusability
51
+ We will define Zod schemas in `src/types/schemas.ts` that mirror the OpenAPI `components/schemas`. Use `z.infer` to generate TypeScript types for compile-time safety.
52
+
53
+ ## Alternatives Considered
54
+
55
+ - **OpenAPI Code Generator**: Could auto-generate the client.
56
+ - *Rejected*: Too heavy for 12 endpoints, harder to customize for MCP specific return formats.
57
+ - **Axios**:
58
+ - *Rejected*: `fetch` is built-in.
@@ -0,0 +1,119 @@
1
+ # Feature Specification: MCP Server for Quantix API Integration
2
+
3
+ **Feature Branch**: `001-mcp-api-integration`
4
+ **Created**: 2026-01-31
5
+ **Status**: Draft
6
+ **Input**: User description: "Vamos criar um servidor MCP para acessar todas essa rotas da nossa api, coloque o endereço da url como padrão vindo de env e api-key necessária também, use o zod para padronizar e especificar os inputs"
7
+
8
+ ## User Scenarios & Testing *(mandatory)*
9
+
10
+ ### User Story 1 - Configure and Start MCP Server (Priority: P1)
11
+
12
+ As a developer or AI agent, I want to configure the MCP server with the API URL and API Key so that I can securely access the financial data.
13
+
14
+ **Why this priority**: Essential for the server to function and authenticate.
15
+
16
+ **Independent Test**:
17
+ 1. Set `QUANTIX_API_URL` and `QUANTIX_API_KEY` environment variables.
18
+ 2. Start the server.
19
+ 3. Verify that the server starts without errors and is ready to accept requests.
20
+
21
+ **Acceptance Scenarios**:
22
+
23
+ 1. **Given** valid environment variables, **When** the server starts, **Then** it initializes successfully.
24
+ 2. **Given** missing API Key, **When** the server starts, **Then** it might warn or fail calls (depending on implementation), but tools should be registered.
25
+
26
+ ---
27
+
28
+ ### User Story 2 - Manage Financial Categories (Priority: P2)
29
+
30
+ As a user, I want to create, list, and delete categories to organize my finances.
31
+
32
+ **Why this priority**: Categories are foundational for transactions.
33
+
34
+ **Independent Test**: Use an MCP client to call category tools.
35
+
36
+ **Acceptance Scenarios**:
37
+
38
+ 1. **Given** the MCP server is running, **When** I call `get_categories`, **Then** I receive a list of categories.
39
+ 2. **Given** a new category name and type, **When** I call `create_category`, **Then** the category is created via the API.
40
+ 3. **Given** a category ID, **When** I call `delete_category`, **Then** the category is removed.
41
+
42
+ ---
43
+
44
+ ### User Story 3 - Manage Credit Cards and Statements (Priority: P2)
45
+
46
+ As a user, I want to manage credit cards and view/pay statements.
47
+
48
+ **Why this priority**: Credit card management is a core feature of the API.
49
+
50
+ **Independent Test**: Call credit card related tools.
51
+
52
+ **Acceptance Scenarios**:
53
+
54
+ 1. **Given** card details, **When** I call `create_credit_card`, **Then** a new card is added.
55
+ 2. **Given** a card ID and month, **When** I call `get_statement`, **Then** I see the transactions for that period.
56
+ 3. **Given** a card ID and month, **When** I call `pay_statement`, **Then** the transactions are marked as paid.
57
+
58
+ ---
59
+
60
+ ### User Story 4 - Manage Transactions and Summaries (Priority: P2)
61
+
62
+ As a user, I want to record transactions and view my monthly financial summary.
63
+
64
+ **Why this priority**: Core value of a finance manager.
65
+
66
+ **Independent Test**: Call transaction and summary tools.
67
+
68
+ **Acceptance Scenarios**:
69
+
70
+ 1. **Given** transaction details, **When** I call `create_transaction`, **Then** it is recorded.
71
+ 2. **Given** a month, **When** I call `get_transactions`, **Then** I see the list of transactions.
72
+ 3. **Given** a month, **When** I call `get_summary`, **Then** I see income, expenses, and balance.
73
+ 4. **Given** a transaction ID, **When** I call `pay_transaction`, **Then** it is marked as paid.
74
+
75
+ ## Functional Requirements
76
+
77
+ 1. **Environment Configuration**:
78
+ - Support `QUANTIX_API_URL` (defaulting to `https://api.quantix.example.com` or requiring it).
79
+ - Support `QUANTIX_API_KEY` for authentication header `API-KEY`.
80
+
81
+ 2. **Tool Registration**:
82
+ - Register the following tools in the MCP server:
83
+ - `create_category`
84
+ - `get_categories`
85
+ - `delete_category`
86
+ - `create_credit_card`
87
+ - `get_credit_cards`
88
+ - `get_statement`
89
+ - `pay_statement`
90
+ - `create_transaction`
91
+ - `get_transactions`
92
+ - `pay_transaction`
93
+ - `delete_transaction`
94
+ - `get_summary`
95
+
96
+ 3. **Input Validation**:
97
+ - Use `zod` to define input schemas for all tools.
98
+ - Schemas must match the OpenApi 3.0 definitions provided in `openapi.yaml`.
99
+
100
+ 4. **API Integration**:
101
+ - Make HTTP requests to the configured `QUANTIX_API_URL`.
102
+ - Forward the API Key in headers.
103
+ - Return clear output messages based on API responses.
104
+
105
+ ## Success Criteria
106
+
107
+ 1. **measurable**: 100% of the 12 identified API endpoints are exposed as MCP tools.
108
+ 2. **measurable**: Inputs for all tools are validated using Zod schemas.
109
+ 3. **verifiable**: The server connects to the backend using the environment variables.
110
+ 4. **verifiable**: Tools return meaningful success/error messages to the model.
111
+
112
+ ## Assumptions
113
+
114
+ - The `openapi.yaml` is the source of truth for schemas.
115
+ - The existing project structure with `src/index.ts` determines the server setup (Express + MCP SDK).
116
+
117
+ ## Clarifications
118
+
119
+ - None at this stage.
@@ -0,0 +1,64 @@
1
+ # Tasks: MCP Server for Quantix API Integration
2
+
3
+ **Spec**: [spec.md](spec.md)
4
+ **Plan**: [plan.md](plan.md)
5
+ **Status**: In Progress
6
+
7
+ ## Phase 1: Setup
8
+ *Goal: Initialize project structure and dependencies*
9
+
10
+ - [x] T001 [P] Install Vitest and testing dependencies in `package.json`
11
+ - [x] T002 [P] Create project directory structure (`src/tools`, `src/services`, `src/types`, `tests`)
12
+ - [x] T003 Implement `src/config.ts` for environment variable management
13
+ - [x] T004 [P] Configure Vitest in `vitest.config.ts` (or script in package.json)
14
+
15
+ ## Phase 2: Foundational & Shared Components
16
+ *Goal: Establish core API client and data schemas*
17
+
18
+ - [x] T005 [P] Implement `src/services/apiClient.ts` with authentication and typed `fetch`
19
+ - [x] T006 [P] Implement `src/types/schemas.ts` with Zod definitions for all entities (Category, Transaction, etc.)
20
+ - [x] T007 Create basic test setup/helpers in `tests/setup.ts`
21
+
22
+ ## Phase 3: Server Configuration (User Story 1)
23
+ *Goal: Server starts with correct configuration and tool registration architecture*
24
+
25
+ - [x] T008 [US1] Refactor `src/index.ts` to use `src/config.ts` and support modular tool registration
26
+ - [x] T009 [US1] Create integration test `tests/server.test.ts` to verify server startup and env handling
27
+
28
+ ## Phase 4: Categories Support (User Story 2)
29
+ *Goal: Enable management of financial categories*
30
+
31
+ - [x] T010 [US2] TDD: Implement `src/tools/categories.ts` (write tests in `tests/tools/categories.test.ts` first)
32
+ - [x] T011 [US2] Register category tools in `src/index.ts`
33
+
34
+ ## Phase 5: Credit Cards Support (User Story 3)
35
+ *Goal: Enable management of credit cards and statements*
36
+
37
+ - [x] T012 [US3] TDD: Implement `src/tools/credit-cards.ts` (write tests in `tests/tools/credit-cards.test.ts` first)
38
+ - [x] T013 [US3] Register credit card tools in `src/index.ts`
39
+
40
+ ## Phase 6: Transactions & Summary Support (User Story 4)
41
+ *Goal: Enable transaction recording and financial summaries*
42
+
43
+ - [x] T014 [US4] TDD: Implement `src/tools/transactions.ts` (write tests in `tests/tools/transactions.test.ts` first)
44
+ - [x] T015 [US4] TDD: Implement `src/tools/summary.ts` (write tests in `tests/tools/summary.test.ts` first)
45
+ - [x] T016 [US4] Register transaction and summary tools in `src/index.ts`
46
+
47
+ ## Phase 7: Polish & Documentation
48
+ *Goal: Final verification and cleanup*
49
+
50
+ - [x] T017 Remove legacy `get_crypto_price` example from `src/index.ts`
51
+ - [x] T018 Verify `quickstart.md` instructions against the running server
52
+ - [x] T019 Run full test suite and ensure all tests pass
53
+ - [x] T020 Benchmark tool overhead to verify <20ms latency goal
54
+
55
+ ## Dependencies
56
+
57
+ - Phase 2 depends on Phase 1
58
+ - Phase 3 depends on Phase 2 (config & client)
59
+ - Phase 4, 5, 6 depend on Phase 3 (server setup) and Phase 2 (schemas/client)
60
+ - Phases 4, 5, 6 can be executed in parallel (independent modules), but registered sequentially in T0XX tasks if strictly following order.
61
+
62
+ ## Implementation Strategy
63
+ - **MVP**: Complete through Phase 3 + Phase 4 (Categories) to prove the pattern.
64
+ - **Incremental**: Add Credit Cards and Transactions as separate modules.
package/src/config.ts ADDED
@@ -0,0 +1,36 @@
1
+ import 'dotenv/config';
2
+ import * as z from 'zod';
3
+
4
+ const envSchema = z.object({
5
+ QUANTIX_API_URL: z.string().default('https://api.quantix.example.com'),
6
+ QUANTIX_API_KEY: z.string().min(1, "QUANTIX_API_KEY is required"),
7
+ MCPPORT: z.string().optional().default('3001'),
8
+ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
9
+ });
10
+
11
+ const processEnv = {
12
+ QUANTIX_API_URL: process.env.QUANTIX_API_URL,
13
+ QUANTIX_API_KEY: process.env.QUANTIX_API_KEY,
14
+ MCPPORT: process.env.MCPPORT,
15
+ NODE_ENV: process.env.NODE_ENV,
16
+ };
17
+
18
+ // Parse and validate environment variables
19
+ const parsedEnv = envSchema.safeParse(processEnv);
20
+
21
+ if (!parsedEnv.success) {
22
+ console.error("❌ Invalid environment variables:", parsedEnv.error.format());
23
+
24
+ // In a real app, we might want to throw here, but for now we'll just log
25
+ // and let the application fail when it tries to use the missing keys if essential
26
+ if (process.env.NODE_ENV !== 'test') {
27
+ // Allow tests to run without all env vars if they mock config
28
+ }
29
+ }
30
+
31
+ export const config = parsedEnv.success ? parsedEnv.data : {
32
+ QUANTIX_API_URL: process.env.QUANTIX_API_URL || 'https://api.quantix.example.com',
33
+ QUANTIX_API_KEY: process.env.QUANTIX_API_KEY || 'your_api_key_here',
34
+ MCPPORT: process.env.MCPPORT || '3001',
35
+ NODE_ENV: (process.env.NODE_ENV as 'development' | 'production' | 'test') || 'development'
36
+ };
package/src/index.ts ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
5
+ import express, { type Request, type Response } from 'express';
6
+ import { config } from './config.js';
7
+ import { z } from 'zod';
8
+ import { registerCategoryTools } from './tools/categories.js';
9
+ import { registerCreditCardTools } from './tools/credit-cards.js';
10
+ import { registerTransactionTools } from './tools/transactions.js';
11
+ import { registerSummaryTools } from './tools/summary.js';
12
+ import { registerAccountTools } from './tools/accounts.js';
13
+ import { registerSettingsTools } from './tools/settings.js';
14
+
15
+ export function getServer() {
16
+ const mcpServer = new McpServer({
17
+ name: 'quantix_mcp_server',
18
+ version: '1.0.0'
19
+ });
20
+
21
+ console.log('McpServer started');
22
+
23
+ // Register Tools here
24
+ registerCategoryTools(mcpServer);
25
+ registerCreditCardTools(mcpServer);
26
+ registerTransactionTools(mcpServer);
27
+ registerSummaryTools(mcpServer);
28
+ registerAccountTools(mcpServer);
29
+ registerSettingsTools(mcpServer);
30
+
31
+ return mcpServer;
32
+ }
33
+
34
+ const app = express();
35
+ app.use(express.json());
36
+
37
+ app.post('/mcp', async (req: Request, res: Response) => {
38
+ const mcpServer = getServer();
39
+
40
+ const transport = new StreamableHTTPServerTransport({
41
+ });
42
+ const mcpTransport = transport as unknown as Transport;
43
+
44
+ res.on('close', () => {
45
+ transport.close();
46
+ mcpServer.close();
47
+ });
48
+
49
+ await mcpServer.connect(mcpTransport);
50
+ await transport.handleRequest(req, res, req.body);
51
+ });
52
+
53
+ if (config.NODE_ENV !== 'test') {
54
+ const MCPPORT = config.MCPPORT;
55
+ app.listen(MCPPORT, () => {
56
+ console.log(`MCP server is running on http://localhost:${MCPPORT}/mcp`);
57
+ });
58
+ }
59
+
60
+ export { app };
@@ -0,0 +1,49 @@
1
+ import { config } from '../config.js';
2
+
3
+ export class ApiClientError extends Error {
4
+ constructor(public message: string, public status: number, public statusText: string) {
5
+ super(message);
6
+ this.name = 'ApiClientError';
7
+ }
8
+ }
9
+
10
+ async function apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
11
+ const url = `${config.QUANTIX_API_URL}${endpoint}`;
12
+
13
+ const headers = {
14
+ 'Content-Type': 'application/json',
15
+ 'x-api-key': config.QUANTIX_API_KEY,
16
+ ...options.headers,
17
+ };
18
+
19
+ const response = await fetch(url, {
20
+ ...options,
21
+ headers,
22
+ });
23
+
24
+ if (!response.ok) {
25
+ throw new ApiClientError(
26
+ `API request failed: ${response.status} ${response.statusText}`,
27
+ response.status,
28
+ response.statusText
29
+ );
30
+ }
31
+
32
+ // Handle 204 No Content
33
+ if (response.status === 204) {
34
+ return {} as T;
35
+ }
36
+
37
+ return response.json();
38
+ }
39
+
40
+ export const apiClient = {
41
+ get: <T>(endpoint: string) => apiFetch<T>(endpoint, { method: 'GET' }),
42
+ post: <T>(endpoint: string, body: unknown) =>
43
+ apiFetch<T>(endpoint, { method: 'POST', body: JSON.stringify(body) }),
44
+ patch: <T>(endpoint: string, body: unknown = {}) =>
45
+ apiFetch<T>(endpoint, { method: 'PATCH', body: JSON.stringify(body) }),
46
+ put: <T>(endpoint: string, body: unknown) =>
47
+ apiFetch<T>(endpoint, { method: 'PUT', body: JSON.stringify(body) }),
48
+ delete: <T>(endpoint: string) => apiFetch<T>(endpoint, { method: 'DELETE' }),
49
+ };