actual-mcp-server 0.5.6 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,7 @@ Most Actual Budget MCP implementations are simple stdio bridges designed for sin
47
47
  ## Table of Contents
48
48
 
49
49
  - [Quick Start](#quick-start)
50
+ - [Upgrading](#upgrading)
50
51
  - [Available Tools](#available-tools)
51
52
  - [Configuration](#configuration)
52
53
  - [Multi-Budget Switching](#multi-budget-switching)
@@ -234,6 +235,51 @@ See [docs/guides/MCP_CLIENTS_SETUP.md](docs/guides/MCP_CLIENTS_SETUP.md) for all
234
235
 
235
236
  ---
236
237
 
238
+ ## Upgrading
239
+
240
+ ### Docker (Option A)
241
+
242
+ ```bash
243
+ docker pull ghcr.io/agigante80/actual-mcp-server:latest
244
+ docker stop actual-mcp-server-backend
245
+ docker rm actual-mcp-server-backend
246
+ # Re-run the original docker run command with the same flags and volumes
247
+ ```
248
+
249
+ Also available on Docker Hub: `docker pull agigante80/actual-mcp-server:latest`
250
+
251
+ ### Docker Compose (Option B)
252
+
253
+ ```bash
254
+ docker compose pull
255
+ docker compose --profile production up -d
256
+ ```
257
+
258
+ ### npm / cloned repo (Option C)
259
+
260
+ ```bash
261
+ git pull
262
+ npm install
263
+ npm run build
264
+ # Then restart the server
265
+ ```
266
+
267
+ ### npx / stdio (Options C & D)
268
+
269
+ If you run `npx actual-mcp-server` without a globally installed version, npx fetches the latest from the registry automatically. But if you previously installed it globally (`npm install -g actual-mcp-server`), the global install takes precedence — you must upgrade it explicitly:
270
+
271
+ ```bash
272
+ # Upgrade the global install
273
+ npm install -g actual-mcp-server
274
+
275
+ # Or force the registry version without touching your global install
276
+ npx actual-mcp-server@latest --http
277
+ ```
278
+
279
+ For Claude Desktop (stdio), restart Claude after upgrading.
280
+
281
+ ---
282
+
237
283
  ## Available Tools
238
284
 
239
285
  **63 tools** across 12 categories. All tools use the `actual_<category>_<action>` naming convention.
@@ -678,4 +724,4 @@ The software is provided **as-is**, without warranty of any kind. The author acc
678
724
 
679
725
  ---
680
726
 
681
- **Version:** 0.5.6 | **Tool Count:** 63 (verified LibreChat-compatible)
727
+ **Version:** 0.5.8 | **Tool Count:** 63 (verified LibreChat-compatible)
package/dist/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "actual-mcp-server",
3
3
  "displayName": "Actual MCP Server",
4
- "version": "0.5.6",
4
+ "version": "0.5.8",
5
5
  "engines": {
6
6
  "node": ">=20.0.0",
7
7
  "npm": ">=10.0.0"
8
8
  },
9
- "description": "MCP server with 62 tools for AI-driven financial management with Actual Budget — HTTP and stdio transports, LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
9
+ "description": "MCP server with 63 tools for AI-driven financial management with Actual Budget — HTTP and stdio transports, LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
10
+ "homepage": "https://github.com/agigante80/actual-mcp-server#readme",
10
11
  "repository": {
11
12
  "type": "git",
12
13
  "url": "https://github.com/agigante80/actual-mcp-server"
package/dist/src/index.js CHANGED
@@ -89,6 +89,22 @@ if (unknownFlags.length > 0) {
89
89
  console.error(`Unknown option: ${unknownFlags.join(', ')}\nRun \`actual-mcp-server --help\` for usage.`);
90
90
  process.exit(1);
91
91
  }
92
+ // Early transport mode check — before dotenv and dynamic imports.
93
+ // Without this, the config validation error fires first and confuses users who
94
+ // simply forgot to pass --http or --stdio.
95
+ if (!argsEarly.includes('--http') &&
96
+ !argsEarly.includes('--stdio') &&
97
+ !argsEarly.includes('--test-actual-connection') &&
98
+ !argsEarly.includes('--test-mcp-client') &&
99
+ !argsEarly.includes('--help') && !argsEarly.includes('-h') &&
100
+ !argsEarly.includes('--version') && !argsEarly.includes('-v')) {
101
+ console.error('No transport mode specified.\n\n' +
102
+ 'Usage:\n' +
103
+ ' actual-mcp-server --http # HTTP server (LibreChat / LobeChat / multi-user)\n' +
104
+ ' actual-mcp-server --stdio # stdio transport (Claude Desktop / Claude Code)\n\n' +
105
+ 'Run actual-mcp-server --help for all options.\n');
106
+ process.exit(1);
107
+ }
92
108
  if (argsEarly.includes('--help') || argsEarly.includes('-h') ||
93
109
  argsEarly.includes('--version') || argsEarly.includes('-v')) {
94
110
  const pkg = await import('../package.json', { with: { type: 'json' } });
@@ -22,7 +22,7 @@ const InputSchema = z.object({
22
22
  });
23
23
  const tool = {
24
24
  name: 'actual_transactions_uncategorized',
25
- description: 'List uncategorized transactions (category is null/unset). Useful for cleanup workflows and rule-suggestion prompts. Defaults to the current month unless a date range is provided. Returns { transactions, count, summary: { totalAmount }, dateRange }.',
25
+ description: 'List uncategorized transactions (category is null/unset). Excludes transfers, split-transaction parents, opening balance entries, off-budget accounts, and closed accounts — matching Actual Budget\'s own Uncategorized view. Defaults to the current month unless a date range is provided. Returns { transactions, count, summary: { totalAmount }, dateRange }.',
26
26
  inputSchema: InputSchema,
27
27
  call: async (args, _meta) => {
28
28
  const input = InputSchema.parse(args || {});
@@ -38,17 +38,21 @@ const tool = {
38
38
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
39
  const txnRaw = await adapter.getTransactions(accountId, startDate, endDate);
40
40
  const txns = Array.isArray(txnRaw) ? txnRaw : [];
41
- // Fetch accounts to build off-budget exclusion set.
41
+ // Fetch accounts to build exclusion set: off-budget + closed accounts.
42
42
  const accounts = await adapter.getAccounts();
43
- const offBudgetIds = new Set(
43
+ const excludedAccountIds = new Set(
44
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
45
  (Array.isArray(accounts) ? accounts : [])
46
- .filter((acc) => acc?.offbudget === true)
46
+ .filter((acc) => acc?.offbudget === true || acc?.closed === true)
47
47
  .map((acc) => acc.id));
48
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
49
  const uncategorized = txns.filter(
50
50
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
- (txn) => txn?.category == null && !offBudgetIds.has(txn?.account));
51
+ (txn) => txn?.category == null &&
52
+ txn?.transfer_id == null &&
53
+ txn?.is_parent !== true &&
54
+ txn?.starting_balance_flag !== true &&
55
+ !excludedAccountIds.has(txn?.account));
52
56
  const limited = uncategorized.slice(0, input.limit ?? 500);
53
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
58
  const totalAmount = limited.reduce((sum, txn) => {
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "actual-mcp-server",
3
3
  "displayName": "Actual MCP Server",
4
- "version": "0.5.6",
4
+ "version": "0.5.8",
5
5
  "engines": {
6
6
  "node": ">=20.0.0",
7
7
  "npm": ">=10.0.0"
8
8
  },
9
- "description": "MCP server with 62 tools for AI-driven financial management with Actual Budget — HTTP and stdio transports, LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
9
+ "description": "MCP server with 63 tools for AI-driven financial management with Actual Budget — HTTP and stdio transports, LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
10
+ "homepage": "https://github.com/agigante80/actual-mcp-server#readme",
10
11
  "repository": {
11
12
  "type": "git",
12
13
  "url": "https://github.com/agigante80/actual-mcp-server"