@warmio/mcp 1.2.1 → 1.2.2
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/dist/server.js +7 -26
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -28,12 +28,6 @@ function compactTransaction(t) {
|
|
|
28
28
|
c: t.category || null,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
function matchesSearch(t, search) {
|
|
32
|
-
const s = search.toLowerCase();
|
|
33
|
-
const merchant = (t.merchant_name || t.name || '').toLowerCase();
|
|
34
|
-
const category = (t.category || '').toLowerCase();
|
|
35
|
-
return merchant.includes(s) || category.includes(s);
|
|
36
|
-
}
|
|
37
31
|
function inDateRange(t, since, until) {
|
|
38
32
|
if (since && t.date < since)
|
|
39
33
|
return false;
|
|
@@ -117,7 +111,7 @@ async function apiRequest(endpoint, params = {}) {
|
|
|
117
111
|
}
|
|
118
112
|
return response.json();
|
|
119
113
|
}
|
|
120
|
-
const server = new Server({ name: 'warm', version: '1.2.
|
|
114
|
+
const server = new Server({ name: 'warm', version: '1.2.2' }, { capabilities: { tools: {} } });
|
|
121
115
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
122
116
|
tools: [
|
|
123
117
|
{
|
|
@@ -131,14 +125,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
131
125
|
},
|
|
132
126
|
{
|
|
133
127
|
name: 'get_transactions',
|
|
134
|
-
description: '
|
|
128
|
+
description: 'Get transactions and analyze spending. Use for: "How much did I spend on coffee?", "Show my purchases", "What did I buy last month?". Returns: {summary: {total, count, avg}, txns: [{d, a, m, c}]} where d=date, a=amount, m=merchant, c=category. IMPORTANT: Do NOT pre-filter—fetch all transactions then analyze the `c` (category) field to answer category questions (coffee, dining, groceries, etc.). Category details take priority over merchant name string matching.',
|
|
135
129
|
inputSchema: {
|
|
136
130
|
type: 'object',
|
|
137
131
|
properties: {
|
|
138
|
-
search: {
|
|
139
|
-
type: 'string',
|
|
140
|
-
description: 'Filter by merchant or category (e.g., "coffee", "amazon", "groceries")',
|
|
141
|
-
},
|
|
142
132
|
since: {
|
|
143
133
|
type: 'string',
|
|
144
134
|
description: 'Start date inclusive (YYYY-MM-DD)',
|
|
@@ -149,7 +139,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
149
139
|
},
|
|
150
140
|
limit: {
|
|
151
141
|
type: 'number',
|
|
152
|
-
description: 'Max transactions (default:
|
|
142
|
+
description: 'Max transactions to return (default: 200, max: 500)',
|
|
153
143
|
},
|
|
154
144
|
},
|
|
155
145
|
},
|
|
@@ -207,21 +197,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
207
197
|
return { content: [{ type: 'text', text: JSON.stringify(data) }] };
|
|
208
198
|
}
|
|
209
199
|
case 'get_transactions': {
|
|
210
|
-
const search = args?.search ? String(args.search) : undefined;
|
|
211
200
|
const since = args?.since ? String(args.since) : undefined;
|
|
212
201
|
const until = args?.until ? String(args.until) : undefined;
|
|
213
|
-
const parsedLimit = args?.limit ? Number(args.limit) :
|
|
202
|
+
const parsedLimit = args?.limit ? Number(args.limit) : 200;
|
|
214
203
|
const requestedLimit = Number.isFinite(parsedLimit)
|
|
215
|
-
? Math.max(1, Math.min(Math.floor(parsedLimit),
|
|
216
|
-
:
|
|
217
|
-
const needsClientFiltering = Boolean(search || until);
|
|
204
|
+
? Math.max(1, Math.min(Math.floor(parsedLimit), 500))
|
|
205
|
+
: 200;
|
|
218
206
|
let transactions = [];
|
|
219
207
|
let cursor;
|
|
220
208
|
let pagesFetched = 0;
|
|
221
209
|
let scanned = 0;
|
|
222
210
|
do {
|
|
223
211
|
const params = {
|
|
224
|
-
limit: String(
|
|
212
|
+
limit: String(TRANSACTION_PAGE_SIZE),
|
|
225
213
|
};
|
|
226
214
|
if (since)
|
|
227
215
|
params.last_knowledge = since;
|
|
@@ -233,18 +221,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
233
221
|
scanned += batch.length;
|
|
234
222
|
pagesFetched += 1;
|
|
235
223
|
cursor = response.cursor;
|
|
236
|
-
if (!needsClientFiltering) {
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
224
|
} while (cursor && pagesFetched < MAX_TRANSACTION_PAGES && scanned < MAX_TRANSACTION_SCAN);
|
|
240
225
|
// Apply date range filter (until is client-side since API only supports since)
|
|
241
226
|
if (until) {
|
|
242
227
|
transactions = transactions.filter((t) => inDateRange(t, since, until));
|
|
243
228
|
}
|
|
244
|
-
// Apply search filter
|
|
245
|
-
if (search) {
|
|
246
|
-
transactions = transactions.filter((t) => matchesSearch(t, search));
|
|
247
|
-
}
|
|
248
229
|
const compactTxns = transactions.map(compactTransaction);
|
|
249
230
|
// Calculate summary on ALL matching transactions
|
|
250
231
|
const summary = calculateSummary(compactTxns);
|