diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6256a9e..90c0be8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,25 +31,3 @@ jobs: - name: Ruff format check run: ruff format --check . - - test: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: pip - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pytest - - - name: Run tests - run: pytest -v diff --git a/server.py b/server.py index 3a63102..71aa782 100644 --- a/server.py +++ b/server.py @@ -14,6 +14,7 @@ # ── Helper ───────────────────────────────────────────────────────── + def run(cmd: str) -> str: """Run a shell command and return its output.""" try: @@ -23,7 +24,11 @@ def run(cmd: str) -> str: output = result.stdout.strip() if result.returncode != 0: error = result.stderr.strip() - return f"Error: {error}" if error else f"Command failed with code {result.returncode}" + return ( + f"Error: {error}" + if error + else f"Command failed with code {result.returncode}" + ) return output if output else "Done." except subprocess.TimeoutExpired: return "Error: Command timed out after 30 seconds." @@ -33,6 +38,7 @@ def run(cmd: str) -> str: # ── Docker Container Tools ───────────────────────────────────────── + @mcp.tool() def docker_list_containers(all: bool = False) -> str: """List Docker containers. Set all=True to include stopped containers.""" @@ -175,10 +181,13 @@ def docker_stats(containers: Optional[list[str]] = None) -> str: # ── Docker Image Tools ───────────────────────────────────────────── + @mcp.tool() def docker_images() -> str: """List all Docker images.""" - return run("docker images --format 'table {{.Repository}}\\t{{.Tag}}\\t{{.ID}}\\t{{.Size}}'") + return run( + "docker images --format 'table {{.Repository}}\\t{{.Tag}}\\t{{.ID}}\\t{{.Size}}'" + ) @mcp.tool() @@ -208,6 +217,7 @@ def docker_rmi(images: list[str], force: bool = False) -> str: # ── Docker Compose Tools ─────────────────────────────────────────── + @mcp.tool() def docker_compose_up( project_dir: str, detach: bool = True, services: Optional[list[str]] = None @@ -253,6 +263,7 @@ def docker_compose_ps(project_dir: str) -> str: # ── Docker System Tools ──────────────────────────────────────────── + @mcp.tool() def docker_system_prune(all: bool = False, volumes: bool = False) -> str: """Remove unused Docker data (containers, images, networks, build cache). @@ -277,6 +288,7 @@ def docker_system_df() -> str: # ── Docker Network Tools ─────────────────────────────────────────── + @mcp.tool() def docker_network_ls() -> str: """List Docker networks.""" @@ -300,6 +312,7 @@ def docker_network_create(name: str, driver: Optional[str] = None) -> str: # ── Docker Volume Tools ──────────────────────────────────────────── + @mcp.tool() def docker_volume_ls() -> str: """List Docker volumes.""" @@ -318,6 +331,7 @@ def docker_volume_create(name: str) -> str: # ── OrbStack VM Tools ───────────────────────────────────────────── + @mcp.tool() def orb_list() -> str: """List OrbStack Linux machines (VMs).""" @@ -395,6 +409,7 @@ def orb_info() -> str: # ── Kubernetes Tools ─────────────────────────────────────────────── + @mcp.tool() def kubectl_get( resource: str, @@ -417,9 +432,7 @@ def kubectl_get( @mcp.tool() -def kubectl_describe( - resource: str, name: str, namespace: Optional[str] = None -) -> str: +def kubectl_describe(resource: str, name: str, namespace: Optional[str] = None) -> str: """Describe a Kubernetes resource in detail. Args: