diff --git a/airflow-mcp-server/pyproject.toml b/airflow-mcp-server/pyproject.toml index e69de29..553fc20 100644 --- a/airflow-mcp-server/pyproject.toml +++ b/airflow-mcp-server/pyproject.toml @@ -0,0 +1,68 @@ +[project] +name = "airflow-mcp-server" +version = "0.1.0" +description = "MCP Server for Airflow" +requires-python = ">=3.11" +dependencies = [ + "aiofiles>=24.1.0", + "aiohttp>=3.11.11", + "aioresponses>=0.7.7", + "mcp>=1.2.0", + "pydantic>=2.10.5", +] + +[project.scripts] +airflow-mcp-server = "airflow_mcp_server.__main__:main" + +[project.optional-dependencies] +dev = [ + "pre-commit>=4.0.1", + "pytest>=8.3.4", + "pytest-asyncio>=0.25.0", + "ruff>=0.9.2" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pytest.ini_options] +pythonpath = ["src"] +asyncio_mode = "strict" +testpaths = ["tests"] + +[tool.ruff] +line-length = 200 +indent-width = 4 +fix = true +preview = true + +lint.select = [ + "E", # pycodestyle errors + "F", # pyflakes + "I", # isort + "W", # pycodestyle warnings + "C90", # Complexity + "C", # flake8-comprehensions + "ISC", # flake8-implicit-str-concat + "T10", # flake8-debugger + "A", # flake8-builtins + "UP", # pyupgrade +] + +lint.ignore = [ + "C416", # Unnecessary list comprehension - rewrite as a generator expression + "C408", # Unnecessary `dict` call - rewrite as a literal + "ISC001" # Single line implicit string concatenation +] + +lint.fixable = ["ALL"] +lint.unfixable = [] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false + +[tool.ruff.lint.isort] +combine-as-imports = true diff --git a/airflow-mcp-server/src/airflow_mcp_server/__init__.py b/airflow-mcp-server/src/airflow_mcp_server/__init__.py new file mode 100644 index 0000000..37a0c64 --- /dev/null +++ b/airflow-mcp-server/src/airflow_mcp_server/__init__.py @@ -0,0 +1,28 @@ +import logging +import sys +from pathlib import Path + +import click + +from airflow_mcp_server.server import serve + + +@click.command() +@click.option("--working-dir", "-w", type=Path, help="Working directory path") +@click.option("-v", "--verbose", count=True) +def main(working_dir: Path | None, verbose: bool) -> None: + """MCP Code Assist Server - Code operations for MCP""" + import asyncio + + logging_level = logging.WARN + if verbose == 1: + logging_level = logging.INFO + elif verbose >= 2: + logging_level = logging.DEBUG + + logging.basicConfig(level=logging_level, stream=sys.stderr) + asyncio.run(serve(working_dir)) + + +if __name__ == "__main__": + main() diff --git a/airflow-mcp-server/src/airflow_mcp_server/__main__.py b/airflow-mcp-server/src/airflow_mcp_server/__main__.py new file mode 100644 index 0000000..8026839 --- /dev/null +++ b/airflow-mcp-server/src/airflow_mcp_server/__main__.py @@ -0,0 +1,3 @@ +from airflow_mcp_server.server import main + +main() diff --git a/airflow-mcp-server/src/airflow_mcp_server/server.py b/airflow-mcp-server/src/airflow_mcp_server/server.py new file mode 100644 index 0000000..e69de29 diff --git a/airflow-mcp-server/src/airflow_mcp_server/tools/base_tools.py b/airflow-mcp-server/src/airflow_mcp_server/tools/base_tools.py new file mode 100644 index 0000000..cff3932 --- /dev/null +++ b/airflow-mcp-server/src/airflow_mcp_server/tools/base_tools.py @@ -0,0 +1,10 @@ +from abc import ABC, abstractmethod + +class BaseTools(ABC): + + def __init__(self): + pass + + @abstractmethod + def run(self): + pass \ No newline at end of file diff --git a/airflow-mcp-server/tests/__init__.py b/airflow-mcp-server/tests/__init__.py new file mode 100644 index 0000000..e69de29