[project] name = "apple-mail-mcp" version = "0.5.0" description = "Apple Mail MCP server with full-coverage FTS5 body search. Reliable on large mailboxes where AppleScript-based servers timeout." readme = "README.md" license = "GPL-3.0-or-later" requires-python = ">=3.11" authors = [ { name = "Ioan-Mihail Dinu", email = "iodinu@icloud.com" }, ] keywords = [ "anthropic", "apple-mail", "apple-mail-mcp", "claude", "claude-code", "claude-desktop", "email", "emlx", "fts5", "full-text-search", "llm", "macos", "mcp", "model-context-protocol", "search", ] classifiers = [ "Development Status :: 4 - Beta", "Environment :: MacOS X", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Operating System :: MacOS", "Programming Language :: JavaScript", "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 :: Communications :: Email", "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ "fastmcp>=3.0.0b1,<4", "cyclopts>=4.10", "beautifulsoup4>=4.12", "selectolax>=0.4.8", "typing-extensions>=4.6 ; python_full_version < '3.12'", ] [project.optional-dependencies] watch = ["watchfiles>=1.0"] [project.urls] Homepage = "https://github.com/imdinu/apple-mail-mcp" Documentation = "https://imdinu.github.io/apple-mail-mcp/" Repository = "https://github.com/imdinu/apple-mail-mcp" Issues = "https://github.com/imdinu/apple-mail-mcp/issues" Changelog = "https://github.com/imdinu/apple-mail-mcp/blob/main/CHANGELOG.md" [project.scripts] apple-mail-mcp = "apple_mail_mcp:main" [tool.hatch.build.targets.wheel] packages = ["src/apple_mail_mcp"] [tool.hatch.build.targets.sdist] include = ["src/"] [tool.hatch.build] # Include .js files and py.typed marker in the package artifacts = ["src/**/*.js", "src/**/py.typed"] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [dependency-groups] dev = [ "ruff>=0.14.8", "pytest>=8.0", "pytest-cov>=6.0", "pytest-asyncio>=0.24", "flameprof>=0.4", ] bench = [ "plotly[kaleido]>=6", ] docs = [ "zensical", ] [tool.pytest.ini_options] testpaths = ["tests"] pythonpath = ["src"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" [tool.ruff] target-version = "py311" line-length = 80 src = ["src"] [tool.ruff.lint] select = [ "ASYNC", "B", "E", "F", "I", "RUF", "UP", "W", ] ignore = [ "ASYNC109", # Timeout parameter pattern is cleaner API for our use case ] [tool.ruff.format] docstring-code-format = true