bkper 3.3.3 → 3.5.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/CHANGELOG.md +16 -0
- package/README.md +81 -8
- package/lib/cli.js +20 -6
- package/lib/cli.js.map +1 -1
- package/lib/mcp/bkper-factory.d.ts +10 -0
- package/lib/mcp/bkper-factory.d.ts.map +1 -0
- package/lib/mcp/bkper-factory.js +40 -0
- package/lib/mcp/bkper-factory.js.map +1 -0
- package/lib/mcp/server.d.ts +13 -0
- package/lib/mcp/server.d.ts.map +1 -0
- package/lib/mcp/server.js +114 -0
- package/lib/mcp/server.js.map +1 -0
- package/lib/mcp/system-prompt.md +192 -0
- package/lib/mcp/tools/get_balances.d.ts +26 -0
- package/lib/mcp/tools/get_balances.d.ts.map +1 -0
- package/lib/mcp/tools/get_balances.js +106 -0
- package/lib/mcp/tools/get_balances.js.map +1 -0
- package/lib/mcp/tools/get_book.d.ts +21 -0
- package/lib/mcp/tools/get_book.d.ts.map +1 -0
- package/lib/mcp/tools/get_book.js +126 -0
- package/lib/mcp/tools/get_book.js.map +1 -0
- package/lib/mcp/tools/list_books.d.ts +21 -0
- package/lib/mcp/tools/list_books.d.ts.map +1 -0
- package/lib/mcp/tools/list_books.js +67 -0
- package/lib/mcp/tools/list_books.js.map +1 -0
- package/lib/mcp/tools/list_transactions.d.ts +38 -0
- package/lib/mcp/tools/list_transactions.d.ts.map +1 -0
- package/lib/mcp/tools/list_transactions.js +95 -0
- package/lib/mcp/tools/list_transactions.js.map +1 -0
- package/package.json +32 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2025
|
|
4
|
+
|
|
5
|
+
### **July 2025**
|
|
6
|
+
|
|
7
|
+
**MCP Server**
|
|
8
|
+
- Added support for AI assistants to analyze your books with monthly and year-to-date balances
|
|
9
|
+
- Improved date filtering with more intuitive `before:` operator
|
|
10
|
+
- Added setup instructions for Claude Desktop and other AI tools
|
|
11
|
+
|
|
12
|
+
### **June 2025**
|
|
13
|
+
|
|
14
|
+
**bkper-node CLI**
|
|
15
|
+
- Introduced MCP server - connect AI assistants to your Bkper books with `bkper mcp start`
|
|
16
|
+
- Added book name filtering to quickly find specific books
|
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ yarn global add bkper
|
|
|
34
34
|
- ```logout``` - Logs out the user by deleting client credentials.
|
|
35
35
|
- ```app -c``` - Create a new App based on ```./bkperapp.yaml``` file.
|
|
36
36
|
- ```app -u``` - Update an existing App based on ```./bkperapp.yaml``` file.
|
|
37
|
+
- ```mcp start``` - Start the Bkper MCP (Model Context Protocol) server.
|
|
37
38
|
|
|
38
39
|
### Examples
|
|
39
40
|
```
|
|
@@ -76,9 +77,13 @@ id: my-custom-app
|
|
|
76
77
|
# The readable name of the App or Bot.
|
|
77
78
|
name: My Custom App
|
|
78
79
|
|
|
79
|
-
#
|
|
80
|
+
# The logo url from public host. Best fit 200x200 px. Use https://
|
|
80
81
|
logoUrl: https://static.thenounproject.com/png/2318500-200.png
|
|
81
82
|
|
|
83
|
+
# The logo url to be used when in dark mode
|
|
84
|
+
logoUrlDark: https://static.thenounproject.com/png/2318500-200.png
|
|
85
|
+
|
|
86
|
+
|
|
82
87
|
|
|
83
88
|
# CONTEXT MENU CONFIGURATION
|
|
84
89
|
|
|
@@ -95,15 +100,17 @@ menuPopupWidth: 500 # width in pixels. Default to 80% of screen width.
|
|
|
95
100
|
menuPopupHeight: 300 # height in pixels. Default to 90% of screen height.
|
|
96
101
|
|
|
97
102
|
|
|
98
|
-
#
|
|
103
|
+
#ASSISTANT CONFIGURATION
|
|
104
|
+
|
|
105
|
+
# The conversation url to be called by Bkper when a new conversation message is added
|
|
106
|
+
conversationUrl: https://us-central1-bkper-tax-trigger.cloudfunctions.net/chat
|
|
99
107
|
|
|
100
|
-
# The production webhook url to be called by Bkper when an event occurs.
|
|
101
|
-
webhookUrl: https://us-central1-bkper-tax-trigger.cloudfunctions.net/prod
|
|
102
108
|
|
|
103
|
-
|
|
104
|
-
#
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
|
|
110
|
+
# BOT EVENTS CONFIGURATION
|
|
111
|
+
|
|
112
|
+
# The webhook url to be called by Bkper when an event occurs.
|
|
113
|
+
webhookUrl: https://us-central1-bkper-tax-trigger.cloudfunctions.net/events
|
|
107
114
|
|
|
108
115
|
# The events the Bot is capable of processing by the webhook.
|
|
109
116
|
# This is optional and, if not specified, no events will be processed.
|
|
@@ -195,6 +202,72 @@ Bkper.setConfig({
|
|
|
195
202
|
})
|
|
196
203
|
```
|
|
197
204
|
|
|
205
|
+
### MCP (Model Context Protocol) Server
|
|
206
|
+
|
|
207
|
+
Bkper includes an MCP server that allows AI assistants and other tools to interact with your Bkper books through the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
208
|
+
|
|
209
|
+
#### Starting the MCP Server
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
bkper mcp start
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The server runs on stdio and provides the following tools:
|
|
216
|
+
|
|
217
|
+
- **list_books** - List all books accessible by the authenticated user
|
|
218
|
+
- **get_book** - Get details of a specific book by ID
|
|
219
|
+
- **get_balances** - Get account balances for a specific date or period
|
|
220
|
+
- **list_transactions** - List transactions with filtering options
|
|
221
|
+
|
|
222
|
+
#### Prerequisites
|
|
223
|
+
|
|
224
|
+
Before using the MCP server:
|
|
225
|
+
1. Login using `bkper login` to set up authentication
|
|
226
|
+
2. Ensure the `BKPER_API_KEY` environment variable is set
|
|
227
|
+
|
|
228
|
+
The MCP server uses the same authentication as the CLI, reading credentials from `~/.bkper-credentials.json`.
|
|
229
|
+
|
|
230
|
+
#### Integration Examples
|
|
231
|
+
|
|
232
|
+
##### Claude Desktop
|
|
233
|
+
|
|
234
|
+
Add to your configuration file:
|
|
235
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
236
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"mcpServers": {
|
|
241
|
+
"bkper": {
|
|
242
|
+
"command": "npx",
|
|
243
|
+
"args": ["bkper", "mcp", "start"],
|
|
244
|
+
"env": {
|
|
245
|
+
"BKPER_API_KEY": "your-api-key-here"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
##### Other MCP Clients
|
|
253
|
+
|
|
254
|
+
For other MCP-compatible clients, configure them to run:
|
|
255
|
+
```bash
|
|
256
|
+
BKPER_API_KEY=your-api-key npx bkper mcp start
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The server communicates via stdio, so any MCP client that supports stdio transport can connect to it.
|
|
260
|
+
|
|
261
|
+
#### Available MCP Tools
|
|
262
|
+
|
|
263
|
+
Once connected, the MCP client can:
|
|
264
|
+
- List your Bkper books
|
|
265
|
+
- Get account balances for any date or period
|
|
266
|
+
- Search and filter transactions
|
|
267
|
+
- Analyze your financial data
|
|
268
|
+
|
|
269
|
+
For more information about the Model Context Protocol, visit [modelcontextprotocol.io](https://modelcontextprotocol.io).
|
|
270
|
+
|
|
198
271
|
|
|
199
272
|
|
|
200
273
|
## Documentation
|
package/lib/cli.js
CHANGED
|
@@ -8,12 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
import { App
|
|
11
|
+
import { App } from 'bkper-js';
|
|
12
12
|
import program from 'commander';
|
|
13
13
|
import fs from 'fs';
|
|
14
14
|
import * as YAML from 'yaml';
|
|
15
|
-
import {
|
|
15
|
+
import { login, logout } from './auth/local-auth-service.js';
|
|
16
16
|
import dotenv from 'dotenv';
|
|
17
|
+
import { setupBkper } from './mcp/bkper-factory.js';
|
|
17
18
|
dotenv.config();
|
|
18
19
|
program
|
|
19
20
|
.command('login')
|
|
@@ -34,10 +35,7 @@ program
|
|
|
34
35
|
.option('-c, --create', 'Create a new App')
|
|
35
36
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
37
|
try {
|
|
37
|
-
|
|
38
|
-
apiKeyProvider: () => __awaiter(void 0, void 0, void 0, function* () { return process.env.BKPER_API_KEY || ''; }),
|
|
39
|
-
oauthTokenProvider: () => getOAuthToken()
|
|
40
|
-
});
|
|
38
|
+
setupBkper();
|
|
41
39
|
let json;
|
|
42
40
|
if (fs.existsSync('./bkperapp.json')) {
|
|
43
41
|
json = JSON.parse(fs.readFileSync('./bkperapp.json', 'utf8'));
|
|
@@ -66,5 +64,21 @@ program
|
|
|
66
64
|
console.log(err);
|
|
67
65
|
}
|
|
68
66
|
}));
|
|
67
|
+
const mcpCommand = program.command('mcp').description('Bkper MCP server commands');
|
|
68
|
+
mcpCommand
|
|
69
|
+
.command('start')
|
|
70
|
+
.description('Start Bkper MCP server')
|
|
71
|
+
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
try {
|
|
73
|
+
// Import and start the MCP server directly
|
|
74
|
+
const { BkperMcpServer } = yield import('./mcp/server.js');
|
|
75
|
+
const server = new BkperMcpServer();
|
|
76
|
+
yield server.run();
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error('Error starting MCP server:', err);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}));
|
|
69
83
|
program.parse(process.argv);
|
|
70
84
|
//# sourceMappingURL=cli.js.map
|
package/lib/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,OAAO,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Bkper } from 'bkper-js';
|
|
2
|
+
/**
|
|
3
|
+
* Get a configured Bkper instance with authentication setup.
|
|
4
|
+
* Uses singleton pattern to avoid repeated configuration.
|
|
5
|
+
*
|
|
6
|
+
* @returns Configured Bkper instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function getBkperInstance(): Bkper;
|
|
9
|
+
export declare function setupBkper(): void;
|
|
10
|
+
//# sourceMappingURL=bkper-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bkper-factory.d.ts","sourceRoot":"","sources":["../../src/mcp/bkper-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,KAAK,CAiBxC;AAED,wBAAgB,UAAU,SAKzB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
import { Bkper } from 'bkper-js';
|
|
11
|
+
import { getOAuthToken } from '../auth/local-auth-service.js';
|
|
12
|
+
let configuredBkperInstance = undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Get a configured Bkper instance with authentication setup.
|
|
15
|
+
* Uses singleton pattern to avoid repeated configuration.
|
|
16
|
+
*
|
|
17
|
+
* @returns Configured Bkper instance
|
|
18
|
+
*/
|
|
19
|
+
export function getBkperInstance() {
|
|
20
|
+
// Return mock instance if in test environment
|
|
21
|
+
if (process.env.NODE_ENV === 'test' || globalThis.__mockBkper) {
|
|
22
|
+
return globalThis.__mockBkper || Bkper;
|
|
23
|
+
}
|
|
24
|
+
// Return cached instance if already configured
|
|
25
|
+
if (configuredBkperInstance) {
|
|
26
|
+
return configuredBkperInstance;
|
|
27
|
+
}
|
|
28
|
+
// Configure Bkper with authentication
|
|
29
|
+
setupBkper();
|
|
30
|
+
// Cache the configured instance
|
|
31
|
+
configuredBkperInstance = new Bkper();
|
|
32
|
+
return configuredBkperInstance;
|
|
33
|
+
}
|
|
34
|
+
export function setupBkper() {
|
|
35
|
+
Bkper.setConfig({
|
|
36
|
+
apiKeyProvider: () => __awaiter(this, void 0, void 0, function* () { return process.env.BKPER_API_KEY || ''; }),
|
|
37
|
+
oauthTokenProvider: () => getOAuthToken()
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=bkper-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bkper-factory.js","sourceRoot":"","sources":["../../src/mcp/bkper-factory.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,IAAI,uBAAuB,GAAsB,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC9B,8CAA8C;IAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAK,UAAkB,CAAC,WAAW,EAAE,CAAC;QACvE,OAAQ,UAAkB,CAAC,WAAW,IAAI,KAAK,CAAC;IAClD,CAAC;IAED,+CAA+C;IAC/C,IAAI,uBAAuB,EAAE,CAAC;QAC5B,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,sCAAsC;IACtC,UAAU,EAAE,CAAC;IACb,gCAAgC;IAChC,uBAAuB,GAAG,IAAI,KAAK,EAAE,CAAC;IAEtC,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,KAAK,CAAC,SAAS,CAAC;QACd,cAAc,EAAE,GAAS,EAAE,gDAAC,OAAA,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAA,GAAA;QAC3D,kBAAkB,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KAC1C,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { CallToolResult, ListToolsResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
declare class BkperMcpServer {
|
|
4
|
+
private server;
|
|
5
|
+
constructor();
|
|
6
|
+
private setupToolHandlers;
|
|
7
|
+
private setupErrorHandling;
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
testListTools(): Promise<ListToolsResult>;
|
|
10
|
+
testCallTool(name: string, args?: Record<string, unknown>): Promise<CallToolResult>;
|
|
11
|
+
}
|
|
12
|
+
export { BkperMcpServer };
|
|
13
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +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;AAO5C,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAS;;IAmBvB,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,kBAAkB;IAWpB,GAAG;IAOH,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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
import dotenv from 'dotenv';
|
|
12
|
+
dotenv.config();
|
|
13
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
14
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
15
|
+
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
16
|
+
import { handleGetBook, getBookToolDefinition } from './tools/get_book.js';
|
|
17
|
+
import { handleGetBalances, getBalancesToolDefinition } from './tools/get_balances.js';
|
|
18
|
+
import { handleListTransactions, listTransactionsToolDefinition } from './tools/list_transactions.js';
|
|
19
|
+
import { handleListBooks, listBooksToolDefinition } from './tools/list_books.js';
|
|
20
|
+
class BkperMcpServer {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.server = new Server({
|
|
23
|
+
name: 'bkper-mcp-server',
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
}, {
|
|
26
|
+
capabilities: {
|
|
27
|
+
tools: {}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
this.setupToolHandlers();
|
|
31
|
+
this.setupErrorHandling();
|
|
32
|
+
}
|
|
33
|
+
setupToolHandlers() {
|
|
34
|
+
this.server.setRequestHandler(ListToolsRequestSchema, () => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
return {
|
|
36
|
+
tools: [
|
|
37
|
+
listBooksToolDefinition,
|
|
38
|
+
getBookToolDefinition,
|
|
39
|
+
getBalancesToolDefinition,
|
|
40
|
+
listTransactionsToolDefinition,
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}));
|
|
44
|
+
this.server.setRequestHandler(CallToolRequestSchema, (request) => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
switch (request.params.name) {
|
|
46
|
+
case 'list_books':
|
|
47
|
+
return yield handleListBooks(request.params.arguments);
|
|
48
|
+
case 'get_book':
|
|
49
|
+
return yield handleGetBook(request.params.arguments);
|
|
50
|
+
case 'get_balances':
|
|
51
|
+
return yield handleGetBalances(request.params.arguments);
|
|
52
|
+
case 'list_transactions':
|
|
53
|
+
return yield handleListTransactions(request.params.arguments);
|
|
54
|
+
default:
|
|
55
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
setupErrorHandling() {
|
|
60
|
+
this.server.onerror = (error) => {
|
|
61
|
+
console.error('[MCP Error]', error);
|
|
62
|
+
};
|
|
63
|
+
process.on('SIGINT', () => __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
yield this.server.close();
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
run() {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
const transport = new StdioServerTransport();
|
|
71
|
+
yield this.server.connect(transport);
|
|
72
|
+
console.error('Bkper MCP server running on stdio');
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Test helper methods for accessing MCP handlers directly
|
|
76
|
+
testListTools() {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
// Call the list tools handler directly for testing
|
|
79
|
+
const requestHandlers = this.server._requestHandlers;
|
|
80
|
+
const handler = requestHandlers.get('tools/list');
|
|
81
|
+
if (!handler)
|
|
82
|
+
throw new Error('ListTools handler not found');
|
|
83
|
+
// Create proper MCP request format
|
|
84
|
+
const request = {
|
|
85
|
+
method: 'tools/list',
|
|
86
|
+
params: {}
|
|
87
|
+
};
|
|
88
|
+
return yield handler(request);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
testCallTool(name_1) {
|
|
92
|
+
return __awaiter(this, arguments, void 0, function* (name, args = {}) {
|
|
93
|
+
// Call the call tool handler directly for testing
|
|
94
|
+
const requestHandlers = this.server._requestHandlers;
|
|
95
|
+
const handler = requestHandlers.get('tools/call');
|
|
96
|
+
if (!handler)
|
|
97
|
+
throw new Error('CallTool handler not found');
|
|
98
|
+
// Create proper MCP request format
|
|
99
|
+
const request = {
|
|
100
|
+
method: 'tools/call',
|
|
101
|
+
params: { name, arguments: args }
|
|
102
|
+
};
|
|
103
|
+
return yield handler(request);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Export the class for testing
|
|
108
|
+
export { BkperMcpServer };
|
|
109
|
+
// Only run the server if this file is executed directly
|
|
110
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
111
|
+
const server = new BkperMcpServer();
|
|
112
|
+
server.run().catch(console.error);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Bkper MCP Usage Guide
|
|
2
|
+
|
|
3
|
+
## Essential Tools
|
|
4
|
+
|
|
5
|
+
### Discovery
|
|
6
|
+
- `list_books()` - Find available books
|
|
7
|
+
- `get_book({ bookId })` - Book details, structure, and group hierarchies
|
|
8
|
+
|
|
9
|
+
### Analysis
|
|
10
|
+
- `get_balances({ bookId, query })` - **THE** tool for all balance analysis
|
|
11
|
+
- `list_transactions({ bookId, query })` - Transaction inspection only (never for balance calculations)
|
|
12
|
+
|
|
13
|
+
## Core Rules
|
|
14
|
+
|
|
15
|
+
### 1. Root Group Discovery
|
|
16
|
+
**Always discover and use root groups dynamically based on account group types:**
|
|
17
|
+
1. Call `get_book({ bookId })` to see the hierarchy
|
|
18
|
+
2. Look for the top-level group that contains:
|
|
19
|
+
- **For Balance Sheet**: Both ASSET and LIABILITY account types
|
|
20
|
+
- **For P&L**: Both INCOMING and OUTGOING account types
|
|
21
|
+
3. Use that group name (not its children) in your queries
|
|
22
|
+
|
|
23
|
+
**Example**: If you see this structure:
|
|
24
|
+
```
|
|
25
|
+
"Total Equity" (root)
|
|
26
|
+
├── "Assets" (type: ASSET)
|
|
27
|
+
├── "Liabilities" (type: LIABILITY)
|
|
28
|
+
```
|
|
29
|
+
Then use `group:'Total Equity'` - NOT `group:'Assets'` or `group:'Liabilities'`
|
|
30
|
+
|
|
31
|
+
### 2. Date Filter Matching
|
|
32
|
+
|
|
33
|
+
- **Permanent accounts** (ASSET, LIABILITY): Use `before:` dates for point-in-time
|
|
34
|
+
- **Non-permanent accounts** (INCOMING, OUTGOING): Use `after:` and `before:` for periods
|
|
35
|
+
|
|
36
|
+
- **IMPORTANT:** `after:` is inclusive and `before:` is exclusive, so, for example, to filter the whole 2024 year, the range might be `after:2024-01-01 before:2025-01-01`
|
|
37
|
+
|
|
38
|
+
### 3. Correct Tool Selection
|
|
39
|
+
- **Balance analysis**: Always use `get_balances`
|
|
40
|
+
- **Transaction inspection**: Use `list_transactions` (never for calculations)
|
|
41
|
+
|
|
42
|
+
### 4. Balance Analysis Query Requirements (MANDATORY)
|
|
43
|
+
- **MUST include either `group:` or `account:` operator in EVERY query**
|
|
44
|
+
- Never query subgroups directly (Assets, Liabilities, Revenue, Expenses) - use root groups
|
|
45
|
+
- When using `account:`, be specific about individual accounts
|
|
46
|
+
- Always include appropriate date filters
|
|
47
|
+
- Balance analysis queries without group/account operators will be rejected with an error
|
|
48
|
+
- Transaction queries can be without group/account operators
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Balance Sheet Analysis
|
|
53
|
+
```javascript
|
|
54
|
+
// After discovering root group for ASSET + LIABILITY accounts
|
|
55
|
+
get_balances({
|
|
56
|
+
bookId: "book-123",
|
|
57
|
+
query: "group:'Total Equity' before:$m"
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### P&L Analysis
|
|
62
|
+
```javascript
|
|
63
|
+
// After discovering root group for INCOMING + OUTGOING accounts
|
|
64
|
+
get_balances({
|
|
65
|
+
bookId: "book-123",
|
|
66
|
+
query: "group:'Profit & Loss' after:$m-12 before:$m"
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Complete Financial Statements
|
|
71
|
+
```javascript
|
|
72
|
+
// After discovering both root groups
|
|
73
|
+
const balanceSheet = await get_balances({
|
|
74
|
+
bookId: "book-123",
|
|
75
|
+
query: "group:'Total Equity' before:$m+1"
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const pnl = await get_balances({
|
|
79
|
+
bookId: "book-123",
|
|
80
|
+
query: "group:'Profit & Loss' after:$m-1 before:$m"
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Transaction Inspection
|
|
85
|
+
```javascript
|
|
86
|
+
// Recent transactions (inspection only)
|
|
87
|
+
list_transactions({
|
|
88
|
+
bookId: "book-123",
|
|
89
|
+
query: "after:$d-30"
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// Large transactions
|
|
93
|
+
list_transactions({
|
|
94
|
+
bookId: "book-123",
|
|
95
|
+
query: "amount>1000 after:$m-1 before:$m"
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Account Structure Reference
|
|
100
|
+
|
|
101
|
+
### Account Types
|
|
102
|
+
| Type | Nature | Examples |
|
|
103
|
+
|------|--------|----------|
|
|
104
|
+
| **ASSET** | Permanent | Cash, Accounts Receivable |
|
|
105
|
+
| **LIABILITY** | Permanent | Accounts Payable, Loans |
|
|
106
|
+
| **INCOMING** | Non-permanent | Sales, Interest Income |
|
|
107
|
+
| **OUTGOING** | Non-permanent | Rent, Utilities |
|
|
108
|
+
|
|
109
|
+
### Example Group Hierarchies
|
|
110
|
+
|
|
111
|
+
**Example 1: Permanent Accounts (Balance Sheet Analysis)**
|
|
112
|
+
```
|
|
113
|
+
"Total Equity"
|
|
114
|
+
├── Assets
|
|
115
|
+
│ ├── Current Assets
|
|
116
|
+
│ └── Fixed Assets
|
|
117
|
+
└── Liabilities
|
|
118
|
+
├── Current Liabilities
|
|
119
|
+
└── Long-term Liabilities
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Example 2: Non-Permanent Accounts (Profit & Loss Analysis)**
|
|
123
|
+
```
|
|
124
|
+
"Profit & Loss"
|
|
125
|
+
├── Revenue
|
|
126
|
+
│ ├── Product Sales
|
|
127
|
+
│ └── Service Revenue
|
|
128
|
+
└── Expenses
|
|
129
|
+
├── Operating Expenses
|
|
130
|
+
└── Administrative Expenses
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Note**: Root group names vary by book. Always discover the actual names using `get_book()` which includes group hierarchies.
|
|
134
|
+
|
|
135
|
+
## Quick Reference
|
|
136
|
+
|
|
137
|
+
### Date Variables
|
|
138
|
+
- `$d` - Today
|
|
139
|
+
- `$m` - Current month end
|
|
140
|
+
- `$y` - Current year end
|
|
141
|
+
- `$d-N` - N days ago
|
|
142
|
+
- `$m-N` - N months ago
|
|
143
|
+
|
|
144
|
+
### Query Patterns
|
|
145
|
+
```
|
|
146
|
+
group:'[ROOT_GROUP_NAME]' before:$m // Balance sheet (permanent accounts)
|
|
147
|
+
group:'[ROOT_GROUP_NAME]' after:$m-1 before:$m // P&L (non-permanent accounts)
|
|
148
|
+
after:2024-01-01 before:2025-01-01 // Date range
|
|
149
|
+
amount>1000 // Amount filter (transactions only)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Analysis Workflow
|
|
153
|
+
1. **Discover**: `list_books()` → `get_book()` (includes groups)
|
|
154
|
+
2. **Identify Root Groups**: Find groups containing the group types you need
|
|
155
|
+
3. **Analyze**: `get_balances()` with discovered root groups
|
|
156
|
+
4. **Inspect**: `list_transactions()` for transaction details
|
|
157
|
+
|
|
158
|
+
## Reports and Insights Formatting
|
|
159
|
+
|
|
160
|
+
### Markdown Output Preference
|
|
161
|
+
When generating financial insights, reports, or analysis, **strongly prefer well-structured Markdown** for better readability across platforms (cloud, desktop, mobile). Use tables for financial data, clear headers for sections, bold formatting for totals and key metrics, and icons to enhance visual appeal.
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## Common Mistakes to Avoid
|
|
165
|
+
|
|
166
|
+
❌ **Wrong**: `get_balances({ query: "before:$m" })` - Missing group/account operator!
|
|
167
|
+
✅ **Right**: `get_balances({ query: "group:'[ROOT_GROUP]' before:$m" })`
|
|
168
|
+
|
|
169
|
+
❌ **Wrong**: `get_balances({ query: "after:2024-01-01" })` - Missing group/account operator!
|
|
170
|
+
✅ **Right**: `get_balances({ query: "group:'[ROOT_GROUP]' after:2024-01-01 before:2025-01-01" })`
|
|
171
|
+
|
|
172
|
+
❌ **Wrong**: `get_balances({ query: "group:'Assets'" })` - Using subgroup instead of root group
|
|
173
|
+
✅ **Right**: `get_balances({ query: "group:'[ROOT_GROUP_WITH_ASSETS]' before:$m" })`
|
|
174
|
+
|
|
175
|
+
❌ **Wrong**: Query without any filtering
|
|
176
|
+
✅ **Right**: Always include `group:` or `account:` operator for focused analysis
|
|
177
|
+
|
|
178
|
+
❌ **Wrong**: Using `list_transactions` for balance calculations
|
|
179
|
+
✅ **Right**: Use `get_balances` for all balance analysis
|
|
180
|
+
|
|
181
|
+
❌ **Wrong**: Using `before:` without `after:` dates with non-permanent accounts
|
|
182
|
+
✅ **Right**: Use `after:` and `before:` with INCOMING/OUTGOING accounts
|
|
183
|
+
|
|
184
|
+
❌ **Wrong**: Using different date variables on same query. E.g.`after:$y-1` and `before:$d`
|
|
185
|
+
✅ **Right**: Use same date variables on same query. E.g. `after:$y-1` and `before:$y`
|
|
186
|
+
|
|
187
|
+
❌ **Wrong**: Assuming fixed root group names
|
|
188
|
+
✅ **Right**: Always discover root groups using `get_book()` then navigate its `groups` property
|
|
189
|
+
|
|
190
|
+
## CRITICAL REQUIREMENT
|
|
191
|
+
|
|
192
|
+
**⚠️ ALL get_balances queries MUST include either `group:` or `account:` operator.**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
interface GetBalancesParams {
|
|
3
|
+
bookId: string;
|
|
4
|
+
query: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function handleGetBalances(params: GetBalancesParams): Promise<CallToolResult>;
|
|
7
|
+
export declare const getBalancesToolDefinition: {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: string;
|
|
12
|
+
properties: {
|
|
13
|
+
bookId: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
query: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
required: string[];
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=get_balances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_balances.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/get_balances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAIzF,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AASD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAoG1F;AAED,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;CAiBrC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
12
|
+
import { BalanceType } from 'bkper-js';
|
|
13
|
+
export function handleGetBalances(params) {
|
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
try {
|
|
16
|
+
// Validate required parameters
|
|
17
|
+
if (!params.bookId) {
|
|
18
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: bookId');
|
|
19
|
+
}
|
|
20
|
+
if (!params.query) {
|
|
21
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: query');
|
|
22
|
+
}
|
|
23
|
+
// Validate query contains either group: or account: operator
|
|
24
|
+
if (!params.query.includes('group:') && !params.query.includes('account:')) {
|
|
25
|
+
throw new McpError(ErrorCode.InvalidParams, 'Query must include either \'group:\' or \'account:\' operator for proper balance filtering. Example: "group:\'Assets\' before:$m" or "account:\'Cash\' before:$m"');
|
|
26
|
+
}
|
|
27
|
+
// Get configured Bkper instance
|
|
28
|
+
const bkper = getBkperInstance();
|
|
29
|
+
// Get the book first
|
|
30
|
+
const book = yield bkper.getBook(params.bookId, true);
|
|
31
|
+
if (!book) {
|
|
32
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
33
|
+
}
|
|
34
|
+
// Get balances from the book with query (required by bkper-js)
|
|
35
|
+
let actualQuery = params.query;
|
|
36
|
+
// Enforce monthly periodicity by modifying query
|
|
37
|
+
if (actualQuery.includes('by:d')) {
|
|
38
|
+
// Replace daily periodicity with monthly
|
|
39
|
+
actualQuery = actualQuery.replace(/by:d/g, 'by:m');
|
|
40
|
+
}
|
|
41
|
+
else if (actualQuery.includes('by:y')) {
|
|
42
|
+
// Replace yearly periodicity with monthly
|
|
43
|
+
actualQuery = actualQuery.replace(/by:y/g, 'by:m');
|
|
44
|
+
}
|
|
45
|
+
else if (!actualQuery.includes('by:')) {
|
|
46
|
+
// Append monthly periodicity if no by: operator present
|
|
47
|
+
actualQuery = actualQuery + ' by:m';
|
|
48
|
+
}
|
|
49
|
+
// If by:m is already present, keep it unchanged
|
|
50
|
+
// Get the first container to access createDataTable
|
|
51
|
+
const balancesReport = yield book.getBalancesReport(actualQuery);
|
|
52
|
+
// Determine balance type based on presence of after: operator
|
|
53
|
+
const type = actualQuery.includes('after:') ? BalanceType.PERIOD : BalanceType.CUMULATIVE;
|
|
54
|
+
// Use BalancesDataTableBuilder to generate matrix
|
|
55
|
+
let matrix;
|
|
56
|
+
// Get the first container to access createDataTable
|
|
57
|
+
const dataTableBuilder = balancesReport.createDataTable()
|
|
58
|
+
.formatValues(false) // Raw numbers for LLMs
|
|
59
|
+
.formatDates(true) // YYYY-MM-DD dates
|
|
60
|
+
.raw(true) // Raw balances
|
|
61
|
+
.expanded(4)
|
|
62
|
+
.type(type); //
|
|
63
|
+
matrix = dataTableBuilder.build();
|
|
64
|
+
// Build response with matrix format
|
|
65
|
+
const response = {
|
|
66
|
+
matrix,
|
|
67
|
+
query: actualQuery
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: JSON.stringify(response, null, 2),
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Re-throw MCP errors as-is
|
|
80
|
+
if (error instanceof McpError) {
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
// Handle other errors
|
|
84
|
+
throw new McpError(ErrorCode.InternalError, `Failed to get balances: ${error instanceof Error ? error.message : String(error)}`);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export const getBalancesToolDefinition = {
|
|
89
|
+
name: 'get_balances',
|
|
90
|
+
description: 'Get account balances with query filtering. Use get_book first to understand group hierarchy and usage rules.',
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
bookId: {
|
|
95
|
+
type: 'string',
|
|
96
|
+
description: 'The unique identifier of the book'
|
|
97
|
+
},
|
|
98
|
+
query: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
description: 'Required query to filter balances (e.g., "account:\'Cash\'", "group:\'Assets\'", "before:2024-01-31")'
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
required: ['bookId', 'query']
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=get_balances.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_balances.js","sourceRoot":"","sources":["../../../src/mcp/tools/get_balances.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
interface GetBookParams {
|
|
3
|
+
bookId: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function handleGetBook(params: GetBookParams): Promise<CallToolResult>;
|
|
6
|
+
export declare const getBookToolDefinition: {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: string;
|
|
11
|
+
properties: {
|
|
12
|
+
bookId: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
required: string[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=get_book.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_book.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/get_book.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAOzF,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAkED,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAqElF;AAED,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;CAajC,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
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
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
import { join, dirname } from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
function buildHierarchicalStructure(groups) {
|
|
16
|
+
const groupMap = new Map();
|
|
17
|
+
const rootGroups = [];
|
|
18
|
+
// First pass: create all group nodes
|
|
19
|
+
groups.forEach(group => {
|
|
20
|
+
const node = {
|
|
21
|
+
id: group.getId() || '',
|
|
22
|
+
name: group.getName() || '',
|
|
23
|
+
type: group.getType() || '',
|
|
24
|
+
hidden: group.isHidden() || false,
|
|
25
|
+
permanent: group.isPermanent() || false,
|
|
26
|
+
properties: group.getProperties() || {},
|
|
27
|
+
children: []
|
|
28
|
+
};
|
|
29
|
+
groupMap.set(node.id, node);
|
|
30
|
+
});
|
|
31
|
+
// Second pass: build hierarchy
|
|
32
|
+
groups.forEach(group => {
|
|
33
|
+
const node = groupMap.get(group.getId() || '');
|
|
34
|
+
if (!node)
|
|
35
|
+
return;
|
|
36
|
+
const parent = group.getParent();
|
|
37
|
+
if (parent) {
|
|
38
|
+
const parentNode = groupMap.get(parent.getId() || '');
|
|
39
|
+
if (parentNode) {
|
|
40
|
+
parentNode.children.push(node);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// No parent = root group
|
|
45
|
+
rootGroups.push(node);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return rootGroups;
|
|
49
|
+
}
|
|
50
|
+
function loadSystemPrompt() {
|
|
51
|
+
try {
|
|
52
|
+
// Get the directory where this file is located and navigate to the parent mcp directory
|
|
53
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
54
|
+
const __dirname = dirname(__filename);
|
|
55
|
+
const mcpPath = join(__dirname, '..');
|
|
56
|
+
const systemPrompt = readFileSync(join(mcpPath, 'system-prompt.md'), 'utf-8');
|
|
57
|
+
return systemPrompt;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return `# Bkper MCP System Prompt\n\nDocumentation not available.\nError: ${error instanceof Error ? error.message : String(error)}\nPath attempted: ${join(dirname(fileURLToPath(import.meta.url)), '..', 'system-prompt.md')}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function handleGetBook(params) {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
try {
|
|
66
|
+
// Validate required parameters
|
|
67
|
+
if (!params.bookId) {
|
|
68
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: bookId');
|
|
69
|
+
}
|
|
70
|
+
// Get configured Bkper instance
|
|
71
|
+
const bkperInstance = getBkperInstance();
|
|
72
|
+
// Get the specific book
|
|
73
|
+
const book = yield bkperInstance.getBook(params.bookId, false, true);
|
|
74
|
+
if (!book) {
|
|
75
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
76
|
+
}
|
|
77
|
+
// Get book JSON data
|
|
78
|
+
const bookJson = book.json();
|
|
79
|
+
// Get groups from the book
|
|
80
|
+
const groups = yield book.getGroups();
|
|
81
|
+
// Build hierarchical structure
|
|
82
|
+
const hierarchicalGroups = buildHierarchicalStructure(groups || []);
|
|
83
|
+
bookJson.groups = hierarchicalGroups;
|
|
84
|
+
// Build response with book data and groups
|
|
85
|
+
const response = {
|
|
86
|
+
book: bookJson,
|
|
87
|
+
readme: loadSystemPrompt()
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: 'text',
|
|
93
|
+
text: JSON.stringify(response, null, 2),
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
// Handle specific book not found errors
|
|
100
|
+
if (error instanceof Error && error.message.includes('not found')) {
|
|
101
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
102
|
+
}
|
|
103
|
+
// Re-throw MCP errors as-is
|
|
104
|
+
if (error instanceof McpError) {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
// Handle other errors
|
|
108
|
+
throw new McpError(ErrorCode.InternalError, `Failed to get book: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export const getBookToolDefinition = {
|
|
113
|
+
name: 'get_book',
|
|
114
|
+
description: 'Retrieve detailed information about a specific book including its group hierarchy and system prompt',
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: 'object',
|
|
117
|
+
properties: {
|
|
118
|
+
bookId: {
|
|
119
|
+
type: 'string',
|
|
120
|
+
description: 'The unique identifier of the book to retrieve'
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
required: ['bookId']
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=get_book.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get_book.js","sourceRoot":"","sources":["../../../src/mcp/tools/get_book.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
interface ListBooksParams {
|
|
3
|
+
filter: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function handleListBooks(params: ListBooksParams): Promise<CallToolResult>;
|
|
6
|
+
export declare const listBooksToolDefinition: {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: string;
|
|
11
|
+
properties: {
|
|
12
|
+
filter: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
required: string[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=list_books.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_books.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/list_books.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAGzF,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAsB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA+BtF;AAED,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;CAanC,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
12
|
+
function fetchBooks(filter) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
// Get configured Bkper instance
|
|
15
|
+
const bkperInstance = getBkperInstance();
|
|
16
|
+
// Get books using high-level wrapper with required filter
|
|
17
|
+
const bkperBooks = yield bkperInstance.getBooks(filter);
|
|
18
|
+
// Return full book JSON data - no filtering, no transforming
|
|
19
|
+
const books = bkperBooks.map((book) => book.json());
|
|
20
|
+
const total = books.length;
|
|
21
|
+
return { books, total };
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function handleListBooks(params) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
try {
|
|
27
|
+
// Fetch all books with required filter
|
|
28
|
+
const { books, total } = yield fetchBooks(params.filter);
|
|
29
|
+
// Build response
|
|
30
|
+
const response = {
|
|
31
|
+
total,
|
|
32
|
+
books
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: JSON.stringify(response, null, 2),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
// Re-throw MCP errors as-is
|
|
45
|
+
if (error instanceof McpError) {
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
// Handle other errors
|
|
49
|
+
throw new McpError(ErrorCode.InternalError, `Failed to list books: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export const listBooksToolDefinition = {
|
|
54
|
+
name: 'list_books',
|
|
55
|
+
description: 'List books with mandatory filtering by name or property',
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
filter: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
description: 'Required filter to search books by name or property (case-insensitive substring match)'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
required: ['filter']
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=list_books.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_books.js","sourceRoot":"","sources":["../../../src/mcp/tools/list_books.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAkB,SAAS,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAWvD,SAAe,UAAU,CAAC,MAAc;;QACtC,gCAAgC;QAChC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;QAEzC,0DAA0D;QAC1D,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAExD,6DAA6D;QAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAEzD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QAE3B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;CAAA;AAED,MAAM,UAAgB,eAAe,CAAC,MAAuB;;QAC3D,IAAI,CAAC;YACH,uCAAuC;YACvC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEzD,iBAAiB;YACjB,MAAM,QAAQ,GAAkB;gBAC9B,KAAK;gBACL,KAAK;aACN,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;qBACxC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,4BAA4B;YAC5B,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,sBAAsB;YACtB,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;CAAA;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,yDAAyD;IACtE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wFAAwF;aACtG;SACF;QACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;KACrB;CACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
interface ListTransactionsParams {
|
|
3
|
+
bookId: string;
|
|
4
|
+
cursor?: string;
|
|
5
|
+
query: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function handleListTransactions(params: ListTransactionsParams): Promise<CallToolResult>;
|
|
9
|
+
export declare const listTransactionsToolDefinition: {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: {
|
|
15
|
+
bookId: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
cursor: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
query: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
limit: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
minimum: number;
|
|
31
|
+
maximum: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
required: string[];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=list_transactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_transactions.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/list_transactions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,oCAAoC,CAAC;AAGzF,UAAU,sBAAsB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0EpG;AAED,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2B1C,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { getBkperInstance } from '../bkper-factory.js';
|
|
12
|
+
export function handleListTransactions(params) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
try {
|
|
15
|
+
// Validate required parameters
|
|
16
|
+
if (!params.bookId) {
|
|
17
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: bookId');
|
|
18
|
+
}
|
|
19
|
+
if (!params.query) {
|
|
20
|
+
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: query');
|
|
21
|
+
}
|
|
22
|
+
// Get configured Bkper instance
|
|
23
|
+
const bkperInstance = getBkperInstance();
|
|
24
|
+
// Get the book first
|
|
25
|
+
const book = yield bkperInstance.getBook(params.bookId);
|
|
26
|
+
if (!book) {
|
|
27
|
+
throw new McpError(ErrorCode.InvalidParams, `Book not found: ${params.bookId}`);
|
|
28
|
+
}
|
|
29
|
+
// Set up pagination parameters
|
|
30
|
+
const limit = Math.min(params.limit || 25, 100); // Default 25, max 100
|
|
31
|
+
// Get transactions using native API pagination
|
|
32
|
+
const transactionList = yield book.listTransactions(params.query, limit, params.cursor);
|
|
33
|
+
// Get transactions from list
|
|
34
|
+
const transactionItems = transactionList.getItems();
|
|
35
|
+
const transactions = transactionItems.map((transaction) => transaction.json());
|
|
36
|
+
// Get pagination info from list
|
|
37
|
+
const hasMore = transactionItems.length > 0;
|
|
38
|
+
const nextCursor = transactionList.getCursor() || null;
|
|
39
|
+
// Build response
|
|
40
|
+
const response = {
|
|
41
|
+
transactions,
|
|
42
|
+
hasMore,
|
|
43
|
+
cursor: nextCursor,
|
|
44
|
+
limit
|
|
45
|
+
};
|
|
46
|
+
// Include query in response (now always provided)
|
|
47
|
+
response.query = params.query;
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: JSON.stringify(response, null, 2),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// Re-throw MCP errors as-is
|
|
59
|
+
if (error instanceof McpError) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
// Handle other errors
|
|
63
|
+
throw new McpError(ErrorCode.InternalError, `Failed to list transactions: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export const listTransactionsToolDefinition = {
|
|
68
|
+
name: 'list_transactions',
|
|
69
|
+
description: 'List transactions with native API cursor-based pagination and query filtering. Use get_book first to understand query syntax and usage rules.',
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
bookId: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'The unique identifier of the book'
|
|
76
|
+
},
|
|
77
|
+
cursor: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'Pagination cursor for next page (provided by previous response)'
|
|
80
|
+
},
|
|
81
|
+
query: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Required query string to filter transactions using comprehensive syntax (account:, from:, to:, group:, on:, after:, before:, amount:, text search, logical operators, etc.)'
|
|
84
|
+
},
|
|
85
|
+
limit: {
|
|
86
|
+
type: 'number',
|
|
87
|
+
description: 'Number of transactions per page (default: 25, maximum: 100)',
|
|
88
|
+
minimum: 1,
|
|
89
|
+
maximum: 100
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
required: ['bookId', 'query']
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=list_transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list_transactions.js","sourceRoot":"","sources":["../../../src/mcp/tools/list_transactions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bkper",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Node.js command line client for Bkper",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bkper": "./lib/cli.js"
|
|
@@ -17,14 +17,32 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"lib/**/*"
|
|
19
19
|
],
|
|
20
|
+
"mcp": {
|
|
21
|
+
"server": {
|
|
22
|
+
"command": "node",
|
|
23
|
+
"args": [
|
|
24
|
+
"lib/cli.js",
|
|
25
|
+
"mcp",
|
|
26
|
+
"start"
|
|
27
|
+
],
|
|
28
|
+
"env": {}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
20
31
|
"scripts": {
|
|
21
32
|
"clean": "rm -rf ./lib & rm -rf ./node_modules & wait",
|
|
22
33
|
"prebuild": "bun install",
|
|
23
34
|
"build": "run-s build:*",
|
|
24
|
-
"build:clean": "gts clean",
|
|
35
|
+
"build:clean": "gts clean && rimraf temp",
|
|
25
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",
|
|
26
39
|
"predev": "bun run build",
|
|
27
|
-
"dev": "tsc -w",
|
|
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",
|
|
28
46
|
"upgrade:api": "bun update @bkper/bkper-api-types --latest && bun update bkper-js --latest",
|
|
29
47
|
"patch": "yarn version --patch",
|
|
30
48
|
"minor": "yarn version --minor",
|
|
@@ -34,19 +52,28 @@
|
|
|
34
52
|
},
|
|
35
53
|
"dependencies": {
|
|
36
54
|
"@google-cloud/local-auth": "^3.0.1",
|
|
37
|
-
"
|
|
55
|
+
"@modelcontextprotocol/sdk": "^1.13.1",
|
|
56
|
+
"bkper-js": "^2.4.0",
|
|
38
57
|
"commander": "^6.2.1",
|
|
39
58
|
"dotenv": "^8.2.0",
|
|
40
59
|
"google-auth-library": "^9.14.0",
|
|
41
60
|
"yaml": "^2.5.1"
|
|
42
61
|
},
|
|
43
62
|
"devDependencies": {
|
|
44
|
-
"@bkper/bkper-api-types": "^5.
|
|
63
|
+
"@bkper/bkper-api-types": "^5.23.0",
|
|
64
|
+
"@types/chai": "^4.3.0",
|
|
45
65
|
"@types/commander": "^2.12.2",
|
|
66
|
+
"@types/mocha": "^10.0.0",
|
|
46
67
|
"@types/node": "^22.5.1",
|
|
68
|
+
"chai": "^4.3.0",
|
|
69
|
+
"concurrently": "^8.2.2",
|
|
47
70
|
"gts": "^3.0.3",
|
|
71
|
+
"mocha": "^10.0.0",
|
|
72
|
+
"nodemon": "^3.0.1",
|
|
48
73
|
"npm-run-all": "^4.1.5",
|
|
49
74
|
"rimraf": "^3.0.2",
|
|
75
|
+
"ts-node": "^10.9.2",
|
|
76
|
+
"tsconfig-paths": "^4.2.0",
|
|
50
77
|
"typescript": "^5.5.4"
|
|
51
78
|
}
|
|
52
79
|
}
|