[project] name = "kitchensink4ppt" version = "1.2.3" description = "Create and edit PowerPoint (.pptx) files with your AI assistant: diagrams from editable shapes, tables, charts and slide templates. Local MCP server for Claude Code, Codex CLI and other MCP clients." readme = "README.md" license = "AGPL-3.0-only" license-files = ["LICENSE", "NOTICE.md"] authors = [{ name = "Alvut Consulting, LLC (KitchenSink4AI)" }] keywords = [ "mcp", "powerpoint", "pptx", "ooxml", "claude", "model-context-protocol", "presentations", "slides", "shapes", "svg", "vector-graphics", "tables", ] classifiers = [ "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: End Users/Desktop", "Natural Language :: English", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: XML", ] requires-python = ">=3.12" dependencies = [ # PINNED, and the pin is a floor not a shrug: 3.4 is where the # visibility API tiered loading rides (global Visibility transform at # startup, session-scoped ctx.enable_components/disable_components # mid-session, list_changed per toggle) settled. 2.14's # Tool.enable()/disable() is gone in 3.x; see packs.py. "fastmcp>=3.4,<4", "lxml", "regex", "packaging", # version comparison for the startup update check "svgelements>=1.9", "latex2mathml>=3.81", # LaTeX -> MathML (equations pipeline, same as word-mcp) "mathml2omml>=0.0.2", # MathML -> OMML (equations pipeline, same as word-mcp) "pywin32; sys_platform == 'win32'", ] [project.optional-dependencies] dev = [ "pytest", "pytest-timeout", "python-pptx", # test oracle and synthetic corpus generation only, never a runtime dependency ] optimize = [ "Pillow", # compress_deck image downsampling only; without it the purge half still works and recompression is refused honestly ] [project.urls] Homepage = "https://kitchensink4.ai" Documentation = "https://github.com/KitchenSink4AI/KitchenSink4PPT#readme" Repository = "https://github.com/KitchenSink4AI/KitchenSink4PPT" Issues = "https://github.com/KitchenSink4AI/KitchenSink4PPT/issues" [project.scripts] ppt-mcp = "kitchensink4ppt.server:main" kitchensink4ppt = "kitchensink4ppt.server:main" [build-system] requires = ["setuptools>=77"] build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["src"] [tool.pytest.ini_options] testpaths = ["tests"] timeout = 120 # Without the plugin installed, every timeout= setting and # @pytest.mark.timeout in the suite goes silently inert, which is how a COM # hang once ran unbounded during a field round. Fail the run instead. required_plugins = ["pytest-timeout"] markers = [ "live: needs an interactive PowerPoint instance (auto-skipped where PowerPoint is unavailable)", ]