moneymanager-mcp 0.2.0__tar.gz

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.
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ lint:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: '3.12'
15
+ cache: pip
16
+ - run: |
17
+ python -m pip install 'mcp>=1.2' 'moneymanager-parser>=0.2' build mypy pytest pytest-cov ruff
18
+ python -m pip install --no-deps -e .
19
+ - run: ruff check .
20
+ - run: ruff format --check .
21
+ typecheck:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: '3.12'
28
+ cache: pip
29
+ - run: |
30
+ python -m pip install 'mcp>=1.2' 'moneymanager-parser>=0.2' build mypy pytest pytest-cov ruff
31
+ python -m pip install --no-deps -e .
32
+ - run: mypy src
33
+ test:
34
+ runs-on: ubuntu-latest
35
+ strategy:
36
+ matrix:
37
+ python-version: ['3.10', '3.11', '3.12', '3.13']
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - uses: actions/setup-python@v5
41
+ with:
42
+ python-version: ${{ matrix.python-version }}
43
+ cache: pip
44
+ - run: |
45
+ python -m pip install 'mcp>=1.2' 'moneymanager-parser>=0.2' build mypy pytest pytest-cov ruff
46
+ python -m pip install --no-deps -e .
47
+ - run: pytest --cov --cov-report=term-missing --cov-report=xml
48
+ - name: Coverage summary
49
+ run: |
50
+ python - <<'PY' >> "$GITHUB_STEP_SUMMARY"
51
+ import xml.etree.ElementTree as ET
52
+ root = ET.parse('coverage.xml').getroot()
53
+ print(f"Coverage: {float(root.attrib['line-rate']) * 100:.2f}%")
54
+ PY
55
+ - uses: actions/upload-artifact@v4
56
+ with:
57
+ name: coverage-${{ matrix.python-version }}
58
+ path: coverage.xml
@@ -0,0 +1,27 @@
1
+ # One-time PyPI setup before the first tag:
2
+ # create a PyPI project or pending publisher for shubham1172/moneymanager-mcp,
3
+ # workflow release.yml, environment pypi, package moneymanager-mcp.
4
+ name: Release
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - 'v*'
10
+
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+
15
+ jobs:
16
+ build-and-publish:
17
+ runs-on: ubuntu-latest
18
+ environment: pypi
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: '3.12'
24
+ cache: pip
25
+ - run: python -m pip install build
26
+ - run: python -m build
27
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,15 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ build/
5
+ dist/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ coverage.xml
13
+ *.mmbak
14
+ *.sqlite
15
+ *.db
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.2.0] - 2026-06-01
8
+
9
+ ### Added
10
+ - `accounts` tool exposing account names and balances.
11
+ - `currency` tool exposing the main currency and all declared currencies.
12
+
13
+ ### Changed
14
+ - Require `moneymanager-parser>=0.2`.
15
+ - CI installs the published parser instead of a local stub.
16
+
17
+ ### Removed
18
+ - `summary` tool, following its removal from `moneymanager-parser`.
19
+
20
+ ## [0.1.0] - 2026-01-01
21
+
22
+ ### Added
23
+ - Initial MCP stdio server exposing summary, query, schema, and category tools.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shubham Sharma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: moneymanager-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP stdio server for Realbyte Money Manager .mmbak backups.
5
+ Project-URL: Homepage, https://github.com/shubham1172/moneymanager-mcp
6
+ Project-URL: Repository, https://github.com/shubham1172/moneymanager-mcp
7
+ Project-URL: Issues, https://github.com/shubham1172/moneymanager-mcp/issues
8
+ Author-email: Shubham Sharma <shubhamsharma1172@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: finance,mcp,mmbak,money-manager,realbyte
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: mcp>=1.2
23
+ Requires-Dist: moneymanager-parser>=0.2
24
+ Provides-Extra: dev
25
+ Requires-Dist: build>=1.2; extra == 'dev'
26
+ Requires-Dist: mypy>=1.10; extra == 'dev'
27
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
28
+ Requires-Dist: pytest>=8.2; extra == 'dev'
29
+ Requires-Dist: ruff>=0.5; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # moneymanager-mcp
33
+
34
+ [![CI](https://github.com/shubham1172/moneymanager-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/shubham1172/moneymanager-mcp/actions/workflows/ci.yml)
35
+ ![PyPI](https://img.shields.io/badge/PyPI-unpublished-lightgrey)
36
+
37
+ MCP stdio server for querying Realbyte Money Manager `.mmbak` exports with AI clients.
38
+
39
+ The server reads a local `.mmbak` file, which is a ZIP-wrapped SQLite database, through the
40
+ `moneymanager-parser` SDK. It exposes tools for filtered queries, schema inspection, category
41
+ listing, accounts (names and balances), and currencies.
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install moneymanager-mcp
47
+ ```
48
+
49
+ ## Run
50
+
51
+ Point the server at a backup file with `MONEY_BACKUP` or pass `backup_path` to each tool:
52
+
53
+ ```bash
54
+ export MONEY_BACKUP=/path/to/backup.mmbak
55
+ moneymanager-mcp
56
+ ```
57
+
58
+ Tools:
59
+
60
+ - `query(backup_path=None, date_from=None, date_to=None, month=None, category=None, search=None, kind="expense", group_by=None, top=None, list_n=None, limit=24)`
61
+ - `schema(backup_path=None)`
62
+ - `list_categories(backup_path=None)`
63
+ - `accounts(backup_path=None)`
64
+ - `currency(backup_path=None)`
65
+
66
+ Invalid or missing backups return a JSON error payload instead of crashing the server.
67
+
68
+ ## Client configuration
69
+
70
+ Claude Desktop example:
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "money-manager": {
76
+ "command": "moneymanager-mcp",
77
+ "env": {
78
+ "MONEY_BACKUP": "/path/to/backup.mmbak"
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ Generic stdio example:
86
+
87
+ ```json
88
+ {
89
+ "command": "moneymanager-mcp",
90
+ "args": [],
91
+ "env": {"MONEY_BACKUP": "/path/to/backup.mmbak"}
92
+ }
93
+ ```
94
+
95
+ ## Development
96
+
97
+ ```bash
98
+ python3 -m venv .venv
99
+ . .venv/bin/activate
100
+ pip install -e '.[dev]'
101
+ ruff check .
102
+ ruff format --check .
103
+ mypy src
104
+ pytest --cov
105
+ ```
106
+
107
+ ## Contributing
108
+
109
+ Issues and pull requests are welcome. Please use generated sample backups in tests rather than
110
+ personal exports.
111
+
112
+ ## License
113
+
114
+ MIT © 2026 Shubham Sharma
@@ -0,0 +1,83 @@
1
+ # moneymanager-mcp
2
+
3
+ [![CI](https://github.com/shubham1172/moneymanager-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/shubham1172/moneymanager-mcp/actions/workflows/ci.yml)
4
+ ![PyPI](https://img.shields.io/badge/PyPI-unpublished-lightgrey)
5
+
6
+ MCP stdio server for querying Realbyte Money Manager `.mmbak` exports with AI clients.
7
+
8
+ The server reads a local `.mmbak` file, which is a ZIP-wrapped SQLite database, through the
9
+ `moneymanager-parser` SDK. It exposes tools for filtered queries, schema inspection, category
10
+ listing, accounts (names and balances), and currencies.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pip install moneymanager-mcp
16
+ ```
17
+
18
+ ## Run
19
+
20
+ Point the server at a backup file with `MONEY_BACKUP` or pass `backup_path` to each tool:
21
+
22
+ ```bash
23
+ export MONEY_BACKUP=/path/to/backup.mmbak
24
+ moneymanager-mcp
25
+ ```
26
+
27
+ Tools:
28
+
29
+ - `query(backup_path=None, date_from=None, date_to=None, month=None, category=None, search=None, kind="expense", group_by=None, top=None, list_n=None, limit=24)`
30
+ - `schema(backup_path=None)`
31
+ - `list_categories(backup_path=None)`
32
+ - `accounts(backup_path=None)`
33
+ - `currency(backup_path=None)`
34
+
35
+ Invalid or missing backups return a JSON error payload instead of crashing the server.
36
+
37
+ ## Client configuration
38
+
39
+ Claude Desktop example:
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "money-manager": {
45
+ "command": "moneymanager-mcp",
46
+ "env": {
47
+ "MONEY_BACKUP": "/path/to/backup.mmbak"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ Generic stdio example:
55
+
56
+ ```json
57
+ {
58
+ "command": "moneymanager-mcp",
59
+ "args": [],
60
+ "env": {"MONEY_BACKUP": "/path/to/backup.mmbak"}
61
+ }
62
+ ```
63
+
64
+ ## Development
65
+
66
+ ```bash
67
+ python3 -m venv .venv
68
+ . .venv/bin/activate
69
+ pip install -e '.[dev]'
70
+ ruff check .
71
+ ruff format --check .
72
+ mypy src
73
+ pytest --cov
74
+ ```
75
+
76
+ ## Contributing
77
+
78
+ Issues and pull requests are welcome. Please use generated sample backups in tests rather than
79
+ personal exports.
80
+
81
+ ## License
82
+
83
+ MIT © 2026 Shubham Sharma
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "moneymanager-mcp"
7
+ dynamic = ["version"]
8
+ description = "MCP stdio server for Realbyte Money Manager .mmbak backups."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Shubham Sharma", email = "shubhamsharma1172@gmail.com" }]
14
+ keywords = ["mcp", "money-manager", "realbyte", "mmbak", "finance"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Typing :: Typed",
25
+ ]
26
+ dependencies = ["mcp>=1.2", "moneymanager-parser>=0.2"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/shubham1172/moneymanager-mcp"
30
+ Repository = "https://github.com/shubham1172/moneymanager-mcp"
31
+ Issues = "https://github.com/shubham1172/moneymanager-mcp/issues"
32
+
33
+ [project.scripts]
34
+ moneymanager-mcp = "moneymanager_mcp.server:main"
35
+
36
+ [project.optional-dependencies]
37
+ dev = ["build>=1.2", "mypy>=1.10", "pytest>=8.2", "pytest-cov>=5.0", "ruff>=0.5"]
38
+
39
+ [tool.hatch.version]
40
+ path = "src/moneymanager_mcp/__init__.py"
41
+
42
+ [tool.ruff]
43
+ line-length = 100
44
+ target-version = "py310"
45
+
46
+ [tool.ruff.lint]
47
+ select = ["E", "F", "I", "UP", "B"]
48
+ ignore = ["E501"]
49
+
50
+ [tool.mypy]
51
+ python_version = "3.10"
52
+ strict = true
53
+ mypy_path = "src"
54
+
55
+ [tool.pytest.ini_options]
56
+ addopts = "-ra"
57
+ testpaths = ["tests"]
58
+
59
+ [tool.coverage.run]
60
+ branch = true
61
+ source = ["moneymanager_mcp"]
62
+
63
+ [tool.coverage.report]
64
+ show_missing = true
65
+ fail_under = 90
@@ -0,0 +1,3 @@
1
+ """MCP server for Money Manager backups."""
2
+
3
+ __version__ = "0.2.0"
File without changes
@@ -0,0 +1,137 @@
1
+ """FastMCP stdio server for Realbyte Money Manager backups."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from collections.abc import Callable, Sequence
7
+ from pathlib import Path
8
+ from typing import Any, Literal, TypeVar
9
+
10
+ from mcp.server.fastmcp import FastMCP
11
+ from moneymanager_parser import Currency, MoneyManagerBackup
12
+
13
+ Json = dict[str, Any]
14
+ Kind = Literal["expense", "income", "all"]
15
+ Group = Literal["month", "category", "day", "week"]
16
+ T = TypeVar("T")
17
+
18
+ mcp = FastMCP("moneymanager")
19
+
20
+
21
+ def _currency_dict(item: Currency) -> Json:
22
+ return {
23
+ "iso": item.iso,
24
+ "symbol": item.symbol,
25
+ "name": item.name,
26
+ "is_main": item.is_main,
27
+ }
28
+
29
+
30
+ def _resolve_backup(path: str | None = None) -> Path:
31
+ value = path or os.environ.get("MONEY_BACKUP")
32
+ if not value:
33
+ raise ValueError("backup path is required; pass backup_path or set MONEY_BACKUP")
34
+ backup = Path(value).expanduser()
35
+ if not backup.exists():
36
+ raise FileNotFoundError(f"backup not found: {backup}")
37
+ return backup
38
+
39
+
40
+ def _with_backup(path: str | None, func: Callable[[MoneyManagerBackup], T]) -> T | Json:
41
+ try:
42
+ with MoneyManagerBackup.from_file(_resolve_backup(path)) as backup:
43
+ return func(backup)
44
+ except Exception as exc: # noqa: BLE001
45
+ return {"status": "error", "reason": str(exc)}
46
+
47
+
48
+ @mcp.tool()
49
+ def accounts(backup_path: str | None = None) -> Json:
50
+ """Return accounts with names and balances from a Money Manager backup.
51
+
52
+ Balances come from the backup's balance column when present, otherwise they
53
+ are derived from transactions (income adds, expense subtracts, transfers move
54
+ to the destination account) as raw sums without currency conversion.
55
+ """
56
+
57
+ def run(backup: MoneyManagerBackup) -> Json:
58
+ return {
59
+ "status": "ok",
60
+ "accounts": [{"name": a.name, "balance": a.balance} for a in backup.accounts()],
61
+ }
62
+
63
+ return _with_backup(backup_path, run)
64
+
65
+
66
+ @mcp.tool()
67
+ def currency(backup_path: str | None = None) -> Json:
68
+ """Return the main currency and all currencies declared in the backup."""
69
+
70
+ def run(backup: MoneyManagerBackup) -> Json:
71
+ main = backup.currency()
72
+ return {
73
+ "status": "ok",
74
+ "main": _currency_dict(main) if main else None,
75
+ "all": [_currency_dict(c) for c in backup.currencies()],
76
+ }
77
+
78
+ return _with_backup(backup_path, run)
79
+
80
+
81
+ @mcp.tool()
82
+ def query(
83
+ backup_path: str | None = None,
84
+ date_from: str | None = None,
85
+ date_to: str | None = None,
86
+ month: str | None = None,
87
+ category: str | None = None,
88
+ search: str | None = None,
89
+ kind: Kind = "expense",
90
+ group_by: Group | None = None,
91
+ top: int | None = None,
92
+ list_n: int | None = None,
93
+ limit: int = 24,
94
+ ) -> Json:
95
+ """Run a filtered full-history query over a Money Manager backup."""
96
+
97
+ def run(backup: MoneyManagerBackup) -> Json:
98
+ return backup.query(
99
+ date_from=date_from,
100
+ date_to=date_to,
101
+ month=month,
102
+ category=category,
103
+ search=search,
104
+ kind=kind,
105
+ group_by=group_by,
106
+ top=top,
107
+ list_n=list_n,
108
+ limit=limit,
109
+ ).as_dict()
110
+
111
+ result = _with_backup(backup_path, run)
112
+ return result
113
+
114
+
115
+ @mcp.tool()
116
+ def schema(backup_path: str | None = None) -> Json:
117
+ """Return resolved tables, columns, and transaction type counts."""
118
+ result = _with_backup(backup_path, lambda backup: backup.schema())
119
+ return result
120
+
121
+
122
+ @mcp.tool()
123
+ def list_categories(backup_path: str | None = None) -> Json:
124
+ """Return category names found in the backup."""
125
+ result = _with_backup(
126
+ backup_path, lambda backup: {"status": "ok", "categories": backup.categories()}
127
+ )
128
+ return result
129
+
130
+
131
+ def main(_argv: Sequence[str] | None = None) -> int:
132
+ mcp.run(transport="stdio")
133
+ return 0
134
+
135
+
136
+ if __name__ == "__main__":
137
+ raise SystemExit(main())
@@ -0,0 +1,82 @@
1
+ from __future__ import annotations
2
+
3
+ import sqlite3
4
+ import zipfile
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ from moneymanager_mcp import __version__
10
+ from moneymanager_mcp.server import (
11
+ _resolve_backup,
12
+ accounts,
13
+ currency,
14
+ list_categories,
15
+ main,
16
+ mcp,
17
+ query,
18
+ schema,
19
+ )
20
+
21
+
22
+ def _backup(path: Path) -> Path:
23
+ db = path / "sample.sqlite"
24
+ con = sqlite3.connect(db)
25
+ con.executescript(
26
+ """
27
+ CREATE TABLE ZCATEGORY (uid TEXT, ZNAME TEXT);
28
+ CREATE TABLE ASSETS (uid TEXT, ZNAME TEXT, ZMONEY TEXT);
29
+ CREATE TABLE CURRENCY (uid TEXT, ISO TEXT, SYMBOL TEXT, NAME TEXT, IS_MAIN_CURRENCY INTEGER);
30
+ CREATE TABLE INOUTCOME (ZMONEY TEXT, WDATE TEXT, DO_TYPE TEXT, ctgUid TEXT, assetUid TEXT, ZCONTENT TEXT);
31
+ INSERT INTO ZCATEGORY VALUES ('1', 'Food');
32
+ INSERT INTO ASSETS VALUES ('a1', 'Cash', '50');
33
+ INSERT INTO CURRENCY VALUES ('c1', 'USD', '$', 'US Dollar', 1);
34
+ INSERT INTO INOUTCOME VALUES ('12', '2026-01-02', '1', '1', 'a1', 'test coffee');
35
+ INSERT INTO INOUTCOME VALUES ('100', '2026-01-02', '0', '1', 'a1', 'test income');
36
+ """
37
+ )
38
+ con.commit()
39
+ con.close()
40
+ archive_path = path / "sample.mmbak"
41
+ with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as archive:
42
+ archive.write(db, "money.sqlite")
43
+ return archive_path
44
+
45
+
46
+ def test_tools_with_explicit_path(tmp_path: Path) -> None:
47
+ backup = _backup(tmp_path)
48
+ assert query(str(backup), month="2026-01", group_by="category")["groups"][0]["key"] == "Food"
49
+ assert schema(str(backup))["transaction_table"] == "INOUTCOME"
50
+ assert list_categories(str(backup))["categories"] == ["Food"]
51
+ accts = accounts(str(backup))
52
+ assert accts["status"] == "ok"
53
+ assert accts["accounts"] == [{"name": "Cash", "balance": 50.0}]
54
+ cur = currency(str(backup))
55
+ assert cur["status"] == "ok"
56
+ assert cur["main"]["iso"] == "USD"
57
+ assert cur["main"]["symbol"] == "$"
58
+ assert [c["iso"] for c in cur["all"]] == ["USD"]
59
+
60
+
61
+ def test_env_path_and_errors(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
62
+ backup = _backup(tmp_path)
63
+ monkeypatch.setenv("MONEY_BACKUP", str(backup))
64
+ assert _resolve_backup() == backup
65
+ assert query()["status"] == "ok"
66
+ monkeypatch.delenv("MONEY_BACKUP")
67
+ assert query()["status"] == "error"
68
+ assert accounts(str(tmp_path / "missing.mmbak"))["status"] == "error"
69
+ assert currency(str(tmp_path / "missing.mmbak"))["status"] == "error"
70
+
71
+
72
+ def test_entry_point_smoke(monkeypatch: pytest.MonkeyPatch) -> None:
73
+ assert __version__ == "0.2.0"
74
+ assert mcp.name == "moneymanager"
75
+ called: list[str] = []
76
+
77
+ def fake_run(*, transport: str) -> None:
78
+ called.append(transport)
79
+
80
+ monkeypatch.setattr(mcp, "run", fake_run)
81
+ assert main([]) == 0
82
+ assert called == ["stdio"]