bkper 3.5.5 → 3.6.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.
- package/README.md +36 -40
- package/lib/auth/local-auth-service.js +3 -3
- package/lib/auth/local-auth-service.js.map +1 -1
- package/lib/mcp/domain/transaction/merge-operation.d.ts +48 -0
- package/lib/mcp/domain/transaction/merge-operation.d.ts.map +1 -0
- package/lib/mcp/domain/transaction/merge-operation.js +195 -0
- package/lib/mcp/domain/transaction/merge-operation.js.map +1 -0
- package/lib/mcp/domain/transaction/merge-types.d.ts +25 -0
- package/lib/mcp/domain/transaction/merge-types.d.ts.map +1 -0
- package/lib/mcp/domain/transaction/merge-types.js +8 -0
- package/lib/mcp/domain/transaction/merge-types.js.map +1 -0
- package/lib/mcp/server.d.ts.map +1 -1
- package/lib/mcp/server.js +63 -16
- package/lib/mcp/server.js.map +1 -1
- package/lib/mcp/tools/create_transactions.d.ts +59 -0
- package/lib/mcp/tools/create_transactions.d.ts.map +1 -0
- package/lib/mcp/tools/create_transactions.js +163 -0
- package/lib/mcp/tools/create_transactions.js.map +1 -0
- package/lib/mcp/tools/merge_transactions.d.ts +40 -0
- package/lib/mcp/tools/merge_transactions.d.ts.map +1 -0
- package/lib/mcp/tools/merge_transactions.js +120 -0
- package/lib/mcp/tools/merge_transactions.js.map +1 -0
- package/package.json +76 -76
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[Bkper REST API]: https://bkper.com/docs/#rest-api-enabling
|
|
2
2
|
|
|
3
|
-
A **command line** utility for managing [Bkper Apps and Bots](https://bkper.com/docs/) and running the [Model Context Protocol (MCP) server](https://modelcontextprotocol.io).
|
|
3
|
+
A **command line** utility for managing [Bkper Apps and Bots](https://bkper.com/docs/) and running the [Model Context Protocol (MCP) server](https://modelcontextprotocol.io).
|
|
4
4
|
|
|
5
5
|
The MCP server enables AI assistants and agents to interact with your Bkper books through a standardized protocol.
|
|
6
6
|
|
|
@@ -13,37 +13,45 @@ The MCP server enables AI assistants and agents to interact with your Bkper book
|
|
|
13
13
|
```
|
|
14
14
|
npm i bkper
|
|
15
15
|
```
|
|
16
|
+
|
|
16
17
|
or
|
|
18
|
+
|
|
17
19
|
```
|
|
18
20
|
yarn add bkper
|
|
19
21
|
```
|
|
22
|
+
|
|
20
23
|
or
|
|
24
|
+
|
|
21
25
|
```
|
|
22
26
|
bun add bkper
|
|
23
27
|
```
|
|
24
28
|
|
|
25
|
-
Optionally, you can install it globally to be able to use the
|
|
29
|
+
Optionally, you can install it globally to be able to use the `bkper` command line utility:
|
|
26
30
|
|
|
27
31
|
```
|
|
28
32
|
npm i -g bkper
|
|
29
33
|
```
|
|
34
|
+
|
|
30
35
|
or
|
|
36
|
+
|
|
31
37
|
```
|
|
32
38
|
yarn global add bkper
|
|
33
39
|
```
|
|
34
40
|
|
|
35
41
|
## Commands
|
|
36
42
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
43
|
+
- `login` - Logs the user in. Saves the client credentials to a `~/.config/bkper/.bkper-credentials.json` file.
|
|
44
|
+
- `logout` - Logs out the user by deleting client credentials.
|
|
45
|
+
- `mcp start` - Start the Bkper MCP (Model Context Protocol) server.
|
|
46
|
+
- `app -c` - Create a new App based on `./bkperapp.yaml` file.
|
|
47
|
+
- `app -u` - Update an existing App based on `./bkperapp.yaml` file.
|
|
42
48
|
|
|
43
49
|
### Examples
|
|
50
|
+
|
|
44
51
|
```
|
|
45
52
|
npm bkper login
|
|
46
53
|
```
|
|
54
|
+
|
|
47
55
|
```
|
|
48
56
|
yarn bkper login
|
|
49
57
|
```
|
|
@@ -68,6 +76,7 @@ The server runs on stdio and provides the following tools:
|
|
|
68
76
|
#### Prerequisites
|
|
69
77
|
|
|
70
78
|
Before using the MCP server:
|
|
79
|
+
|
|
71
80
|
1. Login using `bkper login` to set up authentication
|
|
72
81
|
2. Enable the [Bkper REST API]
|
|
73
82
|
3. Ensure the `BKPER_API_KEY` environment variable is set.
|
|
@@ -79,6 +88,7 @@ The MCP server uses the same authentication as the CLI, reading credentials from
|
|
|
79
88
|
##### Claude Desktop
|
|
80
89
|
|
|
81
90
|
Add to your configuration file:
|
|
91
|
+
|
|
82
92
|
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
83
93
|
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
84
94
|
|
|
@@ -99,6 +109,7 @@ Add to your configuration file:
|
|
|
99
109
|
##### Other MCP Clients
|
|
100
110
|
|
|
101
111
|
For other MCP-compatible clients, configure them to run:
|
|
112
|
+
|
|
102
113
|
```bash
|
|
103
114
|
BKPER_API_KEY=your-api-key npx bkper mcp start
|
|
104
115
|
```
|
|
@@ -108,6 +119,7 @@ The server communicates via stdio, so any MCP client that supports stdio transpo
|
|
|
108
119
|
#### Available MCP Tools
|
|
109
120
|
|
|
110
121
|
Once connected, the MCP client can:
|
|
122
|
+
|
|
111
123
|
- List your Bkper books
|
|
112
124
|
- Get account balances for any date or period
|
|
113
125
|
- Search and filter transactions
|
|
@@ -115,18 +127,17 @@ Once connected, the MCP client can:
|
|
|
115
127
|
|
|
116
128
|
For more information about the Model Context Protocol, visit [modelcontextprotocol.io](https://modelcontextprotocol.io).
|
|
117
129
|
|
|
118
|
-
|
|
119
|
-
|
|
120
130
|
## Apps and Bots
|
|
121
131
|
|
|
122
132
|
### Environment Variables
|
|
133
|
+
|
|
123
134
|
The following environment variable is necessary in order to communicate with the [Bkper REST API]:
|
|
124
135
|
|
|
125
136
|
```
|
|
126
137
|
BKPER_API_KEY=XXXX
|
|
127
138
|
```
|
|
128
139
|
|
|
129
|
-
The
|
|
140
|
+
The `app` command also uses the following variables in order to perform App create/update operations:
|
|
130
141
|
|
|
131
142
|
```
|
|
132
143
|
BKPER_CLIENT_SECRET=YYYY
|
|
@@ -134,16 +145,14 @@ BKPER_USER_EMAILS="someone@gmail.com anotherone@altrostat.com"
|
|
|
134
145
|
BKPER_DEVELOPER_EMAIL=somedeveloer@mycompany.com
|
|
135
146
|
```
|
|
136
147
|
|
|
137
|
-
You can add a
|
|
148
|
+
You can add a `.env` file at the root of your project with those variables and bkper will automatically load from it.
|
|
138
149
|
Follow [these](https://bkper.com/docs/#rest-api-enabling) steps in order to configure a valid Bkper API key.
|
|
139
150
|
|
|
140
151
|
> WARNING: Never upload variables to the source code repository.
|
|
141
152
|
|
|
142
|
-
|
|
143
|
-
### ```./bkperapp.yaml``` Reference
|
|
153
|
+
### `./bkperapp.yaml` Reference
|
|
144
154
|
|
|
145
155
|
```yaml
|
|
146
|
-
|
|
147
156
|
# BASIC APP CONFIGURATION
|
|
148
157
|
|
|
149
158
|
# The agent id of the App or Bot. It can NOT be changed after the App or Bot is created.
|
|
@@ -158,8 +167,6 @@ logoUrl: https://static.thenounproject.com/png/2318500-200.png
|
|
|
158
167
|
# The logo url to be used when in dark mode
|
|
159
168
|
logoUrlDark: https://static.thenounproject.com/png/2318500-200.png
|
|
160
169
|
|
|
161
|
-
|
|
162
|
-
|
|
163
170
|
# CONTEXT MENU CONFIGURATION
|
|
164
171
|
|
|
165
172
|
# The menu production url to open in the popup window. See accepted expressions bellow.
|
|
@@ -174,20 +181,12 @@ menuText: Open My Custom App
|
|
|
174
181
|
menuPopupWidth: 500 # width in pixels. Default to 80% of screen width.
|
|
175
182
|
menuPopupHeight: 300 # height in pixels. Default to 90% of screen height.
|
|
176
183
|
|
|
177
|
-
|
|
178
|
-
#ASSISTANT CONFIGURATION
|
|
179
|
-
|
|
180
|
-
# The conversation url to be called by Bkper when a new conversation message is added
|
|
181
|
-
conversationUrl: https://us-central1-bkper-tax-trigger.cloudfunctions.net/chat
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
184
|
# BOT EVENTS CONFIGURATION
|
|
186
185
|
|
|
187
186
|
# The webhook url to be called by Bkper when an event occurs.
|
|
188
187
|
webhookUrl: https://us-central1-bkper-tax-trigger.cloudfunctions.net/events
|
|
189
188
|
|
|
190
|
-
# The events the Bot is capable of processing by the webhook.
|
|
189
|
+
# The events the Bot is capable of processing by the webhook.
|
|
191
190
|
# This is optional and, if not specified, no events will be processed.
|
|
192
191
|
events:
|
|
193
192
|
- "TRANSACTION_POSTED"
|
|
@@ -211,7 +210,6 @@ filePatterns:
|
|
|
211
210
|
- "-*.qif"
|
|
212
211
|
- "*.csv"
|
|
213
212
|
|
|
214
|
-
|
|
215
213
|
# Schema to provide autocompletion on properties editor.
|
|
216
214
|
propertiesSchema:
|
|
217
215
|
book:
|
|
@@ -242,19 +240,18 @@ propertiesSchema:
|
|
|
242
240
|
values:
|
|
243
241
|
- "value2"
|
|
244
242
|
- "value2"
|
|
245
|
-
|
|
246
243
|
```
|
|
247
244
|
|
|
248
245
|
#### Accepted expressions in menuUrl property:
|
|
249
246
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
247
|
+
- `${book.id}` - the current book id
|
|
248
|
+
- `${book.properties.xxxxx}` - any property value from the current book
|
|
249
|
+
- `${transactions.query}` - the current query being executed on transactions list
|
|
250
|
+
- `${transactions.ids}` - the ids of selected transactions, splitted by comma
|
|
251
|
+
- `${account.id}` - the current account being filterd
|
|
252
|
+
- `${account.properties.xxxxx}` - any property value from the current account being filtered
|
|
253
|
+
- `${group.id}` - the current group being filterd
|
|
254
|
+
- `${group.properties.xxxxx}` - any property value from the current group being filtered
|
|
258
255
|
|
|
259
256
|
#### Example:
|
|
260
257
|
|
|
@@ -264,20 +261,19 @@ propertiesSchema:
|
|
|
264
261
|
|
|
265
262
|
#### Library
|
|
266
263
|
|
|
267
|
-
The
|
|
264
|
+
The `getOAuthToken` returns a Promise that resolves to a valid OAuth token, to be used by the [`bkper-js`](https://github.com/bkper/bkper-js) library
|
|
268
265
|
|
|
269
266
|
Example:
|
|
270
267
|
|
|
271
268
|
```javascript
|
|
272
|
-
import { Bkper } from
|
|
273
|
-
import { getOAuthToken } from
|
|
269
|
+
import { Bkper } from "bkper-js";
|
|
270
|
+
import { getOAuthToken } from "bkper";
|
|
274
271
|
|
|
275
272
|
Bkper.setConfig({
|
|
276
273
|
oauthTokenProvider: async () => getOAuthToken(),
|
|
277
|
-
})
|
|
274
|
+
});
|
|
278
275
|
```
|
|
279
276
|
|
|
280
277
|
## Documentation
|
|
281
278
|
|
|
282
279
|
- [Developer Docs](https://bkper.com/docs)
|
|
283
|
-
|
|
@@ -31,10 +31,10 @@ if (!fs.existsSync(storedCredentialsPath) && fs.existsSync(oldCredentialsPath))
|
|
|
31
31
|
const oldCredentials = fs.readFileSync(oldCredentialsPath, 'utf8');
|
|
32
32
|
fs.writeFileSync(storedCredentialsPath, oldCredentials, 'utf8');
|
|
33
33
|
fs.rmSync(oldCredentialsPath);
|
|
34
|
-
|
|
34
|
+
// Credentials migrated successfully
|
|
35
35
|
}
|
|
36
36
|
catch (err) {
|
|
37
|
-
|
|
37
|
+
// Migration failed - will fall back to old behavior
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
try {
|
|
@@ -42,7 +42,7 @@ try {
|
|
|
42
42
|
storedCredentials = JSON.parse(credentialsJson);
|
|
43
43
|
}
|
|
44
44
|
catch (err) {
|
|
45
|
-
|
|
45
|
+
// Credentials will be null if not found - no need to log during module loading
|
|
46
46
|
}
|
|
47
47
|
export function login() {
|
|
48
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-auth-service.js","sourceRoot":"","sources":["../../src/auth/local-auth-service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAQ,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;AACvF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,gCAAgC;AAE5E,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,SAAS,YAAY,CAAC,CAAC;AAE/C,IAAI,iBAA8B,CAAC;AAEnC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,0BAA0B,CAAC;AACrE,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC;AAClD,MAAM,qBAAqB,GAAG,GAAG,SAAS,0BAA0B,CAAC;AAErE,sCAAsC;AACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;IAC/E,IAAI,CAAC;QACH,iCAAiC;QACjC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,mCAAmC;QACnC,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QACnE,EAAE,CAAC,aAAa,CAAC,qBAAqB,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QAChE,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC9B,
|
|
1
|
+
{"version":3,"file":"local-auth-service.js","sourceRoot":"","sources":["../../src/auth/local-auth-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction Merge Operation - Domain Logic
|
|
3
|
+
*
|
|
4
|
+
* Pure business logic for merging two transactions into one.
|
|
5
|
+
* This class contains no dependencies on MCP, HTTP, or other infrastructure concerns.
|
|
6
|
+
* It operates on Transaction domain objects from bkper-js.
|
|
7
|
+
*/
|
|
8
|
+
import { Transaction, Book } from 'bkper-js';
|
|
9
|
+
import { MergedTransactionData } from './merge-types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Represents the result of a transaction merge operation
|
|
12
|
+
*
|
|
13
|
+
* Determines which transaction to keep (edit) vs discard (revert),
|
|
14
|
+
* then intelligently merges data from both transactions.
|
|
15
|
+
*/
|
|
16
|
+
export declare class TransactionMergeOperation {
|
|
17
|
+
private book;
|
|
18
|
+
editTransaction: Transaction;
|
|
19
|
+
revertTransaction: Transaction;
|
|
20
|
+
mergedData: MergedTransactionData;
|
|
21
|
+
record: string | null;
|
|
22
|
+
private static readonly WORD_SPLITTER;
|
|
23
|
+
constructor(book: Book, transaction1: Transaction, transaction2: Transaction);
|
|
24
|
+
/**
|
|
25
|
+
* Merges data from both transactions into a single transaction data object
|
|
26
|
+
* @returns Merged transaction data
|
|
27
|
+
*/
|
|
28
|
+
private merge;
|
|
29
|
+
/**
|
|
30
|
+
* Merges two descriptions intelligently, avoiding duplicate words
|
|
31
|
+
* @param desc1 First description (from edit transaction)
|
|
32
|
+
* @param desc2 Second description (from revert transaction)
|
|
33
|
+
* @returns Merged description with unique words
|
|
34
|
+
*/
|
|
35
|
+
private mergeDescription;
|
|
36
|
+
/**
|
|
37
|
+
* Trims and normalizes whitespace in text
|
|
38
|
+
* @param text Text to trim
|
|
39
|
+
* @returns Trimmed text with normalized whitespace
|
|
40
|
+
*/
|
|
41
|
+
private trim;
|
|
42
|
+
/**
|
|
43
|
+
* Apply the merged data to the edit transaction
|
|
44
|
+
* This mutates the edit transaction object with the merged data
|
|
45
|
+
*/
|
|
46
|
+
applyMergedData(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=merge-operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-operation.d.ts","sourceRoot":"","sources":["../../../../src/mcp/domain/transaction/merge-operation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;;;GAKG;AACH,qBAAa,yBAAyB;IAS9B,OAAO,CAAC,IAAI;IART,eAAe,EAAE,WAAW,CAAC;IAC7B,iBAAiB,EAAE,WAAW,CAAC;IAC/B,UAAU,EAAE,qBAAqB,CAAC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAa;gBAGtC,IAAI,EAAE,IAAI,EAClB,YAAY,EAAE,WAAW,EACzB,YAAY,EAAE,WAAW;IA8B7B;;;OAGG;IACH,OAAO,CAAC,KAAK;IAkFb;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACH,OAAO,CAAC,IAAI;IAIZ;;;OAGG;IACH,eAAe,IAAI,IAAI;CAsD1B"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction Merge Operation - Domain Logic
|
|
3
|
+
*
|
|
4
|
+
* Pure business logic for merging two transactions into one.
|
|
5
|
+
* This class contains no dependencies on MCP, HTTP, or other infrastructure concerns.
|
|
6
|
+
* It operates on Transaction domain objects from bkper-js.
|
|
7
|
+
*/
|
|
8
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Represents the result of a transaction merge operation
|
|
11
|
+
*
|
|
12
|
+
* Determines which transaction to keep (edit) vs discard (revert),
|
|
13
|
+
* then intelligently merges data from both transactions.
|
|
14
|
+
*/
|
|
15
|
+
export class TransactionMergeOperation {
|
|
16
|
+
constructor(book, transaction1, transaction2) {
|
|
17
|
+
var _a, _b;
|
|
18
|
+
this.book = book;
|
|
19
|
+
this.record = null;
|
|
20
|
+
// Determine which transaction to edit vs revert based on priority rules
|
|
21
|
+
const tx1IsPosted = (_a = transaction1.isPosted()) !== null && _a !== void 0 ? _a : false;
|
|
22
|
+
const tx2IsPosted = (_b = transaction2.isPosted()) !== null && _b !== void 0 ? _b : false;
|
|
23
|
+
// Rule 1: Prefer posted transactions over drafts
|
|
24
|
+
if (!tx1IsPosted && tx2IsPosted) {
|
|
25
|
+
this.revertTransaction = transaction1;
|
|
26
|
+
this.editTransaction = transaction2;
|
|
27
|
+
}
|
|
28
|
+
else if (tx1IsPosted && !tx2IsPosted) {
|
|
29
|
+
this.revertTransaction = transaction2;
|
|
30
|
+
this.editTransaction = transaction1;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Rule 2: If both same status, prefer newer transaction (higher createdAt)
|
|
34
|
+
const tx1Created = transaction1.getCreatedAt().getTime();
|
|
35
|
+
const tx2Created = transaction2.getCreatedAt().getTime();
|
|
36
|
+
if (tx1Created < tx2Created) {
|
|
37
|
+
this.revertTransaction = transaction1;
|
|
38
|
+
this.editTransaction = transaction2;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.revertTransaction = transaction2;
|
|
42
|
+
this.editTransaction = transaction1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
this.mergedData = this.merge();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Merges data from both transactions into a single transaction data object
|
|
49
|
+
* @returns Merged transaction data
|
|
50
|
+
*/
|
|
51
|
+
merge() {
|
|
52
|
+
// Start with edit transaction's JSON data as base
|
|
53
|
+
const merged = Object.assign({}, this.editTransaction.json());
|
|
54
|
+
// Merge description using Transaction wrapper
|
|
55
|
+
const editDescription = this.editTransaction.getDescription();
|
|
56
|
+
const revertDescription = this.revertTransaction.getDescription();
|
|
57
|
+
merged.description = this.mergeDescription(editDescription || null, revertDescription || null);
|
|
58
|
+
// Merge files using Transaction wrapper
|
|
59
|
+
const editFiles = this.editTransaction.getFiles() || [];
|
|
60
|
+
const revertFiles = this.revertTransaction.getFiles() || [];
|
|
61
|
+
const mergedFiles = [
|
|
62
|
+
...editFiles.map(f => f.json()),
|
|
63
|
+
...revertFiles.map(f => f.json())
|
|
64
|
+
];
|
|
65
|
+
merged.files = mergedFiles;
|
|
66
|
+
// Keep "attachments" for backward compatibility with test fixtures
|
|
67
|
+
merged.attachments = mergedFiles;
|
|
68
|
+
// Merge remote IDs using Transaction wrapper
|
|
69
|
+
const editRemoteIds = this.editTransaction.getRemoteIds();
|
|
70
|
+
const revertRemoteIds = this.revertTransaction.getRemoteIds();
|
|
71
|
+
merged.remoteIds = [...new Set([...editRemoteIds, ...revertRemoteIds])];
|
|
72
|
+
// Merge URLs using Transaction wrapper
|
|
73
|
+
const editUrls = this.editTransaction.getUrls();
|
|
74
|
+
const revertUrls = this.revertTransaction.getUrls();
|
|
75
|
+
merged.urls = [...new Set([...editUrls, ...revertUrls])];
|
|
76
|
+
// Merge properties using Transaction wrapper (revert overwrites edit)
|
|
77
|
+
const editProperties = this.editTransaction.getProperties();
|
|
78
|
+
const revertProperties = this.revertTransaction.getProperties();
|
|
79
|
+
merged.properties = Object.assign(Object.assign({}, editProperties), revertProperties);
|
|
80
|
+
// Backfill credit account - get from revert if edit doesn't have it
|
|
81
|
+
const editData = this.editTransaction.json();
|
|
82
|
+
const revertData = this.revertTransaction.json();
|
|
83
|
+
if (!editData.creditAccount && !editData.creditAccountId) {
|
|
84
|
+
if (revertData.creditAccount)
|
|
85
|
+
merged.creditAccount = revertData.creditAccount;
|
|
86
|
+
const revertCompat = revertData;
|
|
87
|
+
if (revertCompat.creditAccountId)
|
|
88
|
+
merged.creditAccountId = revertCompat.creditAccountId;
|
|
89
|
+
}
|
|
90
|
+
// Backfill debit account - get from revert if edit doesn't have it
|
|
91
|
+
if (!editData.debitAccount && !editData.debitAccountId) {
|
|
92
|
+
if (revertData.debitAccount)
|
|
93
|
+
merged.debitAccount = revertData.debitAccount;
|
|
94
|
+
const revertCompat = revertData;
|
|
95
|
+
if (revertCompat.debitAccountId)
|
|
96
|
+
merged.debitAccountId = revertCompat.debitAccountId;
|
|
97
|
+
}
|
|
98
|
+
// Handle amount validation and merging using Transaction wrapper
|
|
99
|
+
const editAmount = this.editTransaction.getAmount();
|
|
100
|
+
const revertAmount = this.revertTransaction.getAmount();
|
|
101
|
+
if (editAmount && revertAmount) {
|
|
102
|
+
// Both have amounts - validate they are equal
|
|
103
|
+
if (editAmount.cmp(revertAmount) !== 0) {
|
|
104
|
+
// Amounts differ - throw error for manual reconciliation
|
|
105
|
+
throw new McpError(ErrorCode.InvalidParams, `Cannot merge transactions with different amounts: ${editAmount.toString()} vs ${revertAmount.toString()}. ` +
|
|
106
|
+
`Please reconcile amounts manually before merging.`);
|
|
107
|
+
}
|
|
108
|
+
// Amounts are equal - keep edit's amount (no change needed)
|
|
109
|
+
}
|
|
110
|
+
else if (!editAmount && revertAmount) {
|
|
111
|
+
// Edit has no amount, use revert's amount
|
|
112
|
+
merged.amount = revertAmount.toString();
|
|
113
|
+
}
|
|
114
|
+
// If edit has amount and revert doesn't, keep edit's amount (already in merged)
|
|
115
|
+
return merged;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Merges two descriptions intelligently, avoiding duplicate words
|
|
119
|
+
* @param desc1 First description (from edit transaction)
|
|
120
|
+
* @param desc2 Second description (from revert transaction)
|
|
121
|
+
* @returns Merged description with unique words
|
|
122
|
+
*/
|
|
123
|
+
mergeDescription(desc1, desc2) {
|
|
124
|
+
if (!desc1)
|
|
125
|
+
return desc2 || '';
|
|
126
|
+
if (!desc2)
|
|
127
|
+
return desc1;
|
|
128
|
+
const desc1Lower = desc1.toLowerCase();
|
|
129
|
+
const words = desc2.split(TransactionMergeOperation.WORD_SPLITTER)
|
|
130
|
+
.filter(word => word.length > 0);
|
|
131
|
+
const uniqueWords = words.filter(word => !desc1Lower.includes(word.toLowerCase()));
|
|
132
|
+
return this.trim(desc1 + ' ' + uniqueWords.join(' '));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Trims and normalizes whitespace in text
|
|
136
|
+
* @param text Text to trim
|
|
137
|
+
* @returns Trimmed text with normalized whitespace
|
|
138
|
+
*/
|
|
139
|
+
trim(text) {
|
|
140
|
+
return text.trim().replace(/\s+/g, ' ');
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Apply the merged data to the edit transaction
|
|
144
|
+
* This mutates the edit transaction object with the merged data
|
|
145
|
+
*/
|
|
146
|
+
applyMergedData() {
|
|
147
|
+
var _a;
|
|
148
|
+
const edit = this.editTransaction;
|
|
149
|
+
const merged = this.mergedData;
|
|
150
|
+
// Set description (ensure it's a string)
|
|
151
|
+
if (merged.description !== undefined) {
|
|
152
|
+
edit.setDescription(merged.description);
|
|
153
|
+
}
|
|
154
|
+
// Set properties
|
|
155
|
+
if (merged.properties) {
|
|
156
|
+
edit.setProperties(merged.properties);
|
|
157
|
+
}
|
|
158
|
+
// Set URLs
|
|
159
|
+
if (merged.urls && merged.urls.length > 0) {
|
|
160
|
+
edit.setUrls(merged.urls);
|
|
161
|
+
}
|
|
162
|
+
// Set amount if changed
|
|
163
|
+
if (merged.amount) {
|
|
164
|
+
edit.setAmount(merged.amount);
|
|
165
|
+
}
|
|
166
|
+
// Set credit account if changed
|
|
167
|
+
if (merged.creditAccount) {
|
|
168
|
+
edit.setCreditAccount(merged.creditAccount);
|
|
169
|
+
}
|
|
170
|
+
// Set debit account if changed
|
|
171
|
+
if (merged.debitAccount) {
|
|
172
|
+
edit.setDebitAccount(merged.debitAccount);
|
|
173
|
+
}
|
|
174
|
+
// Add remote IDs
|
|
175
|
+
const currentRemoteIds = edit.getRemoteIds();
|
|
176
|
+
if (merged.remoteIds) {
|
|
177
|
+
merged.remoteIds.forEach((remoteId) => {
|
|
178
|
+
if (!currentRemoteIds.includes(remoteId)) {
|
|
179
|
+
edit.addRemoteId(remoteId);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// Add files
|
|
184
|
+
if (merged.files && merged.files.length > (((_a = this.editTransaction.getFiles()) === null || _a === void 0 ? void 0 : _a.length) || 0)) {
|
|
185
|
+
const currentFiles = this.editTransaction.getFiles() || [];
|
|
186
|
+
const newFiles = merged.files.slice(currentFiles.length);
|
|
187
|
+
newFiles.forEach((file) => {
|
|
188
|
+
// addFile expects File class but accepts raw bkper.File in practice
|
|
189
|
+
edit.addFile(file);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
TransactionMergeOperation.WORD_SPLITTER = /[ \-_]+/;
|
|
195
|
+
//# sourceMappingURL=merge-operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-operation.js","sourceRoot":"","sources":["../../../../src/mcp/domain/transaction/merge-operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain types for transaction merge operations
|
|
3
|
+
*
|
|
4
|
+
* These types represent the core business domain for merging transactions,
|
|
5
|
+
* independent of any specific API or protocol (MCP, REST, etc.)
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Merged transaction data that extends the base bkper.Transaction type
|
|
9
|
+
* with compatibility fields for legacy systems and test fixtures
|
|
10
|
+
*/
|
|
11
|
+
export interface MergedTransactionData extends bkper.Transaction {
|
|
12
|
+
/**
|
|
13
|
+
* Compatibility field: alias for 'files' used in test fixtures
|
|
14
|
+
*/
|
|
15
|
+
attachments?: bkper.File[];
|
|
16
|
+
/**
|
|
17
|
+
* Compatibility field: ID-only version of creditAccount for legacy systems
|
|
18
|
+
*/
|
|
19
|
+
creditAccountId?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Compatibility field: ID-only version of debitAccount for legacy systems
|
|
22
|
+
*/
|
|
23
|
+
debitAccountId?: string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=merge-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-types.d.ts","sourceRoot":"","sources":["../../../../src/mcp/domain/transaction/merge-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,WAAW;IAC5D;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-types.js","sourceRoot":"","sources":["../../../../src/mcp/domain/transaction/merge-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/lib/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAOA,OAAO,EAEL,cAAc,EAGd,eAAe,EAEhB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAOA,OAAO,EAEL,cAAc,EAGd,eAAe,EAEhB,MAAM,oCAAoC,CAAC;AAS5C,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAS;;IAmBvB,OAAO,CAAC,iBAAiB;IAgEzB,OAAO,CAAC,kBAAkB;IAqBpB,GAAG;IAYH,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC;IAczC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAc9F;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
package/lib/mcp/server.js
CHANGED
|
@@ -17,6 +17,8 @@ import { handleGetBook, getBookToolDefinition } from './tools/get_book.js';
|
|
|
17
17
|
import { handleGetBalances, getBalancesToolDefinition } from './tools/get_balances.js';
|
|
18
18
|
import { handleListTransactions, listTransactionsToolDefinition } from './tools/list_transactions.js';
|
|
19
19
|
import { handleListBooks, listBooksToolDefinition } from './tools/list_books.js';
|
|
20
|
+
import { handleCreateTransactions, createTransactionsToolDefinition } from './tools/create_transactions.js';
|
|
21
|
+
import { handleMergeTransactions, mergeTransactionsToolDefinition } from './tools/merge_transactions.js';
|
|
20
22
|
class BkperMcpServer {
|
|
21
23
|
constructor() {
|
|
22
24
|
this.server = new Server({
|
|
@@ -38,27 +40,63 @@ class BkperMcpServer {
|
|
|
38
40
|
getBookToolDefinition,
|
|
39
41
|
getBalancesToolDefinition,
|
|
40
42
|
listTransactionsToolDefinition,
|
|
43
|
+
createTransactionsToolDefinition,
|
|
44
|
+
mergeTransactionsToolDefinition,
|
|
41
45
|
],
|
|
42
46
|
};
|
|
43
47
|
}));
|
|
44
48
|
this.server.setRequestHandler(CallToolRequestSchema, (request) => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const toolName = request.params.name;
|
|
50
|
+
const toolArgs = request.params.arguments;
|
|
51
|
+
let result;
|
|
52
|
+
try {
|
|
53
|
+
switch (toolName) {
|
|
54
|
+
case 'list_books':
|
|
55
|
+
result = yield handleListBooks(toolArgs);
|
|
56
|
+
break;
|
|
57
|
+
case 'get_book':
|
|
58
|
+
result = yield handleGetBook(toolArgs);
|
|
59
|
+
break;
|
|
60
|
+
case 'get_balances':
|
|
61
|
+
result = yield handleGetBalances(toolArgs);
|
|
62
|
+
break;
|
|
63
|
+
case 'list_transactions':
|
|
64
|
+
result = yield handleListTransactions(toolArgs);
|
|
65
|
+
break;
|
|
66
|
+
case 'create_transactions':
|
|
67
|
+
result = yield handleCreateTransactions(toolArgs);
|
|
68
|
+
break;
|
|
69
|
+
case 'merge_transactions':
|
|
70
|
+
result = yield handleMergeTransactions(toolArgs);
|
|
71
|
+
break;
|
|
72
|
+
default:
|
|
73
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
// Only log actual errors, not debug info
|
|
79
|
+
if (!(error instanceof McpError)) {
|
|
80
|
+
// Convert unexpected errors to MCP errors
|
|
81
|
+
throw new McpError(ErrorCode.InternalError, `Tool ${toolName} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
56
84
|
}
|
|
57
85
|
}));
|
|
58
86
|
}
|
|
59
87
|
setupErrorHandling() {
|
|
60
88
|
this.server.onerror = (error) => {
|
|
61
|
-
|
|
89
|
+
// Log critical server errors to a file or syslog in production
|
|
90
|
+
// Avoid console output during MCP stdio mode as it contaminates the stream
|
|
91
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
92
|
+
// In development, log to stderr only if not in MCP mode
|
|
93
|
+
const isStdioMode = process.argv.includes('mcp') && process.argv.includes('start');
|
|
94
|
+
if (!isStdioMode) {
|
|
95
|
+
console.error('[MCP Server Error]:', error instanceof Error ? error.message : String(error));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// TODO: In production, implement proper logging to file/syslog
|
|
99
|
+
// Example: logger.error('MCP Server Error', { error: error.message, stack: error.stack });
|
|
62
100
|
};
|
|
63
101
|
process.on('SIGINT', () => __awaiter(this, void 0, void 0, function* () {
|
|
64
102
|
yield this.server.close();
|
|
@@ -67,9 +105,15 @@ class BkperMcpServer {
|
|
|
67
105
|
}
|
|
68
106
|
run() {
|
|
69
107
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
108
|
+
try {
|
|
109
|
+
const transport = new StdioServerTransport();
|
|
110
|
+
yield this.server.connect(transport);
|
|
111
|
+
// Server is now ready and listening on stdio
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// Do not log startup errors as they contaminate stdio stream
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
73
117
|
});
|
|
74
118
|
}
|
|
75
119
|
// Test helper methods for accessing MCP handlers directly
|
|
@@ -109,6 +153,9 @@ export { BkperMcpServer };
|
|
|
109
153
|
// Only run the server if this file is executed directly
|
|
110
154
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
111
155
|
const server = new BkperMcpServer();
|
|
112
|
-
server.run().catch(
|
|
156
|
+
server.run().catch(() => {
|
|
157
|
+
// Exit silently on error to avoid contaminating stdio stream
|
|
158
|
+
process.exit(1);
|
|
159
|
+
});
|
|
113
160
|
}
|
|
114
161
|
//# sourceMappingURL=server.js.map
|
package/lib/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EAErB,SAAS,EACT,sBAAsB,EAEtB,QAAQ,GACT,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
interface TransactionInput {
|
|
3
|
+
date: string;
|
|
4
|
+
amount: number;
|
|
5
|
+
from_account?: string;
|
|
6
|
+
to_account?: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}
|
|
9
|
+
interface CreateTransactionsParams {
|
|
10
|
+
bookId: string;
|
|
11
|
+
transactions: TransactionInput[];
|
|
12
|
+
}
|
|
13
|
+
export declare function handleCreateTransactions(params: CreateTransactionsParams): Promise<CallToolResult>;
|
|
14
|
+
export declare const createTransactionsToolDefinition: {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: string;
|
|
19
|
+
properties: {
|
|
20
|
+
bookId: {
|
|
21
|
+
type: string;
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
24
|
+
transactions: {
|
|
25
|
+
type: string;
|
|
26
|
+
items: {
|
|
27
|
+
type: string;
|
|
28
|
+
properties: {
|
|
29
|
+
date: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
amount: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
from_account: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
to_account: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
description: {
|
|
46
|
+
type: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
required: string[];
|
|
51
|
+
};
|
|
52
|
+
description: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
required: string[];
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=create_transactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_transactions.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/create_transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAIzF,UAAU,gBAAgB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,wBAAwB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,gBAAgB,EAAE,CAAC;CACpC;AAMD,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiJxG;AAED,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2C5C,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
21
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
22
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
23
|
+
import { Transaction } from 'bkper-js';
|
|
24
|
+
export function handleCreateTransactions(params) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
try {
|
|
27
|
+
// Debug logging removed to prevent stdio contamination
|
|
28
|
+
// Validate required parameters
|
|
29
|
+
if (!params.bookId) {
|
|
30
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: bookId');
|
|
31
|
+
}
|
|
32
|
+
if (!params.transactions) {
|
|
33
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: transactions');
|
|
34
|
+
}
|
|
35
|
+
if (!Array.isArray(params.transactions)) {
|
|
36
|
+
throw new McpError(ErrorCode.InvalidParams, 'Parameter transactions must be an array');
|
|
37
|
+
}
|
|
38
|
+
// Handle empty array case
|
|
39
|
+
if (params.transactions.length === 0) {
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: 'text',
|
|
44
|
+
text: JSON.stringify({ transactions: [] }, null, 2),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Validate each transaction
|
|
50
|
+
params.transactions.forEach((tx, index) => {
|
|
51
|
+
if (!tx.date || typeof tx.date !== 'string' || tx.date.trim() === '') {
|
|
52
|
+
throw new McpError(ErrorCode.InvalidParams, `Transaction at index ${index}: Missing or empty required field 'date'`);
|
|
53
|
+
}
|
|
54
|
+
if (tx.amount === undefined || tx.amount === null || typeof tx.amount !== 'number') {
|
|
55
|
+
throw new McpError(ErrorCode.InvalidParams, `Transaction at index ${index}: Missing or invalid required field 'amount'`);
|
|
56
|
+
}
|
|
57
|
+
if (!tx.description || typeof tx.description !== 'string' || tx.description.trim() === '') {
|
|
58
|
+
throw new McpError(ErrorCode.InvalidParams, `Transaction at index ${index}: Missing or empty required field 'description'`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// Get configured Bkper instance
|
|
62
|
+
const bkperInstance = getBkperInstance();
|
|
63
|
+
// Get the book
|
|
64
|
+
const book = yield bkperInstance.getBook(params.bookId);
|
|
65
|
+
if (!book) {
|
|
66
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
67
|
+
}
|
|
68
|
+
// Create Transaction objects with description built from structured data
|
|
69
|
+
const bkperTransactions = params.transactions.map((tx) => {
|
|
70
|
+
const transaction = new Transaction(book);
|
|
71
|
+
// Build description with optional accounts
|
|
72
|
+
const parts = [];
|
|
73
|
+
if (tx.from_account && tx.from_account.trim()) {
|
|
74
|
+
parts.push(tx.from_account.trim());
|
|
75
|
+
}
|
|
76
|
+
if (tx.to_account && tx.to_account.trim()) {
|
|
77
|
+
parts.push(tx.to_account.trim());
|
|
78
|
+
}
|
|
79
|
+
parts.push(tx.description);
|
|
80
|
+
const fullDescription = parts.join(' ');
|
|
81
|
+
transaction.setDate(tx.date);
|
|
82
|
+
transaction.setAmount(tx.amount);
|
|
83
|
+
transaction.setDescription(fullDescription);
|
|
84
|
+
return transaction;
|
|
85
|
+
});
|
|
86
|
+
// Batch create transactions
|
|
87
|
+
const createdTransactions = yield book.batchCreateTransactions(bkperTransactions);
|
|
88
|
+
// Clean response by removing internal fields and ensure JSON serializable
|
|
89
|
+
const transactions = createdTransactions.map((transaction) => {
|
|
90
|
+
const transactionJson = transaction.json();
|
|
91
|
+
const { agentId, agentName, agentLogo, agentLogoDark, createdAt, createdBy, updatedAt, dateValue } = transactionJson, cleanTransaction = __rest(transactionJson, ["agentId", "agentName", "agentLogo", "agentLogoDark", "createdAt", "createdBy", "updatedAt", "dateValue"]);
|
|
92
|
+
// Ensure all values are JSON serializable
|
|
93
|
+
return JSON.parse(JSON.stringify(cleanTransaction));
|
|
94
|
+
});
|
|
95
|
+
// Build response
|
|
96
|
+
const response = {
|
|
97
|
+
transactions
|
|
98
|
+
};
|
|
99
|
+
const responseText = JSON.stringify(response, null, 2);
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: 'text',
|
|
104
|
+
text: responseText,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Re-throw MCP errors as-is
|
|
111
|
+
if (error instanceof McpError) {
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
// Handle other errors
|
|
115
|
+
throw new McpError(ErrorCode.InternalError, `Failed to create transactions: ${error instanceof Error ? error.message : String(error)}`);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export const createTransactionsToolDefinition = {
|
|
120
|
+
name: 'create_transactions',
|
|
121
|
+
description: 'Create transactions in batch from structured data. Accounts are specified by name and resolved by Bkper.',
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
bookId: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
description: 'The unique identifier of the book'
|
|
128
|
+
},
|
|
129
|
+
transactions: {
|
|
130
|
+
type: 'array',
|
|
131
|
+
items: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
date: {
|
|
135
|
+
type: 'string',
|
|
136
|
+
description: 'Transaction date in ISO format (YYYY-MM-DD) or book date format'
|
|
137
|
+
},
|
|
138
|
+
amount: {
|
|
139
|
+
type: 'number',
|
|
140
|
+
description: 'Transaction amount'
|
|
141
|
+
},
|
|
142
|
+
from_account: {
|
|
143
|
+
type: 'string',
|
|
144
|
+
description: 'Origin/Credit account name'
|
|
145
|
+
},
|
|
146
|
+
to_account: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'Destination/Debit account name'
|
|
149
|
+
},
|
|
150
|
+
description: {
|
|
151
|
+
type: 'string',
|
|
152
|
+
description: 'Transaction description (can include #hashtags)'
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
required: ['date', 'amount', 'description']
|
|
156
|
+
},
|
|
157
|
+
description: 'Array of transactions to create'
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
required: ['bookId', 'transactions']
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=create_transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_transactions.js","sourceRoot":"","sources":["../../../src/mcp/tools/create_transactions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: merge_transactions
|
|
3
|
+
*
|
|
4
|
+
* Thin adapter that handles MCP protocol concerns (validation, error handling, response formatting)
|
|
5
|
+
* and delegates business logic to the domain layer.
|
|
6
|
+
*/
|
|
7
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* MCP-specific request parameters
|
|
10
|
+
*/
|
|
11
|
+
interface MergeTransactionsParams {
|
|
12
|
+
bookId: string;
|
|
13
|
+
transactionId1: string;
|
|
14
|
+
transactionId2: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function handleMergeTransactions(params: MergeTransactionsParams): Promise<CallToolResult>;
|
|
17
|
+
export declare const mergeTransactionsToolDefinition: {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: string;
|
|
22
|
+
properties: {
|
|
23
|
+
bookId: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
transactionId1: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
transactionId2: {
|
|
32
|
+
type: string;
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
required: string[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=merge_transactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge_transactions.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/merge_transactions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAKzF;;GAEG;AACH,UAAU,uBAAuB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAWD,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC,CA6GtG;AAED,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;CAqB3C,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: merge_transactions
|
|
3
|
+
*
|
|
4
|
+
* Thin adapter that handles MCP protocol concerns (validation, error handling, response formatting)
|
|
5
|
+
* and delegates business logic to the domain layer.
|
|
6
|
+
*/
|
|
7
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
17
|
+
var t = {};
|
|
18
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
19
|
+
t[p] = s[p];
|
|
20
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
21
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
22
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
23
|
+
t[p[i]] = s[p[i]];
|
|
24
|
+
}
|
|
25
|
+
return t;
|
|
26
|
+
};
|
|
27
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
28
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
29
|
+
import { TransactionMergeOperation } from '../domain/transaction/merge-operation.js';
|
|
30
|
+
export function handleMergeTransactions(params) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
try {
|
|
33
|
+
// Validate required parameters
|
|
34
|
+
if (!params.bookId) {
|
|
35
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: bookId');
|
|
36
|
+
}
|
|
37
|
+
if (!params.transactionId1) {
|
|
38
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: transactionId1');
|
|
39
|
+
}
|
|
40
|
+
if (!params.transactionId2) {
|
|
41
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: transactionId2');
|
|
42
|
+
}
|
|
43
|
+
// Get configured Bkper instance
|
|
44
|
+
const bkperInstance = getBkperInstance();
|
|
45
|
+
// Get the book
|
|
46
|
+
const book = yield bkperInstance.getBook(params.bookId);
|
|
47
|
+
if (!book) {
|
|
48
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
49
|
+
}
|
|
50
|
+
// Fetch both transactions
|
|
51
|
+
const transaction1 = yield book.getTransaction(params.transactionId1);
|
|
52
|
+
if (!transaction1) {
|
|
53
|
+
throw new McpError(ErrorCode.InvalidParams, `Transaction not found: ${params.transactionId1}`);
|
|
54
|
+
}
|
|
55
|
+
const transaction2 = yield book.getTransaction(params.transactionId2);
|
|
56
|
+
if (!transaction2) {
|
|
57
|
+
throw new McpError(ErrorCode.InvalidParams, `Transaction not found: ${params.transactionId2}`);
|
|
58
|
+
}
|
|
59
|
+
// Perform merge operation
|
|
60
|
+
const mergeOperation = new TransactionMergeOperation(book, transaction1, transaction2);
|
|
61
|
+
// Execute the merge: trash the revert transaction
|
|
62
|
+
yield mergeOperation.revertTransaction.trash();
|
|
63
|
+
// Apply merged data to edit transaction (only needed for real API, not mocks)
|
|
64
|
+
if (typeof mergeOperation.editTransaction.setDescription === 'function') {
|
|
65
|
+
mergeOperation.applyMergedData();
|
|
66
|
+
// Update the edit transaction with merged data
|
|
67
|
+
yield mergeOperation.editTransaction.update();
|
|
68
|
+
}
|
|
69
|
+
// Return the merged data
|
|
70
|
+
const _a = mergeOperation.mergedData, { agentId, agentName, agentLogo, agentLogoDark, createdAt, createdBy, updatedAt, dateValue } = _a, cleanTransaction = __rest(_a, ["agentId", "agentName", "agentLogo", "agentLogoDark", "createdAt", "createdBy", "updatedAt", "dateValue"]);
|
|
71
|
+
// Build response
|
|
72
|
+
const response = {
|
|
73
|
+
mergedTransaction: JSON.parse(JSON.stringify(cleanTransaction)),
|
|
74
|
+
revertedTransactionId: mergeOperation.revertTransaction.getId() || '',
|
|
75
|
+
auditRecord: null // Always null - we throw error if amounts differ
|
|
76
|
+
};
|
|
77
|
+
const responseText = JSON.stringify(response, null, 2);
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: responseText,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
// Re-throw MCP errors as-is
|
|
89
|
+
if (error instanceof McpError) {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
// Handle other errors
|
|
93
|
+
console.error('Merge transactions error details:', error);
|
|
94
|
+
throw new McpError(ErrorCode.InternalError, `Failed to merge transactions: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export const mergeTransactionsToolDefinition = {
|
|
99
|
+
name: 'merge_transactions',
|
|
100
|
+
description: 'Merge two duplicate or related transactions into a single consolidated transaction. Intelligently combines descriptions, attachments, amounts, and metadata while marking one transaction as reverted.',
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
bookId: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
description: 'The unique identifier of the book'
|
|
107
|
+
},
|
|
108
|
+
transactionId1: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
description: 'The ID of the first transaction to merge'
|
|
111
|
+
},
|
|
112
|
+
transactionId2: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'The ID of the second transaction to merge'
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
required: ['bookId', 'transactionId1', 'transactionId2']
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=merge_transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge_transactions.js","sourceRoot":"","sources":["../../../src/mcp/tools/merge_transactions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
"name": "bkper",
|
|
3
|
+
"version": "3.6.0",
|
|
4
|
+
"description": "Node.js command line client for Bkper",
|
|
5
|
+
"bin": {
|
|
6
|
+
"bkper": "./lib/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"repository": "https://github.com/bkper/bkper-node.git",
|
|
9
|
+
"homepage": "https://bkper.com/docs",
|
|
10
|
+
"author": "mael <mael@bkper.com>",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"private": false,
|
|
13
|
+
"main": "./lib/index.js",
|
|
14
|
+
"module": "./lib/index.js",
|
|
15
|
+
"types": "./lib/index.d.ts",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"files": [
|
|
18
|
+
"lib/**/*"
|
|
19
|
+
],
|
|
20
|
+
"mcp": {
|
|
21
|
+
"server": {
|
|
22
|
+
"command": "node",
|
|
23
|
+
"args": [
|
|
24
|
+
"lib/cli.js",
|
|
25
|
+
"mcp",
|
|
26
|
+
"start"
|
|
27
|
+
],
|
|
28
|
+
"env": {}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"clean": "rm -rf ./lib & rm -rf ./node_modules & wait",
|
|
33
|
+
"prebuild": "bun install",
|
|
34
|
+
"build": "run-s build:*",
|
|
35
|
+
"build:clean": "gts clean && rimraf temp",
|
|
36
|
+
"build:compile": "tsc",
|
|
37
|
+
"build:copy-docs": "mkdir -p lib/docs && cp -f docs/*.md lib/docs/ 2>/dev/null || true",
|
|
38
|
+
"build:copy-mcp-assets": "mkdir -p lib/mcp && cp -f src/mcp/*.md lib/mcp/ 2>/dev/null || true",
|
|
39
|
+
"predev": "bun run build",
|
|
40
|
+
"dev": "bun run build && npx concurrently \"tsc -w\" \"./scripts/dev-mcp.sh\"",
|
|
41
|
+
"mcp": "bun run build && node lib/cli.js mcp start",
|
|
42
|
+
"ports": "devpod ssh ../ -L 6274",
|
|
43
|
+
"test": "TS_NODE_PROJECT=tsconfig.test.json mocha",
|
|
44
|
+
"test:unit": "TS_NODE_PROJECT=tsconfig.test.json mocha --config .mocharc.json",
|
|
45
|
+
"test:integration": "TS_NODE_PROJECT=tsconfig.test.json mocha --config .mocharc.integration.json",
|
|
46
|
+
"test:all": "bun run test:unit && bun run test:integration",
|
|
47
|
+
"upgrade:api": "bun update @bkper/bkper-api-types --latest && bun update bkper-js --latest",
|
|
48
|
+
"patch": "yarn version --patch",
|
|
49
|
+
"minor": "yarn version --minor",
|
|
50
|
+
"major": "yarn version --major",
|
|
51
|
+
"preversion": "bun run build",
|
|
52
|
+
"postversion": "git push --tags && yarn publish --new-version $npm_package_version && git push && echo \"Successfully released version $npm_package_version!\""
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@google-cloud/local-auth": "^3.0.1",
|
|
56
|
+
"@modelcontextprotocol/sdk": "^1.13.1",
|
|
57
|
+
"bkper-js": "^2.4.0",
|
|
58
|
+
"commander": "^6.2.1",
|
|
59
|
+
"dotenv": "^8.2.0",
|
|
60
|
+
"google-auth-library": "^9.14.0",
|
|
61
|
+
"yaml": "^2.5.1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@bkper/bkper-api-types": "^5.23.0",
|
|
65
|
+
"@types/chai": "^4.3.0",
|
|
66
|
+
"@types/mocha": "^10.0.0",
|
|
67
|
+
"@types/node": "^22.5.1",
|
|
68
|
+
"chai": "^4.3.0",
|
|
69
|
+
"concurrently": "^8.2.2",
|
|
70
|
+
"gts": "^3.0.3",
|
|
71
|
+
"mocha": "^10.0.0",
|
|
72
|
+
"nodemon": "^3.0.1",
|
|
73
|
+
"npm-run-all": "^4.1.5",
|
|
74
|
+
"rimraf": "^3.0.2",
|
|
75
|
+
"ts-node": "^10.9.2",
|
|
76
|
+
"tsconfig-paths": "^4.2.0",
|
|
77
|
+
"typescript": "^5.5.4"
|
|
29
78
|
}
|
|
30
|
-
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"clean": "rm -rf ./lib & rm -rf ./node_modules & wait",
|
|
33
|
-
"prebuild": "bun install",
|
|
34
|
-
"build": "run-s build:*",
|
|
35
|
-
"build:clean": "gts clean && rimraf temp",
|
|
36
|
-
"build:compile": "tsc",
|
|
37
|
-
"build:copy-docs": "mkdir -p lib/docs && cp -f docs/*.md lib/docs/ 2>/dev/null || true",
|
|
38
|
-
"build:copy-mcp-assets": "mkdir -p lib/mcp && cp -f src/mcp/*.md lib/mcp/ 2>/dev/null || true",
|
|
39
|
-
"predev": "bun run build",
|
|
40
|
-
"dev": "bun run build && npx concurrently \"tsc -w\" \"./scripts/dev-mcp.sh\"",
|
|
41
|
-
"mcp": "bun run build && node lib/cli.js mcp start",
|
|
42
|
-
"test": "TS_NODE_PROJECT=tsconfig.test.json mocha",
|
|
43
|
-
"test:unit": "TS_NODE_PROJECT=tsconfig.test.json mocha --config .mocharc.json",
|
|
44
|
-
"test:integration": "TS_NODE_PROJECT=tsconfig.test.json mocha --config .mocharc.integration.json",
|
|
45
|
-
"test:all": "bun run test:unit && bun run test:integration",
|
|
46
|
-
"upgrade:api": "bun update @bkper/bkper-api-types --latest && bun update bkper-js --latest",
|
|
47
|
-
"patch": "yarn version --patch",
|
|
48
|
-
"minor": "yarn version --minor",
|
|
49
|
-
"major": "yarn version --major",
|
|
50
|
-
"preversion": "bun run build",
|
|
51
|
-
"postversion": "git push --tags && yarn publish --new-version $npm_package_version && git push && echo \"Successfully released version $npm_package_version!\""
|
|
52
|
-
},
|
|
53
|
-
"dependencies": {
|
|
54
|
-
"@google-cloud/local-auth": "^3.0.1",
|
|
55
|
-
"@modelcontextprotocol/sdk": "^1.13.1",
|
|
56
|
-
"bkper-js": "^2.4.0",
|
|
57
|
-
"commander": "^6.2.1",
|
|
58
|
-
"dotenv": "^8.2.0",
|
|
59
|
-
"google-auth-library": "^9.14.0",
|
|
60
|
-
"yaml": "^2.5.1"
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@bkper/bkper-api-types": "^5.23.0",
|
|
64
|
-
"@types/chai": "^4.3.0",
|
|
65
|
-
"@types/commander": "^2.12.2",
|
|
66
|
-
"@types/mocha": "^10.0.0",
|
|
67
|
-
"@types/node": "^22.5.1",
|
|
68
|
-
"chai": "^4.3.0",
|
|
69
|
-
"concurrently": "^8.2.2",
|
|
70
|
-
"gts": "^3.0.3",
|
|
71
|
-
"mocha": "^10.0.0",
|
|
72
|
-
"nodemon": "^3.0.1",
|
|
73
|
-
"npm-run-all": "^4.1.5",
|
|
74
|
-
"rimraf": "^3.0.2",
|
|
75
|
-
"ts-node": "^10.9.2",
|
|
76
|
-
"tsconfig-paths": "^4.2.0",
|
|
77
|
-
"typescript": "^5.5.4"
|
|
78
|
-
}
|
|
79
79
|
}
|