actual-mcp-server 0.6.42 → 0.6.44
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 +13 -12
- package/dist/package.json +6 -4
- package/dist/src/actualToolsManager.js +1 -0
- package/dist/src/lib/constants.js +1 -1
- package/dist/src/tools/entities_search.js +100 -0
- package/dist/src/tools/index.js +1 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -19,13 +19,13 @@ Actual MCP Server is a [Model Context Protocol](https://modelcontextprotocol.io/
|
|
|
19
19
|
┌─────────────┐ MCP/HTTP ┌──────────────────┐ Actual API ┌──────────────┐
|
|
20
20
|
│ LibreChat │ ◄───────────► │ Actual MCP │ ◄───────────► │ Actual │
|
|
21
21
|
│ LobeChat │ │ Server │ │ Budget │
|
|
22
|
-
│ (remote) │ │ (
|
|
22
|
+
│ (remote) │ │ (71 tools) │ │ Server │
|
|
23
23
|
└─────────────┘ └──────────────────┘ └──────────────┘
|
|
24
24
|
|
|
25
25
|
┌─────────────┐ MCP/stdio ┌──────────────────┐ Actual API ┌──────────────┐
|
|
26
26
|
│ Claude │ ◄───────────► │ Actual MCP │ ◄───────────► │ Actual │
|
|
27
27
|
│ Desktop │ │ Server │ │ Budget │
|
|
28
|
-
│ (local) │ │ (
|
|
28
|
+
│ (local) │ │ (71 tools) │ │ Server │
|
|
29
29
|
└─────────────┘ └──────────────────┘ └──────────────┘
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -33,14 +33,14 @@ Actual MCP Server is a [Model Context Protocol](https://modelcontextprotocol.io/
|
|
|
33
33
|
|
|
34
34
|
Most Actual Budget MCP implementations are simple stdio bridges designed for single-user, local use with Claude Desktop. This project goes further:
|
|
35
35
|
|
|
36
|
-
- **
|
|
36
|
+
- **71 tools, the most comprehensive coverage available.** Accounts, transactions, categories, payees, tags, notes, rules, budgets, batch operations, bank sync, and more. Covers 87% of the Actual Budget API.
|
|
37
37
|
- **HTTP and stdio transport.** Runs as a real remote server for LibreChat/LobeChat (`--http`), or as a direct local process for Claude Desktop (`--stdio`). No Docker or HTTP server is needed for local use.
|
|
38
38
|
- **6 exclusive ActualQL-powered tools.** Search and summarise transactions by month, amount, category, or payee using Actual Budget's native query engine. Aggregated results, no raw data dumped into the AI context window.
|
|
39
39
|
- **Multi-budget switching at runtime.** Configure multiple budget files and let the AI switch between them mid-conversation with `actual_budgets_switch`.
|
|
40
40
|
- **Multi-user ready with OIDC.** Secure every session with JWKS-validated JWTs and per-user budget ACLs. No shared tokens required.
|
|
41
41
|
- **Production-grade reliability.** Connection pooling (up to 15 concurrent sessions), automatic retry with exponential backoff, and a full test suite (unit + E2E + integration).
|
|
42
42
|
|
|
43
|
-
> **Verified working** with [LibreChat](https://www.librechat.ai/), [LobeChat](https://lobehub.com/home), and [Claude Desktop](https://claude.ai/download). All
|
|
43
|
+
> **Verified working** with [LibreChat](https://www.librechat.ai/), [LobeChat](https://lobehub.com/home), and [Claude Desktop](https://claude.ai/download). All 71 tools tested end-to-end. Any MCP-compatible client should work.
|
|
44
44
|
|
|
45
45
|
---
|
|
46
46
|
|
|
@@ -172,7 +172,7 @@ Add to `claude_desktop_config.json` (see [docs/guides/MCP_CLIENTS_SETUP.md](docs
|
|
|
172
172
|
}
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
> **No token needed.** stdio runs as a local process owned by your user. The transport itself is the security boundary. All
|
|
175
|
+
> **No token needed.** stdio runs as a local process owned by your user. The transport itself is the security boundary. All 71 tools are available.
|
|
176
176
|
>
|
|
177
177
|
> **`MCP_BRIDGE_DATA_DIR` should be an absolute path.** Without one, the data directory resolves relative to wherever the client spawns the process, which can be unpredictable. The directory is created automatically on first run.
|
|
178
178
|
|
|
@@ -282,7 +282,7 @@ For Claude Desktop (stdio), restart Claude after upgrading.
|
|
|
282
282
|
|
|
283
283
|
## Available Tools
|
|
284
284
|
|
|
285
|
-
**
|
|
285
|
+
**71 tools** across 12 categories. All tools use the `actual_<category>_<action>` naming convention.
|
|
286
286
|
|
|
287
287
|
### Accounts (7)
|
|
288
288
|
|
|
@@ -396,13 +396,14 @@ For Claude Desktop (stdio), restart Claude after upgrading.
|
|
|
396
396
|
|
|
397
397
|
`actual_budget_updates_batch`: batch multiple budget updates in one call
|
|
398
398
|
|
|
399
|
-
### Server Information & Lookup (
|
|
399
|
+
### Server Information & Lookup (4)
|
|
400
400
|
|
|
401
401
|
| Tool | Description |
|
|
402
402
|
|------|-------------|
|
|
403
403
|
| `actual_server_info` | Server status, version, build info |
|
|
404
404
|
| `actual_server_get_version` | Actual Budget server version |
|
|
405
|
-
| `actual_get_id_by_name` | Resolve name → UUID for accounts, categories, payees |
|
|
405
|
+
| `actual_get_id_by_name` | Resolve an exact name → UUID for accounts, categories, payees |
|
|
406
|
+
| `actual_entities_search` | Find accounts/categories/payees by a name pattern (contains/startsWith/endsWith/exact/fuzzy). Fixes "payee not found" from a partial or mistyped name |
|
|
406
407
|
|
|
407
408
|
### Session Management (2)
|
|
408
409
|
|
|
@@ -528,7 +529,7 @@ stdio is the simplest way to connect Claude Desktop directly to Actual Budget. T
|
|
|
528
529
|
- No auth token. Process ownership is the security boundary.
|
|
529
530
|
- All logs go to stderr so they never corrupt the JSON-RPC framing on stdout
|
|
530
531
|
- The process exits when stdin closes (Claude Desktop shutting down)
|
|
531
|
-
- All
|
|
532
|
+
- All 71 tools are available, identical to HTTP mode
|
|
532
533
|
|
|
533
534
|
**Start manually to verify:**
|
|
534
535
|
|
|
@@ -605,7 +606,7 @@ See [AI Client Setup, OIDC](docs/guides/AI_CLIENT_SETUP.md#oidc-authentication-m
|
|
|
605
606
|
| Command | What It Tests | Requires Live Server |
|
|
606
607
|
|---------|---------------|---------------------|
|
|
607
608
|
| `npm run build` | TypeScript compilation | No |
|
|
608
|
-
| `npm run test:unit-js` |
|
|
609
|
+
| `npm run test:unit-js` | 71-tool smoke, schema validation, auth ACL | No |
|
|
609
610
|
| `npm run test:adapter` | Adapter, retry logic, concurrency | No |
|
|
610
611
|
| `npm run test:e2e` | MCP protocol compliance (Playwright) | No |
|
|
611
612
|
| `npm run test:e2e:docker:full` | Full stack integration | Yes (Docker) |
|
|
@@ -647,7 +648,7 @@ Several MCP servers exist for personal finance management. Here's how this proje
|
|
|
647
648
|
| **Version** | v0.4.26 | v1.11.1 | v0.2.0 | v0.1.0 |
|
|
648
649
|
| **Budget App** | Actual Budget (self-hosted) | Actual Budget (self-hosted) | Actual Budget (self-hosted) | YNAB (cloud, subscription) |
|
|
649
650
|
| **Language** | TypeScript / Node.js | TypeScript / Node.js | TypeScript / Node.js | Python |
|
|
650
|
-
| **Tool Count** | **
|
|
651
|
+
| **Tool Count** | **71** | ~22 | 18 | 9 |
|
|
651
652
|
| **Setup & Distribution** |||||
|
|
652
653
|
| **Transport** | HTTP + stdio | STDIO + SSE option | STDIO | STDIO |
|
|
653
654
|
| **Docker support** | ✅ Full (image + Compose) | ✅ Image only | ❌ | ❌ |
|
|
@@ -750,4 +751,4 @@ The software is provided **as-is**, without warranty of any kind. The author acc
|
|
|
750
751
|
|
|
751
752
|
---
|
|
752
753
|
|
|
753
|
-
**Version:** 0.6.
|
|
754
|
+
**Version:** 0.6.44 | **Tool Count:** 71 (verified LibreChat-compatible)
|
package/dist/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actual-mcp-server",
|
|
3
3
|
"displayName": "Actual MCP Server",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.44",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0",
|
|
7
7
|
"npm": ">=10.0.0"
|
|
8
8
|
},
|
|
9
|
-
"description": "MCP server with
|
|
9
|
+
"description": "MCP server with 71 tools for AI-driven financial management with Actual Budget. HTTP and stdio transports for LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
|
|
10
10
|
"homepage": "https://github.com/agigante80/actual-mcp-server#readme",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"verify-tools": "npm run build && node scripts/verify-tools.js",
|
|
31
31
|
"check:coverage": "node scripts/list-actual-api-methods.mjs",
|
|
32
32
|
"direct-sync": "node scripts/direct-sync/bank-sync-direct.mjs",
|
|
33
|
-
"test:unit-js": "node tests/unit/transactions_create.test.js && node tests/unit/generated_tools.smoke.test.js && node tests/unit/schema_validation.test.js && node tests/unit/config_https_validation.test.js && node tests/unit/config_insecure_upstream.test.js && node tests/unit/auth-acl.test.js && node tests/unit/bug76.test.js && node tests/unit/budgets_setAmount.test.js && node tests/unit/budgets_transfer.test.js && node tests/unit/transactions_uncategorized.test.js && node tests/unit/httpServer_session_init.test.js && node tests/unit/httpServer_session_not_found.test.js && node tests/unit/manual_mcp_client_retry.test.js && node tests/unit/manual_mcp_client_session.test.js && node tests/unit/manual_mcp_client_circuit.test.js && node tests/unit/manual_runner_killswitch.test.js && node tests/unit/adapter_auth_rate_limit.test.js && node tests/unit/adapter_session_reuse.test.js && node tests/unit/retry_classifier.test.js && node tests/unit/adapter_module_surface.test.js && node tests/unit/adapter_nonidempotent_no_retry.test.js && node tests/unit/pool_liveness.test.js && node tests/unit/pool_shutdown_all.test.js && node tests/unit/query_where_operators.test.js && node tests/unit/query_run_validation.test.js && node tests/unit/adapter_with_write_session.test.js && node tests/unit/category_groups_delete.test.js && node tests/unit/rules_delete.test.js && node tests/unit/schedules_delete.test.js && node tests/unit/payees_delete.test.js && node tests/unit/rules_create_or_update.test.js && node tests/unit/unhandled-rejection.test.js && node tests/unit/rejection-allowlist-purity.test.js && node tests/unit/httpServer_bearer_auth.test.js && node tests/unit/httpServer_oidc_audience.test.js && node tests/unit/httpServer_oidc_auth_verification.test.js && node tests/unit/httpServer_body_limit.test.js && node tests/unit/adapter_write_pool_cooperation.test.js && node tests/unit/budget_acl_enforcement.test.js && node tests/unit/budget_preference_store.test.js && node tests/unit/budget_preference_restore.test.js && node tests/unit/tags_list.test.js && node tests/unit/tags_create.test.js && node tests/unit/tags_update.test.js && node tests/unit/tags_delete.test.js && node tests/unit/notes_get.test.js && node tests/unit/notes_update.test.js && node tests/unit/payees_common_list.test.js && node tests/unit/transactions_update_guard.test.js && node tests/unit/check_coverage.test.js",
|
|
33
|
+
"test:unit-js": "node tests/unit/transactions_create.test.js && node tests/unit/generated_tools.smoke.test.js && node tests/unit/schema_validation.test.js && node tests/unit/config_https_validation.test.js && node tests/unit/config_insecure_upstream.test.js && node tests/unit/auth-acl.test.js && node tests/unit/bug76.test.js && node tests/unit/budgets_setAmount.test.js && node tests/unit/budgets_transfer.test.js && node tests/unit/transactions_uncategorized.test.js && node tests/unit/httpServer_session_init.test.js && node tests/unit/httpServer_session_not_found.test.js && node tests/unit/manual_mcp_client_retry.test.js && node tests/unit/manual_mcp_client_session.test.js && node tests/unit/manual_mcp_client_circuit.test.js && node tests/unit/manual_runner_killswitch.test.js && node tests/unit/adapter_auth_rate_limit.test.js && node tests/unit/adapter_session_reuse.test.js && node tests/unit/retry_classifier.test.js && node tests/unit/adapter_module_surface.test.js && node tests/unit/adapter_nonidempotent_no_retry.test.js && node tests/unit/pool_liveness.test.js && node tests/unit/pool_shutdown_all.test.js && node tests/unit/query_where_operators.test.js && node tests/unit/query_run_validation.test.js && node tests/unit/adapter_with_write_session.test.js && node tests/unit/category_groups_delete.test.js && node tests/unit/rules_delete.test.js && node tests/unit/schedules_delete.test.js && node tests/unit/payees_delete.test.js && node tests/unit/rules_create_or_update.test.js && node tests/unit/unhandled-rejection.test.js && node tests/unit/rejection-allowlist-purity.test.js && node tests/unit/httpServer_bearer_auth.test.js && node tests/unit/httpServer_oidc_audience.test.js && node tests/unit/httpServer_oidc_auth_verification.test.js && node tests/unit/httpServer_body_limit.test.js && node tests/unit/adapter_write_pool_cooperation.test.js && node tests/unit/budget_acl_enforcement.test.js && node tests/unit/budget_preference_store.test.js && node tests/unit/budget_preference_restore.test.js && node tests/unit/tags_list.test.js && node tests/unit/tags_create.test.js && node tests/unit/tags_update.test.js && node tests/unit/tags_delete.test.js && node tests/unit/notes_get.test.js && node tests/unit/notes_update.test.js && node tests/unit/payees_common_list.test.js && node tests/unit/transactions_update_guard.test.js && node tests/unit/entities_search.test.js && node tests/unit/tool_count_sync.test.js && node tests/unit/check_coverage.test.js",
|
|
34
34
|
"test:adapter": "npm run build && node dist/src/tests_adapter_runner.js",
|
|
35
35
|
"test:e2e": "npx playwright test",
|
|
36
36
|
"test:e2e:docker": "./tests/e2e/run-docker-e2e.sh",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"version:check": "node scripts/version-check.js",
|
|
55
55
|
"release:major": "npm run version:bump -- major",
|
|
56
56
|
"release:minor": "npm run version:bump -- minor",
|
|
57
|
-
"release:patch": "npm run version:bump -- patch"
|
|
57
|
+
"release:patch": "npm run version:bump -- patch",
|
|
58
|
+
"tool-count": "node scripts/tool-count.mjs"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
61
|
"@actual-app/api": "^26.6.0",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"debug": "^4.4.3",
|
|
63
64
|
"dotenv": "^17.4.2",
|
|
64
65
|
"express": "^5.2.1",
|
|
66
|
+
"fuse.js": "^7.4.2",
|
|
65
67
|
"jose": "^6.2.3",
|
|
66
68
|
"mcp-auth": "^0.2.0",
|
|
67
69
|
"winston": "^3.18.3",
|
|
@@ -75,7 +75,7 @@ export const DEFAULT_HTTP_PATH = '/';
|
|
|
75
75
|
*/
|
|
76
76
|
export const SERVER_INFO = {
|
|
77
77
|
name: 'actual-budget-mcp',
|
|
78
|
-
description: 'MCP server for Actual Budget -
|
|
78
|
+
description: 'MCP server for Actual Budget - 71 tools for finance management',
|
|
79
79
|
};
|
|
80
80
|
// ============================================================================
|
|
81
81
|
// VALIDATION & LIMITS
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import Fuse from 'fuse.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { createTool } from '../lib/toolFactory.js';
|
|
4
|
+
import adapter from '../lib/actual-adapter.js';
|
|
5
|
+
/**
|
|
6
|
+
* actual_entities_search (#204)
|
|
7
|
+
*
|
|
8
|
+
* Find payees, categories, or accounts by a NAME pattern, so an AI can resolve a
|
|
9
|
+
* partial or mistyped name (the common "payee not found" failure) without knowing
|
|
10
|
+
* the exact string. Read-only.
|
|
11
|
+
*
|
|
12
|
+
* matchType: contains (default) | startsWith | endsWith | exact are case-insensitive
|
|
13
|
+
* native string ops; fuzzy is typo-tolerant via Fuse.js (a maintained, zero-dependency
|
|
14
|
+
* library, chosen over a hand-rolled Levenshtein). Regex is intentionally out of scope
|
|
15
|
+
* (separate Phase 2 ticket: ReDoS attack surface).
|
|
16
|
+
*
|
|
17
|
+
* On no match the tool returns `{ matches: [], count: 0 }` (never an error): an empty
|
|
18
|
+
* result is a valid "found nothing" signal that lets the AI retry with a broader
|
|
19
|
+
* matchType (e.g. switch `contains` to `fuzzy`).
|
|
20
|
+
*/
|
|
21
|
+
const ENTITY_TYPES = ['accounts', 'categories', 'payees'];
|
|
22
|
+
const FETCH = {
|
|
23
|
+
accounts: () => adapter.getAccounts(),
|
|
24
|
+
categories: () => adapter.getCategories(),
|
|
25
|
+
payees: () => adapter.getPayees(),
|
|
26
|
+
};
|
|
27
|
+
const schema = z.object({
|
|
28
|
+
type: z.enum(ENTITY_TYPES).describe('Entity type to search: accounts, categories, or payees.'),
|
|
29
|
+
query: z
|
|
30
|
+
.union([z.string().trim().min(1), z.array(z.string().trim().min(1)).min(1)])
|
|
31
|
+
.describe('Name pattern to match. A single string, or an array of strings (matches if ANY pattern matches).'),
|
|
32
|
+
matchType: z
|
|
33
|
+
.enum(['contains', 'startsWith', 'endsWith', 'exact', 'fuzzy'])
|
|
34
|
+
.default('contains')
|
|
35
|
+
.describe('contains (default), startsWith, endsWith, exact (all case-insensitive), or fuzzy (typo-tolerant). Regex is not supported.'),
|
|
36
|
+
limit: z.number().int().min(1).max(100).default(10).describe('Maximum number of matches to return (1 to 100, default 10).'),
|
|
37
|
+
});
|
|
38
|
+
export default createTool({
|
|
39
|
+
name: 'actual_entities_search',
|
|
40
|
+
description: 'Find accounts, categories, or payees by a name pattern. Use this to resolve a partial or mistyped name to its entity (the fix for "payee not found"). ' +
|
|
41
|
+
'matchType: contains (default), startsWith, endsWith, exact (all case-insensitive), or fuzzy (typo-tolerant, e.g. "amzon" matches "Amazon.com"). ' +
|
|
42
|
+
'query may be a single string or an array (matches if ANY matches). Read-only. ' +
|
|
43
|
+
'On no match it returns { matches: [], count: 0 } (not an error): retry with a broader matchType such as fuzzy.',
|
|
44
|
+
schema,
|
|
45
|
+
examples: [
|
|
46
|
+
{ description: 'Find the payee for a partial name', input: { type: 'payees', query: 'amazon', matchType: 'contains', limit: 10 } },
|
|
47
|
+
{ description: 'Typo-tolerant payee lookup', input: { type: 'payees', query: 'amzon', matchType: 'fuzzy', limit: 10 } },
|
|
48
|
+
{ description: 'Categories starting with "Gro"', input: { type: 'categories', query: 'gro', matchType: 'startsWith', limit: 10 } },
|
|
49
|
+
],
|
|
50
|
+
handler: async (input) => {
|
|
51
|
+
const { type, matchType, limit } = input;
|
|
52
|
+
const patterns = (Array.isArray(input.query) ? input.query : [input.query]).map((p) => p.trim());
|
|
53
|
+
const raw = (await FETCH[type]());
|
|
54
|
+
// Only entities with a usable string name can be matched (some payees have null names).
|
|
55
|
+
const entities = raw.filter((e) => typeof e?.name === 'string' && e.name.length > 0);
|
|
56
|
+
let matches;
|
|
57
|
+
if (matchType === 'fuzzy') {
|
|
58
|
+
const fuse = new Fuse(entities, {
|
|
59
|
+
keys: ['name'],
|
|
60
|
+
includeScore: true,
|
|
61
|
+
threshold: 0.4,
|
|
62
|
+
ignoreLocation: true,
|
|
63
|
+
minMatchCharLength: 1,
|
|
64
|
+
});
|
|
65
|
+
// Multi-pattern OR: search each pattern, keep the best (lowest) score per entity.
|
|
66
|
+
const bestById = new Map();
|
|
67
|
+
for (const pattern of patterns) {
|
|
68
|
+
for (const r of fuse.search(pattern)) {
|
|
69
|
+
const score = typeof r.score === 'number' ? r.score : 1;
|
|
70
|
+
const prev = bestById.get(r.item.id);
|
|
71
|
+
if (!prev || score < (prev.score ?? 1)) {
|
|
72
|
+
bestById.set(r.item.id, { id: r.item.id, name: r.item.name, score: Math.round(score * 1000) / 1000 });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
matches = [...bestById.values()].sort((a, b) => (a.score ?? 1) - (b.score ?? 1));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const needles = patterns.map((p) => p.toLowerCase());
|
|
80
|
+
const test = (name) => {
|
|
81
|
+
const n = name.toLowerCase();
|
|
82
|
+
return needles.some((q) => {
|
|
83
|
+
switch (matchType) {
|
|
84
|
+
case 'startsWith': return n.startsWith(q);
|
|
85
|
+
case 'endsWith': return n.endsWith(q);
|
|
86
|
+
case 'exact': return n === q;
|
|
87
|
+
case 'contains':
|
|
88
|
+
default: return n.includes(q);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
matches = entities
|
|
93
|
+
.filter((e) => test(e.name))
|
|
94
|
+
.map((e) => ({ id: e.id, name: e.name }))
|
|
95
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
96
|
+
}
|
|
97
|
+
const limited = matches.slice(0, limit);
|
|
98
|
+
return { matches: limited, count: limited.length, type, matchType };
|
|
99
|
+
},
|
|
100
|
+
});
|
package/dist/src/tools/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Auto-generated index for all tool modules
|
|
2
|
+
export { default as entities_search } from './entities_search.js';
|
|
2
3
|
export { default as accounts_close } from './accounts_close.js';
|
|
3
4
|
export { default as accounts_create } from './accounts_create.js';
|
|
4
5
|
export { default as accounts_delete } from './accounts_delete.js';
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actual-mcp-server",
|
|
3
3
|
"displayName": "Actual MCP Server",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.44",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0",
|
|
7
7
|
"npm": ">=10.0.0"
|
|
8
8
|
},
|
|
9
|
-
"description": "MCP server with
|
|
9
|
+
"description": "MCP server with 71 tools for AI-driven financial management with Actual Budget. HTTP and stdio transports for LibreChat, Claude Desktop, Cursor, VS Code, Gemini CLI",
|
|
10
10
|
"homepage": "https://github.com/agigante80/actual-mcp-server#readme",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"verify-tools": "npm run build && node scripts/verify-tools.js",
|
|
31
31
|
"check:coverage": "node scripts/list-actual-api-methods.mjs",
|
|
32
32
|
"direct-sync": "node scripts/direct-sync/bank-sync-direct.mjs",
|
|
33
|
-
"test:unit-js": "node tests/unit/transactions_create.test.js && node tests/unit/generated_tools.smoke.test.js && node tests/unit/schema_validation.test.js && node tests/unit/config_https_validation.test.js && node tests/unit/config_insecure_upstream.test.js && node tests/unit/auth-acl.test.js && node tests/unit/bug76.test.js && node tests/unit/budgets_setAmount.test.js && node tests/unit/budgets_transfer.test.js && node tests/unit/transactions_uncategorized.test.js && node tests/unit/httpServer_session_init.test.js && node tests/unit/httpServer_session_not_found.test.js && node tests/unit/manual_mcp_client_retry.test.js && node tests/unit/manual_mcp_client_session.test.js && node tests/unit/manual_mcp_client_circuit.test.js && node tests/unit/manual_runner_killswitch.test.js && node tests/unit/adapter_auth_rate_limit.test.js && node tests/unit/adapter_session_reuse.test.js && node tests/unit/retry_classifier.test.js && node tests/unit/adapter_module_surface.test.js && node tests/unit/adapter_nonidempotent_no_retry.test.js && node tests/unit/pool_liveness.test.js && node tests/unit/pool_shutdown_all.test.js && node tests/unit/query_where_operators.test.js && node tests/unit/query_run_validation.test.js && node tests/unit/adapter_with_write_session.test.js && node tests/unit/category_groups_delete.test.js && node tests/unit/rules_delete.test.js && node tests/unit/schedules_delete.test.js && node tests/unit/payees_delete.test.js && node tests/unit/rules_create_or_update.test.js && node tests/unit/unhandled-rejection.test.js && node tests/unit/rejection-allowlist-purity.test.js && node tests/unit/httpServer_bearer_auth.test.js && node tests/unit/httpServer_oidc_audience.test.js && node tests/unit/httpServer_oidc_auth_verification.test.js && node tests/unit/httpServer_body_limit.test.js && node tests/unit/adapter_write_pool_cooperation.test.js && node tests/unit/budget_acl_enforcement.test.js && node tests/unit/budget_preference_store.test.js && node tests/unit/budget_preference_restore.test.js && node tests/unit/tags_list.test.js && node tests/unit/tags_create.test.js && node tests/unit/tags_update.test.js && node tests/unit/tags_delete.test.js && node tests/unit/notes_get.test.js && node tests/unit/notes_update.test.js && node tests/unit/payees_common_list.test.js && node tests/unit/transactions_update_guard.test.js && node tests/unit/check_coverage.test.js",
|
|
33
|
+
"test:unit-js": "node tests/unit/transactions_create.test.js && node tests/unit/generated_tools.smoke.test.js && node tests/unit/schema_validation.test.js && node tests/unit/config_https_validation.test.js && node tests/unit/config_insecure_upstream.test.js && node tests/unit/auth-acl.test.js && node tests/unit/bug76.test.js && node tests/unit/budgets_setAmount.test.js && node tests/unit/budgets_transfer.test.js && node tests/unit/transactions_uncategorized.test.js && node tests/unit/httpServer_session_init.test.js && node tests/unit/httpServer_session_not_found.test.js && node tests/unit/manual_mcp_client_retry.test.js && node tests/unit/manual_mcp_client_session.test.js && node tests/unit/manual_mcp_client_circuit.test.js && node tests/unit/manual_runner_killswitch.test.js && node tests/unit/adapter_auth_rate_limit.test.js && node tests/unit/adapter_session_reuse.test.js && node tests/unit/retry_classifier.test.js && node tests/unit/adapter_module_surface.test.js && node tests/unit/adapter_nonidempotent_no_retry.test.js && node tests/unit/pool_liveness.test.js && node tests/unit/pool_shutdown_all.test.js && node tests/unit/query_where_operators.test.js && node tests/unit/query_run_validation.test.js && node tests/unit/adapter_with_write_session.test.js && node tests/unit/category_groups_delete.test.js && node tests/unit/rules_delete.test.js && node tests/unit/schedules_delete.test.js && node tests/unit/payees_delete.test.js && node tests/unit/rules_create_or_update.test.js && node tests/unit/unhandled-rejection.test.js && node tests/unit/rejection-allowlist-purity.test.js && node tests/unit/httpServer_bearer_auth.test.js && node tests/unit/httpServer_oidc_audience.test.js && node tests/unit/httpServer_oidc_auth_verification.test.js && node tests/unit/httpServer_body_limit.test.js && node tests/unit/adapter_write_pool_cooperation.test.js && node tests/unit/budget_acl_enforcement.test.js && node tests/unit/budget_preference_store.test.js && node tests/unit/budget_preference_restore.test.js && node tests/unit/tags_list.test.js && node tests/unit/tags_create.test.js && node tests/unit/tags_update.test.js && node tests/unit/tags_delete.test.js && node tests/unit/notes_get.test.js && node tests/unit/notes_update.test.js && node tests/unit/payees_common_list.test.js && node tests/unit/transactions_update_guard.test.js && node tests/unit/entities_search.test.js && node tests/unit/tool_count_sync.test.js && node tests/unit/check_coverage.test.js",
|
|
34
34
|
"test:adapter": "npm run build && node dist/src/tests_adapter_runner.js",
|
|
35
35
|
"test:e2e": "npx playwright test",
|
|
36
36
|
"test:e2e:docker": "./tests/e2e/run-docker-e2e.sh",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"version:check": "node scripts/version-check.js",
|
|
55
55
|
"release:major": "npm run version:bump -- major",
|
|
56
56
|
"release:minor": "npm run version:bump -- minor",
|
|
57
|
-
"release:patch": "npm run version:bump -- patch"
|
|
57
|
+
"release:patch": "npm run version:bump -- patch",
|
|
58
|
+
"tool-count": "node scripts/tool-count.mjs"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
61
|
"@actual-app/api": "^26.6.0",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"debug": "^4.4.3",
|
|
63
64
|
"dotenv": "^17.4.2",
|
|
64
65
|
"express": "^5.2.1",
|
|
66
|
+
"fuse.js": "^7.4.2",
|
|
65
67
|
"jose": "^6.2.3",
|
|
66
68
|
"mcp-auth": "^0.2.0",
|
|
67
69
|
"winston": "^3.18.3",
|