MCPunk

[project] name = "mcpunk" dynamic = ["version"] description = "MCP tools for Roaming RAG" authors = [{ name = "Michael Jurasoovic" }] license = { text = "MIT" } readme = "README.md" requires-python = ">=3.11" dependencies = [ "gitpython~=3.1.44", "pydantic~=2.10.6", "asttokens~=3.0.0", "more-itertools~=10.6.0", "mcp~=1.2.0", "fastmcp~=0.4.1", "beautifulsoup4~=4.13.3", "uvicorn>=0.34.0,<1.0.0", "watchdog~=6.0.0", ] [project.scripts] mcpunk = "mcpunk.run_mcp_server:main" [build-system] requires = ["hatchling>=1.21.0", "hatch-vcs>=0.4.0"] build-backend = "hatchling.build" [tool.hatch.version] source = "vcs" [tool.setuptools.dynamic] version = {attr = "mcpunk.__version__"} [tool.setuptools.packages.find] include = ["mcpunk*"] [project.optional-dependencies] dev = [ "mypy~=1.15.0", "pytest~=8.3.4", "ruff~=0.9.9", "pytest-cov~=6.0.0", "deepdiff~=8.2.0", "pre-commit~=4.1.0", "line-profiler~=4.2.0", ] [tool.mypy] python_version = "3.11" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true ignore_missing_imports = true show_error_codes = true pretty = true no_implicit_optional = true implicit_reexport = false strict_equality = true strict=true disallow_untyped_decorators = true enable_error_code=[ "ignore-without-code", "truthy-bool", "unused-awaitable", "possibly-undefined", ] [tool.pydantic-mypy] init_forbid_extra = true init_typed = true warn_required_dynamic_aliases = true warn_untyped_fields = true [tool.ruff] target-version = "py311" show-fixes = true line-length = 100 lint.select = [ "ALL", ] lint.ignore = [ "C408", # unnecessary-collection-call ( e.g. `dict(x=y)` => `{'x': y}`) "D100", # Missing docstring in public module "D101", # Missing docstring in public class "D102", # Missing docstring in public method "D103", # Missing docstring in public function "D104", # Missing docstring in public package "D105", # Missing docstring in magic method "D106", # Missing docstring in public nested class "D107", # Missing docstring in `__init__` "PT003", # scope='function' is implied in @pytest.fixture() "PT018", # Assertion should be broken down into multiple parts "PT015", # Assertion always fails, replace with `pytest.fail()` "RET504", # Unnecessary variable assignment before `return` statement "RET506", # Unnecessary `elif` after `raise` statement "RET505", # Unnecessary `elif` after `return` statement "SIM118", # Use 'key in dict' instead of 'key in dict.keys()' "SIM108", # Use ternary operator `d = 1 if b else 0` instead of if-else-block "SIM103", # Checks for if statements that can be replaced with bool. "TRY003", # Avoid specifying long messages outside the exception class "S101", # Use of `assert` detected "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes "TD002", # Missing author "TD003", # Missing issue link "PD901", # `df` is a bad variable name. Be kinder to your future self. "D211", # `o-blank-line-before-class "D213", # multi-line-summary-second-line "D415", # First line should end with a period, question mark, or exclamation point "D400", # First line should end with a period "D203", # one-blank-line-before-class "FBT001", # Boolean-typed positional argument in function definition "FBT002", # Boolean default positional argument in function definition "T201", # `print` found "TC001", # Move application import x into a type-checking block "TC002", # Move third-party import x into a type-checking block "TC003", # Move standard library import x into a type-checking block "ERA001", # Found commented-out code "FIX002", # Line contains TODO, consider resolving the issue # Textual goes hard on shadowing builtins so 🤷 "A002", # Function argument `id` is shadowing a Python builtin "EM102", # Exception must not use an f-string literal, assign to variable first "ANN401", # Dynamically typed expressions (typing.Any) are disallowed in `**kwargs` "PLR2004", # Magic value used in comparison, consider replacing `1_000` with a constant variable "PLR0912", # Too many branches (15 > 12) "PLR0915", # Too many statements (52 > 50) "C901", # `get_diff_summary` is too complex (11 > 10) "SIM102", # `Use a single `if` statement instead of nested `if` statements "G004", # Logging statement uses f-string "EM101", # Exception must not use a string literal, assign to variable first "PLR0913", # Too many arguments in function definition (9 > 5) "TRY300", # Consider moving this statement to an `else` block "TRY301", # Abstract `raise` to an inner function "SIM114", # if-with-same-arms "FIX004", # Line contains HACK, consider resolving the issue "G003", # Logging statement uses `+` "PERF401", # Use `list.extend` to create a transformed list ] lint.unfixable = [ # Auto-fixing RUF100 often results in it auto removing the noqa statement, # which might just be a typo. Best to leave it to the user to fix. "RUF100", # Unused `noqa` directive / Unused blanket `noqa` directive # Auto-fixing F841 results in e.g. `a = df["a"]` silently turning ino `df["a"]` # Mega annoying, especially if running ruff against WIP code. "F841", # Local variable `a` is assigned to but never used # Auto-fixing PIE794 wipes an item from the class - would rather fix manually. "PIE794", # duplicate-class-field-definition # The autofix for this sets it to False 🫠🫠🫠🫠 good God "B905", # zip() without explicit `strict` parameter ] [tool.ruff.lint.pydocstyle] convention = "google" # Accepts: "google", "numpy", or "pep257". [tool.ruff.lint.flake8-pytest-style] parametrize-values-type = "tuple" [tool.ruff.lint.flake8-unused-arguments] ignore-variadic-names = true [tool.ruff.lint.flake8-tidy-imports] # Disallow all relative imports. ban-relative-imports = "all" [tool.uv.workspace] members = ["blah/blah"]