[build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [project] name = "compartment" version = "4.13.0" description = "Compartment - high-security, fully offline, encrypted vector memory for AI agents (MCP)" readme = "README.md" license = { text = "Apache-2.0" } requires-python = ">=3.11" keywords = ["mcp", "model-context-protocol", "memory", "agent-memory", "vector-database", "semantic-search", "encryption", "offline", "local-first", "claude", "claude-code", "privacy", "rag"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Environment :: Console", "Environment :: MacOS X", "Operating System :: OS Independent", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Security :: Cryptography", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Database :: Database Engines/Servers", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", ] dependencies = [ "pynacl>=1.5", "argon2-cffi>=23.1", "onnxruntime>=1.17", "tokenizers>=0.15", "numpy>=1.26", # Both majors. mcp 2.0 (2026-07-28) removed mcp.server.fastmcp in favour # of mcp.server.mcpserver; server.py imports whichever is present, so the # same wheel runs on 1.x and 2.x and single-version distros are not # stranded on either side of the rename. The floor is 1.21.2, not 1.0: # nothing before 1.10 can register the tools at all (FastMCP arrived in # 1.2, tool titles in 1.10), and 1.10 through 1.21.1 break against the # pydantic 2.12+ that pip installs beside them - an import error inside # mcp, or a TypeError on this module's postponed annotations - so an # older mcp already in the environment meant a server that never # started while pip called the install satisfied. With this floor pip # upgrades it instead. CI's lowest-dependencies job runs the suite at # exactly these floors. "mcp>=1.21.2,<3", # The app ships with every install. It is not an add-on: unlocking, # locking and changing the passphrase are things people do through a # panel, not through a terminal, so an install that only lays down a CLI # is an incomplete install. The markers keep it honest - nothing # macOS-only is fetched on Windows and nothing Windows-only on macOS. # Linux needs neither: its panel is Tk, which is in the standard library, # so nothing here is fetched and nothing is compiled there. "pyobjc-framework-Cocoa>=10.0; sys_platform == 'darwin'", "pystray>=0.19; sys_platform == 'win32'", "pillow>=10; sys_platform == 'win32'", # Two platforms the newest releases of two indirect dependencies left # without wheels. pip takes the newest version whether or not it has a # wheel for the machine, and then tries to compile it: cryptography (via # mcp -> pyjwt[crypto]) needs a Rust toolchain, so `pip install # compartment` simply failed on a Snapdragon Windows laptop and on an # Intel Mac, and the release build of the Intel app failed with it. # These caps hold each one at its last release with a wheel there, on # that platform only; everywhere else nothing changes. Compartment # itself never imports cryptography - mcp needs it only for its HTTP # transports' auth, which a stdio server does not use. Lift a cap when # the project ships those wheels again; CI's windows-11-arm and # macos-15-intel jobs show it. "cryptography<46.0.4; sys_platform == 'win32' and platform_machine == 'ARM64'", "cryptography<49; sys_platform == 'darwin' and platform_machine == 'x86_64'", "argon2-cffi-bindings<26; sys_platform == 'darwin' and platform_machine == 'x86_64'", ] # PyPI is the repo's declared homepage, so it is a real front door - and # without these it is a dead end: no Source link, no Issues link, nothing # carrying a reader back to GitHub. Directories that scrape PyPI were # producing a listing with no repository link at all. [project.urls] Homepage = "https://github.com/MaxFreedomPollard/Compartment" Source = "https://github.com/MaxFreedomPollard/Compartment" Issues = "https://github.com/MaxFreedomPollard/Compartment/issues" Changelog = "https://github.com/MaxFreedomPollard/Compartment/releases" Documentation = "https://github.com/MaxFreedomPollard/Compartment#readme" Security = "https://github.com/MaxFreedomPollard/Compartment/blob/main/SECURITY.md" [project.scripts] compartment = "compartment.cli:main" cmpt = "compartment.cli:main" # Compartment was engRAM until 1.15.1, and `engram` is the command sitting in # every existing MCP client config, shell alias and Hermes setup. Keeping it # means the rename costs nobody a broken agent. engram = "compartment.cli:main" [project.optional-dependencies] # usearch (SIMD HNSW) is only needed ABOVE 20k records; below that Compartment # uses an exact brute-force index. Keeping it optional means the default # `pip install` compiles nothing and installs cleanly everywhere; large # corpora add it with `pip install compartment[hnsw]`. hnsw = ["usearch>=2.9"] # The status bar app is part of the base install now, so these two are kept # only so that an existing `pip install compartment[menubar]` or # `compartment[tray]` in someone's notes or script keeps resolving instead of # failing on an unknown extra. They add nothing. menubar = [] tray = [] dev = ["pytest>=8", "pytest-cov>=5", "pytest-timeout>=2.3", "usearch>=2.9"] [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] compartment = ["models/**/*", "data/**/*"] # Running the suite must cost the machine it runs on nothing. A test marked # real_launchctl talks to the live launchd of whoever started pytest, so it # is deselected by default and asked for by name: # pytest -m real_launchctl [tool.pytest.ini_options] markers = [ "real_launchctl: talks to the real launchd; opt in with -m real_launchctl", ] addopts = "-m 'not real_launchctl'"