[project] name = "people-context" version = "1.2.1" description = "Local-first MCP server giving AI agents contextual knowledge about the people in your life" readme = "README.md" requires-python = ">=3.11" license = "MIT" authors = [{ name = "Jinyang Wang", email = "jinyang.wang27@outlook.com" }] keywords = ["ai-agents", "local-first", "mcp", "model-context-protocol", "personal-context"] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Database", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] # `starlette` and `uvicorn` are already resolved beneath `mcp`; they are declared because # `pctx browse` imports them directly, not added. dependencies = [ "mcp>=2,<3", "pydantic>=2.7", "python-ulid>=2.2", "starlette>=1,<2", "tzdata>=2024.1", "uvicorn>=0.31.1", ] [project.urls] Homepage = "https://github.com/JinyangWang27/people-context" Repository = "https://github.com/JinyangWang27/people-context" Issues = "https://github.com/JinyangWang27/people-context/issues" [project.optional-dependencies] semantic = [ "model2vec>=0.8.2,<0.10", "sqlite-vec>=0.1.9,<0.2", ] # Opt-in SQLCipher at-rest encryption. `sqlcipher3-binary` publishes only # manylinux x86_64 wheels and no source distribution, so the marker keeps macOS, # Windows, and non-x86_64 resolution working instead of failing there. PEP 508 # has no libc marker, so musl-based Linux (Alpine) cannot be excluded here and is # documented as uncovered; a locally built `sqlcipher3` serves it and every other # platform. See docs/privacy-and-safety.md#optional-at-rest-encryption. encrypted = [ "sqlcipher3-binary>=0.6.0,<0.7; sys_platform == 'linux' and platform_machine == 'x86_64'", ] [project.scripts] people-context-mcp = "people_context.adapters.mcp.server:main" people-context = "people_context.adapters.mcp.server:main" pctx = "people_context.cli:main" [dependency-groups] dev = [ # `starlette.testclient` imports `httpx2`, which `mcp` already requires. "httpx2>=2.5", "ipykernel>=7.3.0", "mypy>=1.18", "pytest>=8", "ruff>=0.6", "model2vec>=0.8.2,<0.10", "sqlite-vec>=0.1.9,<0.2", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/people_context"] # The evaluation harness is developer tooling: fictional fixtures, prompts, and a # runner that starts an agent CLI. None of it is importable by the server or the # CLI, so it stays out of both published artifacts. The wheel already ships only # `src/people_context`; the source distribution needs the exclusion stated. Its # tests go with it, so the shipped test suite stays runnable without the harness. [tool.hatch.build.targets.sdist] exclude = ["/evals", "/tests/evals"] [tool.ruff] line-length = 120 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "SIM"] [tool.pytest.ini_options] testpaths = ["tests"] # The architecture depends on static typing to hold: use cases receive narrow # `typing.Protocol` ports rather than concrete adapters, so a port that a delegate # does not actually satisfy is a mistake nothing else in the pipeline catches. Ruff # checks style and imports, not types. The interpreter version is deliberately not # pinned here: CI runs this across the supported range, so each run checks the code # against the standard library it will actually import. [tool.mypy] plugins = ["pydantic.mypy"] files = ["src/people_context"] # Third-party packages here ship no type information; the project's own code is # checked, and its use of those packages is not silently skipped. ignore_missing_imports = true disallow_untyped_defs = true disallow_incomplete_defs = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true # numpy arrives through the optional semantic extra and ships stubs written for a # newer Python than the lowest version checked here. Its internals are not this # project's code to check; call sites still are. [[tool.mypy.overrides]] module = ["numpy.*"] follow_imports = "skip"