diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..8f859cc --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,46 @@ +name: Docker Build & Compose Validation + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + docker_build: + name: Build Docker Image + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU (for multi-platform builds) + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + run: docker build --file Dockerfile --tag telegram-mcp:ci . + + docker_compose: + name: Build & Validate Docker Compose + runs-on: ubuntu-latest + needs: docker_build + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Create dummy .env file + run: | + echo "TELEGRAM_API_ID=DUMMY_ID" > .env + echo "TELEGRAM_API_HASH=DUMMY_HASH" >> .env + echo "TELEGRAM_SESSION_STRING=DUMMY_SESSION" >> .env + # Add other required variables with dummy values if needed + + - name: Validate Compose file syntax + run: docker compose config + + - name: Build Compose services + run: docker compose build \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..14babb0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +# Use an official Python runtime as a parent image (Alpine-based for minimal vulnerabilities) +FROM python:3.13-alpine + +# Set the working directory in the container +WORKDIR /app + +# Prevent Python from writing pyc files to disc +ENV PYTHONDONTWRITEBYTECODE=1 +# Ensure Python output is sent straight to terminal (useful for logs) +ENV PYTHONUNBUFFERED=1 + +# Install system dependencies if needed (e.g., for certain Python packages) +# RUN apt-get update && apt-get install -y --no-install-recommends some-package && rm -rf /var/lib/apt/lists/* + +# Copy dependency definition files +# If using Poetry: +# COPY pyproject.toml poetry.lock* ./ +# RUN pip install --no-cache-dir poetry +# RUN poetry config virtualenvs.create false && poetry install --no-dev --no-interaction --no-ansi +# If using pip with requirements.txt: +COPY requirements.txt ./ +RUN pip install --no-cache-dir --upgrade pip +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the rest of the application code +COPY main.py . +# COPY session_string_generator.py . # Optional: if needed within the container, otherwise can be run outside + +# Create a non-root user and switch to it +RUN adduser --disabled-password --gecos "" appuser && chown -R appuser:appuser /app +USER appuser + +# Define environment variables needed by the application +# These should be provided at runtime, not hardcoded (especially secrets) +ENV TELEGRAM_API_ID="" +ENV TELEGRAM_API_HASH="" +# Specify one of the following at runtime: +# Default session filename +ENV TELEGRAM_SESSION_NAME="telegram_mcp_session" +# Or provide the session string directly +ENV TELEGRAM_SESSION_STRING="" + +# Expose any ports if the application were a web server (not needed for stdio MCP) +# EXPOSE 8000 + +# Define the command to run the application +CMD ["python", "main.py"] \ No newline at end of file diff --git a/README.md b/README.md index cdc7a72..9d87f5d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ![MCP Badge](https://badge.mcpx.dev) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-green?style=flat-square)](https://opensource.org/licenses/Apache-2.0) +[![Python Lint & Format Check](https://github.com/chigwell/telegram-mcp/actions/workflows/python-lint-format.yml/badge.svg)](https://github.com/chigwell/telegram-mcp/actions/workflows/python-lint-format.yml) +[![Docker Build & Compose Validation](https://github.com/chigwell/telegram-mcp/actions/workflows/docker-build.yml/badge.svg)](https://github.com/chigwell/telegram-mcp/actions/workflows/docker-build.yml) --- @@ -168,6 +170,51 @@ Get your API credentials at [my.telegram.org/apps](https://my.telegram.org/apps) --- +## 🐳 Running with Docker + +If you have Docker and Docker Compose installed, you can build and run the server in a container, simplifying dependency management. + +### 1. Build the Image + +From the project root directory, build the Docker image: + +```bash +docker build -t telegram-mcp:latest . +``` + +### 2. Running the Container + +You have two options: + +**Option A: Using Docker Compose (Recommended for Local Use)** + +This method uses the `docker-compose.yml` file and automatically reads your credentials from a `.env` file. + +1. **Create `.env` File:** Ensure you have a `.env` file in the project root containing your `TELEGRAM_API_ID`, `TELEGRAM_API_HASH`, and `TELEGRAM_SESSION_STRING` (or `TELEGRAM_SESSION_NAME`). Use `.env.example` as a template. +2. **Run Compose:** + ```bash + docker compose up --build + ``` + * Use `docker compose up -d` to run in detached mode (background). + * Press `Ctrl+C` to stop the server. + +**Option B: Using `docker run`** + +You can run the container directly, passing credentials as environment variables. + +```bash +docker run -it --rm \ + -e TELEGRAM_API_ID="YOUR_API_ID" \ + -e TELEGRAM_API_HASH="YOUR_API_HASH" \ + -e TELEGRAM_SESSION_STRING="YOUR_SESSION_STRING" \ + telegram-mcp:latest +``` +* Replace placeholders with your actual credentials. +* Use `-e TELEGRAM_SESSION_NAME=your_session_file_name` instead of `TELEGRAM_SESSION_STRING` if you prefer file-based sessions (requires volume mounting, see `docker-compose.yml` for an example). +* The `-it` flags are crucial for interacting with the server. + +--- + ## ⚙️ Configuration for Claude & Cursor ### MCP Configuration @@ -180,7 +227,7 @@ Edit your Claude desktop config (e.g. `~/Library/Application Support/Claude/clau "command": "uv", "args": [ "--directory", - "/full/path/to/telegram-mcp-server", + "/full/path/to/telegram-mcp", "run", "main.py" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e505d20 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.8' + +services: + telegram-mcp: + build: + context: . + dockerfile: Dockerfile + container_name: telegram-mcp + # Load environment variables from a .env file in the same directory + env_file: + - .env + # Keep stdin open and allocate a pseudo-TTY, crucial for stdio MCP servers + stdin_open: true + tty: true + # Optional: Uncomment the following lines to mount a local directory + # for persisting the Telegram session file if NOT using TELEGRAM_SESSION_STRING. + # Replace './telegram_sessions' with your desired host path. + # volumes: + # - ./telegram_sessions:/app + restart: unless-stopped \ No newline at end of file