[project] name = "mcp-server-for-ynab" version = "0.4.0" description = "An AI-first MCP server for YNAB. Read-only by default, with reversible writes." readme = "README.md" requires-python = ">=3.12" license = { text = "Apache-2.0" } authors = [{ name = "Harsh S" }] keywords = ["mcp", "model-context-protocol", "ynab", "budgeting", "personal-finance", "llm", "agent"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: End Users/Desktop", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Office/Business :: Financial :: Accounting", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", ] dependencies = [ "httpx>=0.28.1", # Upper bound is load-bearing, not caution: mcp 2.0 removed # mcp.server.fastmcp, which this server is built on. An unbounded # requirement resolves to 2.x on a fresh install and fails at import with # "No module named 'mcp.server.fastmcp'" — invisible locally, because the # lockfile pins 1.x. Migrating to the 2.x server API is its own change. # # The lower bound is a security floor. 1.27.1 and earlier carry # GHSA-jpw9-pfvf-9f58, where the HTTP transports serve session requests # without verifying the authenticated principal. End users install with # uvx, which resolves from this file and never reads uv.lock, so raising # the lockfile alone would leave them on the vulnerable SDK. "mcp>=2.1.1,<3", "pydantic>=2.13.4", ] [project.urls] Homepage = "https://github.com/hs737/mcp-server-for-ynab" Repository = "https://github.com/hs737/mcp-server-for-ynab" Issues = "https://github.com/hs737/mcp-server-for-ynab/issues" Changelog = "https://github.com/hs737/mcp-server-for-ynab/releases" Security = "https://github.com/hs737/mcp-server-for-ynab/blob/master/SECURITY.md" [project.scripts] mcp-server-for-ynab = "mcp_server_for_ynab.cli.main:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/mcp_server_for_ynab"] [dependency-groups] dev = [ "mypy>=2.1.0", "pytest>=9.0.3", "pytest-asyncio>=1.3.0", "pytest-httpx>=0.36.2", "pyyaml>=6.0.3", "ruff>=0.15.13", "uvicorn>=0.34.0", ] [tool.ruff] target-version = "py312" line-length = 120 src = ["src"] [tool.ruff.lint] select = [ "E", "W", "F", "I", "UP", "B", "C4", "RUF", ] ignore = ["B008"] [tool.ruff.lint.isort] known-first-party = ["mcp_server_for_ynab"] [tool.ruff.lint.per-file-ignores] # The asset renderers are mostly SVG templates. Wrapping markup to satisfy a # line-length rule makes it harder to read, not easier, and these files ship # nothing — they only produce images. "scripts/demo/*.py" = ["E501"] [tool.mypy] python_version = "3.12" strict = true ignore_missing_imports = true explicit_package_bases = true mypy_path = "src" [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" # --------------------------------------------------------------------------- # Postman collection commands # Run with: uv run python scripts/