[project] name = "mnemo-mcp" version = "2.15.13" description = "Open-source MCP Server for persistent AI memory with embedded sync" readme = "README.md" license = { text = "Apache-2.0" } authors = [{ name = "n24q02m", email = "quangminh2422004@gmail.com" }] keywords = ["mcp", "mcp-server", "model-context-protocol", "memory", "ai-memory", "sqlite", "embeddings", "claude", "cursor", "copilot", "antigravity", "codex", "opencode"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] requires-python = "==3.13.*" dependencies = [ # MCP Server "mcp[cli]<3", # HTTP Client (for embedding API calls) "httpx", # Config "pydantic", # 2.15 warns while constructing MCP SDK Settings; lift after upstream rebuilds its model. "pydantic-settings>=2.14.2,<2.15", # Logging "loguru", # SQLite vector search "sqlite-vec", # Local ONNX embedding (auto-fallback when no cloud API) "fastretrieval>=1.2.0,<2", # 1.19.0 ships mcp_core.cli's argument-spec extra subcommand # support ((configure, handler) tuples) this repo's cli.py auth # subcommand consumes. 1.20.0b2 fixes build_cli's `config`/`doctor` # PerPluginStore key (#666): it defaulted to the display # server_name ("mnemo-mcp") instead of the plugin slug ("mnemo") # this server actually saves credentials under, so `mnemo-mcp # config status` always reported "not configured". "n24q02m-mcp-core[llm]==1.24.6", # Transitive pin: fastmcp reaches us only through mcp-core, which requires # it unbounded -- so nothing in this repo constrained it and Renovate's # lockFileMaintenance (`uv lock --upgrade`, automerge on) locked the # 4.0.0b1 beta in #1022. fastmcp 4 reshapes the ToolAnnotations model: # `readOnlyHint`/`destructiveHint` are no longer fields, so Pydantic # silently discards them and all 14 annotated tools in server.py lose # their hints. Cap at <4 until mcp-core itself moves to fastmcp 4 and # this repo's annotations are ported. "fastmcp>=3.4.7,<4", # Pin Pygments to fix ReDoS (CVE in <2.20.0) "Pygments>=2.21.0", "alembic>=1.19.1", # Phase 2: token counting for LLM compression pipeline "tiktoken>=0.14.0", # Phase 2: S3 / R2 / B2 / MinIO passport-sync backend "boto3>=1.43.89", # Phase 2: AES-256-GCM bundle encryption + Argon2id KDF "cryptography>=50.0.1", # Transitive pin: urllib3 < 2.7.0 has 2 HIGH CVEs (GHSA-qccp-gfcp-xxvc # sensitive-header cross-origin forwarding + GHSA-mf9v-mfxr-j63j # decompression-bomb bypass). Both patched in 2.7.0. "urllib3>=2.7.0", # Transitive pin: idna < 3.15 -> CVE-2026-45409; python-multipart # < 0.0.27 -> CVE-2026-42561. Pinned to patched releases. "idna>=3.19", "python-multipart>=0.0.32", ] [dependency-groups] dev = [ "pytest", "pytest-asyncio", "pytest-timeout", "ruff", "ty", "pre-commit", "pytest-cov>=7.1.0", "pytest-xdist>=3.8.0", "syrupy>=6.0.0", # Phase 2: in-memory S3 fixture for sync backend tests "moto[s3]>=5.2.3", "bandit>=1.9.4", ] [project.scripts] mnemo-mcp = "mnemo_mcp.cli:main" mnemo-pilot = "mnemo_cli.__main__:main" mnemo = "mnemo_cli.__main__:main" [project.urls] Homepage = "https://github.com/n24q02m/mnemo-mcp" Repository = "https://github.com/n24q02m/mnemo-mcp.git" Issues = "https://github.com/n24q02m/mnemo-mcp/issues" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/mnemo_mcp", "src/mnemo_core", "src/mnemo_cli"] [tool.hatch.build.targets.wheel.sources] "src" = "" [tool.hatch.build.targets.sdist] include = [ "src/mnemo_mcp/**/*.py", "src/mnemo_mcp/**/*.md", "src/mnemo_mcp/**/*.ini", "src/mnemo_mcp/**/*.mako", "src/mnemo_mcp/alembic/README", "src/mnemo_mcp/py.typed", "src/mnemo_core/**/*.py", "src/mnemo_cli/**/*.py", ] [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" pythonpath = ["."] testpaths = ["tests"] python_files = ["test_*.py"] timeout = 30 markers = [ "integration: integration tests (require network/services)", "live: live MCP protocol tests (spawn real server via stdio)", "full: full live tests with real services", "e2e: end-to-end MCP protocol tests (3 setup modes)", "slow: slow tests (skippable with -m 'not slow')", ] addopts = "-m 'not integration and not live and not full and not e2e'" [tool.ty] rules = { unresolved-import = "ignore", unresolved-attribute = "ignore", possibly-missing-attribute = "ignore" } # Local worktree checkouts are not part of the source tree; without this the # pre-commit ty hook lints stale copies under .worktrees/ and fails on # diagnostics that were fixed long ago in the real tree. [tool.ty.src] exclude = [".worktrees/**"] [tool.semantic_release] version_toml = ["pyproject.toml:project.version"] version_variables = [".claude-plugin/plugin.json:version", "server.json:version"] tag_format = "v{version}" commit_message = "chore(release): v{version}" major_on_zero = false [tool.semantic_release.changelog] changelog_file = "CHANGELOG.md" [tool.semantic_release.remote] type = "github" [tool.ruff] line-length = 88 target-version = "py313" [tool.ruff.lint] select = ["E", "F", "W", "I", "UP", "B", "C4"] ignore = ["E501"] [tool.ruff.format] quote-style = "double" [tool.coverage.run] source = ["src/mnemo_mcp"] branch = true [tool.coverage.report] fail_under = 95 show_missing = true exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"]