@daften/fireflyiii-mcp 0.1.0 → 0.2.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/.env.example +15 -0
- package/CHANGELOG.md +24 -3
- package/README.md +77 -8
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +47 -15
- package/dist/args.js.map +1 -1
- package/dist/client.d.ts +19 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +47 -0
- package/dist/client.js.map +1 -1
- package/dist/http.js +3 -3
- package/dist/http.js.map +1 -1
- package/dist/tools/_helpers.d.ts +54 -0
- package/dist/tools/_helpers.d.ts.map +1 -1
- package/dist/tools/_helpers.js +69 -0
- package/dist/tools/_helpers.js.map +1 -1
- package/dist/tools/accounts.d.ts +2 -0
- package/dist/tools/accounts.d.ts.map +1 -1
- package/dist/tools/accounts.js +57 -9
- package/dist/tools/accounts.js.map +1 -1
- package/dist/tools/attachments.d.ts +13 -1
- package/dist/tools/attachments.d.ts.map +1 -1
- package/dist/tools/attachments.js +29 -5
- package/dist/tools/attachments.js.map +1 -1
- package/dist/tools/budgets.d.ts +1 -0
- package/dist/tools/budgets.d.ts.map +1 -1
- package/dist/tools/budgets.js +55 -11
- package/dist/tools/budgets.js.map +1 -1
- package/dist/tools/categories.d.ts +1 -0
- package/dist/tools/categories.d.ts.map +1 -1
- package/dist/tools/categories.js +51 -7
- package/dist/tools/categories.js.map +1 -1
- package/dist/tools/reports.js +12 -12
- package/dist/tools/reports.js.map +1 -1
- package/package.json +8 -2
package/dist/tools/_helpers.js
CHANGED
|
@@ -20,5 +20,74 @@ export function defineTool(server, name, config, fetch) {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Like {@link defineTool}, but the handler returns a ready-made MCP result
|
|
25
|
+
* (content blocks) rather than a plain value. Error handling is identical:
|
|
26
|
+
* thrown errors become an `isError` text block via {@link formatError}.
|
|
27
|
+
*/
|
|
28
|
+
export function defineContentTool(server, name, config, fetch) {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
server.registerTool(name, config, async (args) => {
|
|
31
|
+
try {
|
|
32
|
+
return await fetch(args);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
return { content: [{ type: 'text', text: formatError(err) }], isError: true };
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
23
39
|
export const dateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD');
|
|
40
|
+
/**
|
|
41
|
+
* Extracts a leading numeric ID from an autocomplete label such as `"42 (Checking - asset)"`.
|
|
42
|
+
*
|
|
43
|
+
* This relies on the completion-label format (the numeric ID always comes first). When the value
|
|
44
|
+
* has no leading digits it is returned unchanged. Note that a free-typed value like `"42 Main St"`
|
|
45
|
+
* would resolve to `"42"`, so callers should prefer values picked from autocomplete suggestions
|
|
46
|
+
* rather than arbitrary user input.
|
|
47
|
+
*/
|
|
48
|
+
export function parseId(id) {
|
|
49
|
+
const match = id.match(/^(\d+)/);
|
|
50
|
+
return match ? match[1] : id;
|
|
51
|
+
}
|
|
52
|
+
// Autocomplete tuning shared by every completion handler.
|
|
53
|
+
export const AUTOCOMPLETE_FETCH_LIMIT = 1000; // max records pulled from the API per refresh
|
|
54
|
+
export const AUTOCOMPLETE_MAX_SUGGESTIONS = 100; // max labels returned to the client per keystroke
|
|
55
|
+
const AUTOCOMPLETE_CACHE_TTL_MS = 60_000; // 1 minute
|
|
56
|
+
const DEBUG_ENABLED = process.env.FIREFLY_DEBUG === 'true' || process.env.FIREFLY_DEBUG === '1';
|
|
57
|
+
/**
|
|
58
|
+
* Writes to stderr only when FIREFLY_DEBUG is set. Never touches stdout, so it is safe under the
|
|
59
|
+
* stdio transport. Used for the verbose autocomplete tracing that would otherwise fire on every
|
|
60
|
+
* keystroke (and echo user search terms) in normal operation.
|
|
61
|
+
*/
|
|
62
|
+
export function debugLog(...args) {
|
|
63
|
+
if (DEBUG_ENABLED)
|
|
64
|
+
console.error(...args);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Creates a module-scoped TTL cache keyed by an opaque identity string. The key MUST scope entries
|
|
68
|
+
* per authenticated user (e.g. a hash of the bearer token): in HTTP mode a single client instance
|
|
69
|
+
* serves every request, so an unkeyed cache would leak one user's data to another.
|
|
70
|
+
*/
|
|
71
|
+
export function createTtlCache(ttlMs = AUTOCOMPLETE_CACHE_TTL_MS) {
|
|
72
|
+
const entries = new Map();
|
|
73
|
+
return {
|
|
74
|
+
get(key, fetchFn) {
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
const existing = entries.get(key);
|
|
77
|
+
if (existing && now - existing.fetchedAt <= ttlMs)
|
|
78
|
+
return existing.promise;
|
|
79
|
+
const promise = fetchFn().catch((err) => {
|
|
80
|
+
// Evict the failed promise so a later attempt re-fetches rather than caching the rejection.
|
|
81
|
+
if (entries.get(key)?.promise === promise)
|
|
82
|
+
entries.delete(key);
|
|
83
|
+
throw err;
|
|
84
|
+
});
|
|
85
|
+
entries.set(key, { promise, fetchedAt: now });
|
|
86
|
+
return promise;
|
|
87
|
+
},
|
|
88
|
+
clear() {
|
|
89
|
+
entries.clear();
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
24
93
|
//# sourceMappingURL=_helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../src/tools/_helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAc3C,MAAM,UAAU,UAAU,CACxB,MAAiB,EACjB,IAAY,EACZ,MAAkB,EAClB,KAA0D;IAE1D,+FAA+F;IAC/F,8DAA8D;IAC7D,MAAc,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QACjF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC5E;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACzF,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,EAAE,yBAAyB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../src/tools/_helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/accounts.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare function fetchAccount(client: FireflyClient, id: string): Promise
|
|
|
10
10
|
export declare function createAccount(client: FireflyClient, params: {
|
|
11
11
|
name: string;
|
|
12
12
|
type: 'asset' | 'expense' | 'revenue' | 'liability';
|
|
13
|
+
account_role?: 'defaultAsset' | 'sharedAsset' | 'savingAsset' | 'ccAsset' | 'cashWalletAsset';
|
|
13
14
|
currency_code?: string;
|
|
14
15
|
iban?: string;
|
|
15
16
|
opening_balance?: string;
|
|
@@ -44,5 +45,6 @@ export declare function searchAccounts(client: FireflyClient, params: {
|
|
|
44
45
|
page?: number;
|
|
45
46
|
limit?: number;
|
|
46
47
|
}): Promise<UnwrappedList>;
|
|
48
|
+
export declare function clearAccountsCache(): void;
|
|
47
49
|
export declare function registerAccountTools(server: McpServer, client: FireflyClient): void;
|
|
48
50
|
//# sourceMappingURL=accounts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAC;AAazB,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC,aAAa,CAAC,CAKxB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAG9F;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IACN,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IACpD,YAAY,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,aAAa,GAAG,SAAS,GAAG,iBAAiB,CAAC;IAC9F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IACN,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAG7G;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACrF,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,OAAO,CAAC,aAAa,CAAC,CAKxB;AAMD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA2MnF"}
|
package/dist/tools/accounts.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
import { unwrapList, unwrapSingle, } from '../transform.js';
|
|
3
4
|
import { DELETE_ANNOTATIONS, READ_ANNOTATIONS, UPDATE_ANNOTATIONS, WRITE_ANNOTATIONS } from './_annotations.js';
|
|
4
|
-
import { dateSchema, defineTool } from './_helpers.js';
|
|
5
|
+
import { AUTOCOMPLETE_FETCH_LIMIT, AUTOCOMPLETE_MAX_SUGGESTIONS, createTtlCache, dateSchema, debugLog, defineTool, parseId, } from './_helpers.js';
|
|
5
6
|
export async function fetchAccounts(client, params) {
|
|
6
7
|
const query = { page: params.page, limit: params.limit };
|
|
7
8
|
if (params.type && params.type !== 'all')
|
|
@@ -43,6 +44,12 @@ export async function searchAccounts(client, params) {
|
|
|
43
44
|
const response = await client.get('/search/accounts', query);
|
|
44
45
|
return unwrapList(response);
|
|
45
46
|
}
|
|
47
|
+
// Module-scoped so the cache survives across the stateless HTTP requests autocomplete fires;
|
|
48
|
+
// keyed per identity inside the completion handler so one user never sees another's accounts.
|
|
49
|
+
const accountsCache = createTtlCache();
|
|
50
|
+
export function clearAccountsCache() {
|
|
51
|
+
accountsCache.clear();
|
|
52
|
+
}
|
|
46
53
|
export function registerAccountTools(server, client) {
|
|
47
54
|
defineTool(server, 'get_accounts', {
|
|
48
55
|
title: 'Get Accounts',
|
|
@@ -62,18 +69,38 @@ export function registerAccountTools(server, client) {
|
|
|
62
69
|
page: page,
|
|
63
70
|
limit: limit,
|
|
64
71
|
}));
|
|
72
|
+
const accountIdSchema = completable(z.string().describe('Account ID — use get_accounts to find valid IDs'), async (value) => {
|
|
73
|
+
debugLog(`[Autocomplete] Account search input: "${value}"`);
|
|
74
|
+
try {
|
|
75
|
+
const accounts = await accountsCache.get(client.cacheKey(), () => fetchAccounts(client, { limit: AUTOCOMPLETE_FETCH_LIMIT }));
|
|
76
|
+
const suggestions = accounts.data
|
|
77
|
+
.map((a) => `${a.id} (${a.name ?? ''} - ${a.type ?? ''})`)
|
|
78
|
+
.filter((label) => label.toLowerCase().includes(value.toLowerCase()))
|
|
79
|
+
.slice(0, AUTOCOMPLETE_MAX_SUGGESTIONS);
|
|
80
|
+
debugLog(`[Autocomplete] Account suggestions found: ${suggestions.length}`);
|
|
81
|
+
return suggestions;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
debugLog('[Autocomplete Error - Account]:', err);
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
65
88
|
defineTool(server, 'get_account', {
|
|
66
89
|
title: 'Get Account',
|
|
67
90
|
description: 'Get a single Firefly III account by its numeric ID, including the current balance. Use get_accounts to find valid account IDs.',
|
|
68
|
-
inputSchema: { id:
|
|
91
|
+
inputSchema: { id: accountIdSchema },
|
|
69
92
|
annotations: READ_ANNOTATIONS,
|
|
70
|
-
}, ({ id }) => fetchAccount(client, id));
|
|
93
|
+
}, ({ id }) => fetchAccount(client, parseId(id)));
|
|
71
94
|
defineTool(server, 'create_account', {
|
|
72
95
|
title: 'Create Account',
|
|
73
96
|
description: 'Create a new account in Firefly III.',
|
|
74
97
|
inputSchema: {
|
|
75
98
|
name: z.string().describe('Account name'),
|
|
76
99
|
type: z.enum(['asset', 'expense', 'revenue', 'liability']).describe('Account type'),
|
|
100
|
+
account_role: z
|
|
101
|
+
.enum(['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'])
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Role for asset accounts (required when type is asset)'),
|
|
77
104
|
currency_code: z.string().optional().describe('Currency code (e.g. EUR, USD)'),
|
|
78
105
|
iban: z.string().optional().describe('IBAN number'),
|
|
79
106
|
opening_balance: z.string().optional().describe('Opening balance as a number string'),
|
|
@@ -87,7 +114,7 @@ export function registerAccountTools(server, client) {
|
|
|
87
114
|
title: 'Update Account',
|
|
88
115
|
description: 'Update an existing account in Firefly III. Only fields provided will be changed. Use get_account to confirm the ID.',
|
|
89
116
|
inputSchema: {
|
|
90
|
-
id:
|
|
117
|
+
id: accountIdSchema,
|
|
91
118
|
name: z.string().optional().describe('Account name'),
|
|
92
119
|
currency_code: z.string().optional().describe('Currency code (e.g. EUR, USD)'),
|
|
93
120
|
iban: z.string().optional().describe('IBAN number'),
|
|
@@ -98,18 +125,18 @@ export function registerAccountTools(server, client) {
|
|
|
98
125
|
notes: z.string().optional().describe('Notes'),
|
|
99
126
|
},
|
|
100
127
|
annotations: UPDATE_ANNOTATIONS,
|
|
101
|
-
}, ({ id, ...params }) => updateAccount(client, id, params));
|
|
128
|
+
}, ({ id, ...params }) => updateAccount(client, parseId(id), params));
|
|
102
129
|
defineTool(server, 'delete_account', {
|
|
103
130
|
title: 'Delete Account',
|
|
104
131
|
description: 'Permanently delete an account from Firefly III. **This action cannot be undone.** Accounts with linked transactions cannot be deleted. Use get_account to confirm before deleting.',
|
|
105
|
-
inputSchema: { id:
|
|
132
|
+
inputSchema: { id: accountIdSchema },
|
|
106
133
|
annotations: DELETE_ANNOTATIONS,
|
|
107
|
-
}, ({ id }) => deleteAccount(client, id));
|
|
134
|
+
}, ({ id }) => deleteAccount(client, parseId(id)));
|
|
108
135
|
defineTool(server, 'get_account_transactions', {
|
|
109
136
|
title: 'Get Account Transactions',
|
|
110
137
|
description: 'Get all transactions for a specific account. Use get_accounts to find valid account IDs.',
|
|
111
138
|
inputSchema: {
|
|
112
|
-
id:
|
|
139
|
+
id: accountIdSchema,
|
|
113
140
|
start: dateSchema.optional().describe('Start date (YYYY-MM-DD)'),
|
|
114
141
|
end: dateSchema.optional().describe('End date (YYYY-MM-DD)'),
|
|
115
142
|
type: z
|
|
@@ -120,7 +147,7 @@ export function registerAccountTools(server, client) {
|
|
|
120
147
|
limit: z.number().int().positive().max(100).optional().default(50).describe('Results per page (max 100)'),
|
|
121
148
|
},
|
|
122
149
|
annotations: READ_ANNOTATIONS,
|
|
123
|
-
}, ({ id, start, end, type, page, limit }) => fetchAccountTransactions(client, id, {
|
|
150
|
+
}, ({ id, start, end, type, page, limit }) => fetchAccountTransactions(client, parseId(id), {
|
|
124
151
|
start: start,
|
|
125
152
|
end: end,
|
|
126
153
|
type: type,
|
|
@@ -147,5 +174,26 @@ export function registerAccountTools(server, client) {
|
|
|
147
174
|
page: page,
|
|
148
175
|
limit: limit,
|
|
149
176
|
}));
|
|
177
|
+
server.registerPrompt('account-transactions', {
|
|
178
|
+
title: 'Get Transactions by Account',
|
|
179
|
+
description: 'Get transactions for a specific account with autocomplete.',
|
|
180
|
+
argsSchema: {
|
|
181
|
+
account: accountIdSchema,
|
|
182
|
+
},
|
|
183
|
+
}, async ({ account }) => {
|
|
184
|
+
const id = parseId(account);
|
|
185
|
+
return {
|
|
186
|
+
description: `Get transactions for account ID ${id}`,
|
|
187
|
+
messages: [
|
|
188
|
+
{
|
|
189
|
+
role: 'user',
|
|
190
|
+
content: {
|
|
191
|
+
type: 'text',
|
|
192
|
+
text: `Show me the recent transactions for account ID "${id}".`,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
});
|
|
150
198
|
}
|
|
151
199
|
//# sourceMappingURL=accounts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/tools/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAKL,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChH,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,cAAc,EACd,UAAU,EACV,QAAQ,EACR,UAAU,EACV,OAAO,GACR,MAAM,eAAe,CAAC;AAEvB,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAqB,EACrB,MAAwD;IAExD,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACtE,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACnE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAsB,WAAW,EAAE,KAAK,CAAC,CAAC;IAC3E,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAqB,EAAE,EAAU;IAClE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAwB,aAAa,EAAE,EAAE,CAAC,CAAC;IAC5E,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAqB,EACrB,MAUC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAwB,WAAW,EAAE,MAAM,CAAC,CAAC;IAC/E,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAqB,EACrB,EAAU,EACV,MASC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAwB,aAAa,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IACpF,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAqB,EAAE,EAAU;IACnE,MAAM,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAqB,EACrB,EAAU,EACV,MAAsF;IAEtF,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACtE,IAAI,MAAM,CAAC,KAAK;QAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC7C,IAAI,MAAM,CAAC,GAAG;QAAE,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAC1C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAsB,aAAa,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;IAC9F,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAqB,EACrB,MAAwE;IAExE,MAAM,KAAK,GAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC3F,IAAI,MAAM,CAAC,KAAK;QAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAsB,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAClF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,6FAA6F;AAC7F,8FAA8F;AAC9F,MAAM,aAAa,GAAG,cAAc,EAAiB,CAAC;AAEtD,MAAM,UAAU,kBAAkB;IAChC,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,UAAU,CACR,MAAM,EACN,cAAc,EACd;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,iNAAiN;QACnN,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;iBACzD,QAAQ,EAAE;iBACV,OAAO,CAAC,KAAK,CAAC;iBACd,QAAQ,CAAC,qBAAqB,CAAC;YAClC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC/E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SAC1G;QACD,WAAW,EAAE,gBAAgB;KAC9B,EACD,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CACxB,aAAa,CAAC,MAAM,EAAE;QACpB,IAAI,EAAE,IAA0B;QAChC,IAAI,EAAE,IAA0B;QAChC,KAAK,EAAE,KAA2B;KACnC,CAAC,CACL,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC,EACtE,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,QAAQ,CAAC,yCAAyC,KAAK,GAAG,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,CAC/D,aAAa,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAC3D,CAAC;YACF,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI;iBAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,GAAG,CAAC;iBACzD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;iBACpE,KAAK,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAAC;YAC1C,QAAQ,CAAC,6CAA6C,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5E,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;YACjD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,UAAU,CACR,MAAM,EACN,aAAa,EACb;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,gIAAgI;QAClI,WAAW,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;QACpC,WAAW,EAAE,gBAAgB;KAC9B,EACD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,EAAY,CAAC,CAAC,CACxD,CAAC;IAEF,UAAU,CACR,MAAM,EACN,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,sCAAsC;QACnD,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACzC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;YACnF,YAAY,EAAE,CAAC;iBACZ,IAAI,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;iBAClF,QAAQ,EAAE;iBACV,QAAQ,CAAC,uDAAuD,CAAC;YACpE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YACnD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YACrF,oBAAoB,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACzF,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACvF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC/C;QACD,WAAW,EAAE,iBAAiB;KAC/B,EACD,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,MAA6C,CAAC,CACjF,CAAC;IAEF,UAAU,CACR,MAAM,EACN,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,qHAAqH;QACvH,WAAW,EAAE;YACX,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACpD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YACnD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YACrF,oBAAoB,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACzF,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACvF,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YACxE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC/C;QACD,WAAW,EAAE,kBAAkB;KAChC,EACD,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAY,CAAC,EAAE,MAA6C,CAAC,CACnH,CAAC;IAEF,UAAU,CACR,MAAM,EACN,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,oLAAoL;QACtL,WAAW,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;QACpC,WAAW,EAAE,kBAAkB;KAChC,EACD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAY,CAAC,CAAC,CACzD,CAAC;IAEF,UAAU,CACR,MAAM,EACN,0BAA0B,EAC1B;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,0FAA0F;QACvG,WAAW,EAAE;YACX,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAChE,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YAC5D,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;iBAC7G,QAAQ,EAAE;iBACV,QAAQ,CAAC,4BAA4B,CAAC;YACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC/E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SAC1G;QACD,WAAW,EAAE,gBAAgB;KAC9B,EACD,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CACxC,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,EAAY,CAAC,EAAE;QACtD,KAAK,EAAE,KAA2B;QAClC,GAAG,EAAE,GAAyB;QAC9B,IAAI,EAAE,IAA0B;QAChC,IAAI,EAAE,IAA0B;QAChC,KAAK,EAAE,KAA2B;KACnC,CAAC,CACL,CAAC;IAEF,UAAU,CACR,MAAM,EACN,iBAAiB,EACjB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,2DAA2D;QACxE,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC1C,KAAK,EAAE,CAAC;iBACL,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;iBAC/D,QAAQ,EAAE;iBACV,OAAO,CAAC,KAAK,CAAC;iBACd,QAAQ,CAAC,oBAAoB,CAAC;YACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC/E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SAC1G;QACD,WAAW,EAAE,gBAAgB;KAC9B,EACD,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAChC,cAAc,CAAC,MAAM,EAAE;QACrB,KAAK,EAAE,KAAe;QACtB,KAAK,EAAE,KAA2B;QAClC,IAAI,EAAE,IAA0B;QAChC,KAAK,EAAE,KAA2B;KACnC,CAAC,CACL,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,sBAAsB,EACtB;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EAAE,4DAA4D;QACzE,UAAU,EAAE;YACV,OAAO,EAAE,eAAe;SACzB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,EAAE,GAAG,OAAO,CAAC,OAAiB,CAAC,CAAC;QACtC,OAAO;YACL,WAAW,EAAE,mCAAmC,EAAE,EAAE;YACpD,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mDAAmD,EAAE,IAAI;qBAChE;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { FireflyClient } from '../client.js';
|
|
3
3
|
import { type UnwrappedList, type UnwrappedSingle } from '../transform.js';
|
|
4
|
+
import { type ContentResult } from './_helpers.js';
|
|
4
5
|
export declare function fetchAttachments(client: FireflyClient, params: {
|
|
5
6
|
page?: number;
|
|
6
7
|
limit?: number;
|
|
@@ -26,6 +27,17 @@ export declare function uploadAttachment(client: FireflyClient, id: string, cont
|
|
|
26
27
|
uploaded: true;
|
|
27
28
|
id: string;
|
|
28
29
|
}>;
|
|
29
|
-
export
|
|
30
|
+
export interface DownloadedAttachment {
|
|
31
|
+
content_base64: string;
|
|
32
|
+
content_type: string;
|
|
33
|
+
filename: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function downloadAttachment(client: FireflyClient, id: string): Promise<DownloadedAttachment>;
|
|
36
|
+
/**
|
|
37
|
+
* Map a downloaded attachment to an MCP result. Image attachments are returned
|
|
38
|
+
* as a native `image` content block so clients can render them; everything else
|
|
39
|
+
* is returned as a text block carrying the filename, MIME type, and Base64 data.
|
|
40
|
+
*/
|
|
41
|
+
export declare function downloadAttachmentContent(file: DownloadedAttachment): ContentResult;
|
|
30
42
|
export declare function registerAttachmentTools(server: McpServer, client: FireflyClient): void;
|
|
31
43
|
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,aAAa,EAAiC,MAAM,eAAe,CAAC;AAIlF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,aAAa,CAAC,CAGxB;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAGjG;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3G,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAGhH;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAGzC;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAOzG;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CAanF;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA+HtF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { unwrapList, unwrapSingle, } from '../transform.js';
|
|
3
3
|
import { DELETE_ANNOTATIONS, READ_ANNOTATIONS, UPDATE_ANNOTATIONS, WRITE_ANNOTATIONS } from './_annotations.js';
|
|
4
|
-
import { defineTool } from './_helpers.js';
|
|
4
|
+
import { defineContentTool, defineTool } from './_helpers.js';
|
|
5
5
|
// ---- Attachment fetch + CRUD ----
|
|
6
6
|
export async function fetchAttachments(client, params) {
|
|
7
7
|
const response = await client.get('/attachments', { page: params.page, limit: params.limit });
|
|
@@ -28,7 +28,31 @@ export async function uploadAttachment(client, id, content) {
|
|
|
28
28
|
return { uploaded: true, id };
|
|
29
29
|
}
|
|
30
30
|
export async function downloadAttachment(client, id) {
|
|
31
|
-
|
|
31
|
+
const { data, contentType, filename } = await client.getBinary(`/attachments/${id}/download`);
|
|
32
|
+
return {
|
|
33
|
+
content_base64: data.toString('base64'),
|
|
34
|
+
content_type: contentType,
|
|
35
|
+
filename,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Map a downloaded attachment to an MCP result. Image attachments are returned
|
|
40
|
+
* as a native `image` content block so clients can render them; everything else
|
|
41
|
+
* is returned as a text block carrying the filename, MIME type, and Base64 data.
|
|
42
|
+
*/
|
|
43
|
+
export function downloadAttachmentContent(file) {
|
|
44
|
+
const mimeType = file.content_type.split(';')[0].trim();
|
|
45
|
+
if (mimeType.startsWith('image/')) {
|
|
46
|
+
return { content: [{ type: 'image', data: file.content_base64, mimeType }] };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: `filename: ${file.filename}\ncontent_type: ${file.content_type}\ncontent_base64: ${file.content_base64}`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
32
56
|
}
|
|
33
57
|
export function registerAttachmentTools(server, client) {
|
|
34
58
|
defineTool(server, 'get_attachments', {
|
|
@@ -100,13 +124,13 @@ export function registerAttachmentTools(server, client) {
|
|
|
100
124
|
},
|
|
101
125
|
annotations: WRITE_ANNOTATIONS,
|
|
102
126
|
}, ({ id, content_base64 }) => uploadAttachment(client, id, Buffer.from(content_base64, 'base64')));
|
|
103
|
-
|
|
127
|
+
defineContentTool(server, 'download_attachment', {
|
|
104
128
|
title: 'Download Attachment',
|
|
105
|
-
description: 'Download
|
|
129
|
+
description: 'Download a file attachment (such as an invoice, PDF, or image receipt) by its ID. Image attachments are returned as a rendered image; other files are returned as their filename, MIME content type, and Base64-encoded content. Use get_attachments to find valid IDs.',
|
|
106
130
|
inputSchema: {
|
|
107
131
|
id: z.string().describe('Attachment ID'),
|
|
108
132
|
},
|
|
109
133
|
annotations: READ_ANNOTATIONS,
|
|
110
|
-
}, ({ id }) => downloadAttachment(client, id));
|
|
134
|
+
}, async ({ id }) => downloadAttachmentContent(await downloadAttachment(client, id)));
|
|
111
135
|
}
|
|
112
136
|
//# sourceMappingURL=attachments.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAKL,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/budgets.d.ts
CHANGED
|
@@ -61,5 +61,6 @@ export declare function fetchTransactionsWithoutBudget(client: FireflyClient, pa
|
|
|
61
61
|
page?: number;
|
|
62
62
|
limit?: number;
|
|
63
63
|
}): Promise<UnwrappedList>;
|
|
64
|
+
export declare function clearBudgetsCache(): void;
|
|
64
65
|
export declare function registerBudgetTools(server: McpServer, client: FireflyClient): void;
|
|
65
66
|
//# sourceMappingURL=budgets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../../src/tools/budgets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../../src/tools/budgets.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/budgets.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
import { unwrapList, unwrapSingle, } from '../transform.js';
|
|
3
4
|
import { DELETE_ANNOTATIONS, READ_ANNOTATIONS, UPDATE_ANNOTATIONS, WRITE_ANNOTATIONS } from './_annotations.js';
|
|
4
|
-
import { dateSchema, defineTool } from './_helpers.js';
|
|
5
|
+
import { AUTOCOMPLETE_FETCH_LIMIT, AUTOCOMPLETE_MAX_SUGGESTIONS, createTtlCache, dateSchema, debugLog, defineTool, parseId, } from './_helpers.js';
|
|
5
6
|
export async function fetchBudgets(client, params) {
|
|
6
7
|
const response = await client.get('/budgets', { page: params.page, limit: params.limit });
|
|
7
8
|
return unwrapList(response);
|
|
@@ -68,6 +69,12 @@ export async function fetchTransactionsWithoutBudget(client, params) {
|
|
|
68
69
|
const response = await client.get('/budgets/transactions-without-budget', query);
|
|
69
70
|
return unwrapList(response);
|
|
70
71
|
}
|
|
72
|
+
// Module-scoped so the cache survives across the stateless HTTP requests autocomplete fires;
|
|
73
|
+
// keyed per identity inside the completion handler so one user never sees another's budgets.
|
|
74
|
+
const budgetsCache = createTtlCache();
|
|
75
|
+
export function clearBudgetsCache() {
|
|
76
|
+
budgetsCache.clear();
|
|
77
|
+
}
|
|
71
78
|
export function registerBudgetTools(server, client) {
|
|
72
79
|
defineTool(server, 'get_budgets', {
|
|
73
80
|
title: 'Get Budgets',
|
|
@@ -78,16 +85,32 @@ export function registerBudgetTools(server, client) {
|
|
|
78
85
|
},
|
|
79
86
|
annotations: READ_ANNOTATIONS,
|
|
80
87
|
}, ({ page, limit }) => fetchBudgets(client, { page: page, limit: limit }));
|
|
88
|
+
const budgetIdSchema = completable(z.string().describe('Budget ID — use get_budgets to find valid IDs'), async (value) => {
|
|
89
|
+
debugLog(`[Autocomplete] Budget search input: "${value}"`);
|
|
90
|
+
try {
|
|
91
|
+
const budgets = await budgetsCache.get(client.cacheKey(), () => fetchBudgets(client, { limit: AUTOCOMPLETE_FETCH_LIMIT }));
|
|
92
|
+
const suggestions = budgets.data
|
|
93
|
+
.map((b) => `${b.id} (${b.name ?? ''})`)
|
|
94
|
+
.filter((label) => label.toLowerCase().includes(value.toLowerCase()))
|
|
95
|
+
.slice(0, AUTOCOMPLETE_MAX_SUGGESTIONS);
|
|
96
|
+
debugLog(`[Autocomplete] Budget suggestions found: ${suggestions.length}`);
|
|
97
|
+
return suggestions;
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
debugLog('[Autocomplete Error - Budget]:', err);
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
81
104
|
defineTool(server, 'get_budget_limits', {
|
|
82
105
|
title: 'Get Budget Limits',
|
|
83
106
|
description: 'Get spending limits for a specific Firefly III budget, including how much has been spent against each limit. Optionally filter by date range (YYYY-MM-DD). Use get_budgets to find valid budget IDs.',
|
|
84
107
|
inputSchema: {
|
|
85
|
-
budgetId:
|
|
108
|
+
budgetId: budgetIdSchema,
|
|
86
109
|
start: dateSchema.optional().describe('Start date (YYYY-MM-DD)'),
|
|
87
110
|
end: dateSchema.optional().describe('End date (YYYY-MM-DD)'),
|
|
88
111
|
},
|
|
89
112
|
annotations: READ_ANNOTATIONS,
|
|
90
|
-
}, ({ budgetId, start, end }) => fetchBudgetLimits(client, budgetId, start, end));
|
|
113
|
+
}, ({ budgetId, start, end }) => fetchBudgetLimits(client, parseId(budgetId), start, end));
|
|
91
114
|
defineTool(server, 'create_budget', {
|
|
92
115
|
title: 'Create Budget',
|
|
93
116
|
description: 'Create a new budget in Firefly III.',
|
|
@@ -108,7 +131,7 @@ export function registerBudgetTools(server, client) {
|
|
|
108
131
|
title: 'Update Budget',
|
|
109
132
|
description: 'Update an existing budget in Firefly III. Only fields provided will be changed. Use get_budgets to find valid budget IDs.',
|
|
110
133
|
inputSchema: {
|
|
111
|
-
id:
|
|
134
|
+
id: budgetIdSchema,
|
|
112
135
|
name: z.string().optional().describe('Budget name'),
|
|
113
136
|
active: z.boolean().optional().describe('Whether the budget is active'),
|
|
114
137
|
auto_budget_type: z.enum(['reset', 'rollover', 'none']).optional().describe('Auto-budget type'),
|
|
@@ -120,18 +143,18 @@ export function registerBudgetTools(server, client) {
|
|
|
120
143
|
.describe('Auto-budget period'),
|
|
121
144
|
},
|
|
122
145
|
annotations: UPDATE_ANNOTATIONS,
|
|
123
|
-
}, ({ id, ...params }) => updateBudget(client, id, params));
|
|
146
|
+
}, ({ id, ...params }) => updateBudget(client, parseId(id), params));
|
|
124
147
|
defineTool(server, 'delete_budget', {
|
|
125
148
|
title: 'Delete Budget',
|
|
126
149
|
description: 'Permanently delete a budget from Firefly III. **This action cannot be undone.** Use get_budgets to confirm the ID before deleting.',
|
|
127
|
-
inputSchema: { id:
|
|
150
|
+
inputSchema: { id: budgetIdSchema },
|
|
128
151
|
annotations: DELETE_ANNOTATIONS,
|
|
129
|
-
}, ({ id }) => deleteBudget(client, id));
|
|
152
|
+
}, ({ id }) => deleteBudget(client, parseId(id)));
|
|
130
153
|
defineTool(server, 'create_budget_limit', {
|
|
131
154
|
title: 'Create Budget Limit',
|
|
132
155
|
description: 'Create a spending limit for a budget in Firefly III for a specific date range.',
|
|
133
156
|
inputSchema: {
|
|
134
|
-
budget_id:
|
|
157
|
+
budget_id: budgetIdSchema,
|
|
135
158
|
start: dateSchema.describe('Start date (YYYY-MM-DD)'),
|
|
136
159
|
end: dateSchema.describe('End date (YYYY-MM-DD)'),
|
|
137
160
|
amount: z.string().describe('Limit amount as a number string'),
|
|
@@ -142,7 +165,7 @@ export function registerBudgetTools(server, client) {
|
|
|
142
165
|
.describe('Budget period'),
|
|
143
166
|
},
|
|
144
167
|
annotations: WRITE_ANNOTATIONS,
|
|
145
|
-
}, ({ budget_id, ...params }) => createBudgetLimit(client, budget_id, params));
|
|
168
|
+
}, ({ budget_id, ...params }) => createBudgetLimit(client, parseId(budget_id), params));
|
|
146
169
|
defineTool(server, 'update_budget_limit', {
|
|
147
170
|
title: 'Update Budget Limit',
|
|
148
171
|
description: 'Update an existing budget limit in Firefly III. Only fields provided will be changed. Use get_budget_limits to find valid limit IDs.',
|
|
@@ -186,14 +209,14 @@ export function registerBudgetTools(server, client) {
|
|
|
186
209
|
title: 'Get Budget Transactions',
|
|
187
210
|
description: 'Get all transactions linked to a specific budget. Use get_budgets to find valid budget IDs.',
|
|
188
211
|
inputSchema: {
|
|
189
|
-
id:
|
|
212
|
+
id: budgetIdSchema,
|
|
190
213
|
start: dateSchema.optional().describe('Start date (YYYY-MM-DD)'),
|
|
191
214
|
end: dateSchema.optional().describe('End date (YYYY-MM-DD)'),
|
|
192
215
|
page: z.number().int().positive().optional().default(1).describe('Page number'),
|
|
193
216
|
limit: z.number().int().positive().max(100).optional().default(50).describe('Results per page (max 100)'),
|
|
194
217
|
},
|
|
195
218
|
annotations: READ_ANNOTATIONS,
|
|
196
|
-
}, ({ id, start, end, page, limit }) => fetchBudgetTransactions(client, id, { start, end, page, limit }));
|
|
219
|
+
}, ({ id, start, end, page, limit }) => fetchBudgetTransactions(client, parseId(id), { start, end, page, limit }));
|
|
197
220
|
defineTool(server, 'get_transactions_without_budget', {
|
|
198
221
|
title: 'Get Transactions Without Budget',
|
|
199
222
|
description: 'Get all transactions that have no budget assigned. Useful for finding unbudgeted spending.',
|
|
@@ -205,5 +228,26 @@ export function registerBudgetTools(server, client) {
|
|
|
205
228
|
},
|
|
206
229
|
annotations: READ_ANNOTATIONS,
|
|
207
230
|
}, (params) => fetchTransactionsWithoutBudget(client, params));
|
|
231
|
+
server.registerPrompt('budget-transactions', {
|
|
232
|
+
title: 'Get Transactions by Budget',
|
|
233
|
+
description: 'Get transactions for a specific budget with autocomplete.',
|
|
234
|
+
argsSchema: {
|
|
235
|
+
budget: budgetIdSchema,
|
|
236
|
+
},
|
|
237
|
+
}, async ({ budget }) => {
|
|
238
|
+
const id = parseId(budget);
|
|
239
|
+
return {
|
|
240
|
+
description: `Get transactions for budget ID ${id}`,
|
|
241
|
+
messages: [
|
|
242
|
+
{
|
|
243
|
+
role: 'user',
|
|
244
|
+
content: {
|
|
245
|
+
type: 'text',
|
|
246
|
+
text: `Show me the recent transactions for budget ID "${id}".`,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
};
|
|
251
|
+
});
|
|
208
252
|
}
|
|
209
253
|
//# sourceMappingURL=budgets.js.map
|