MCP Agent
Deployment

Deployment

Local Development

cd agent
 
# Install dependencies
uv sync
 
# Copy and edit environment variables
cp .env.example .env
 
# Run the agent
uv run ziada-mcp

The agent starts on port 8081 by default.

Docker

Dockerfile

Multi-stage build:

  1. Build stage: Uses uv to build a wheel
  2. Runtime stage: Python 3.12-slim with the wheel installed

docker-compose.yml

services:
  agent:
    build: .
    ports:
      - "8081:8081"
    env_file: .env
    healthcheck:
      test: ["CMD", "python", "-c", "import socket; s=socket.socket(); s.connect(('localhost',8081)); s.close()"]
      interval: 30s
      timeout: 5s
      retries: 3

Important: The healthcheck uses TCP connection (not HTTP) because each HTTP probe opens an MCP session and triggers the API's 15-minute login rate-lock.

Build and Run

docker compose build
docker compose up -d

Production (VPS)

Server: 13.140.167.42 (SSH alias: camel)

Architecture

Internet -> Nginx (TLS) -> Agent (port 8087 -> container 8081)

Deploy Steps

# SSH into server
ssh camel
 
# Navigate to project
cd ~/ziadapos-go/deploy
 
# Pull latest changes
git pull
 
# Rebuild and restart
docker compose build agent
docker compose up -d --force-recreate agent
 
# Verify health
docker compose ps agent

Nginx Configuration

The agent is exposed at https://agent.ziadapos.com/mcp via nginx reverse proxy.

CI/CD (GitHub Actions)

Pipeline

  1. Test job:

    • ruff check (lint)
    • pytest (tests)
  2. Deploy job (on push to main):

    • rsync to VPS
    • Docker build
    • Docker compose up
    • Health verification

Workflow File

.github/workflows/deploy.yml

Troubleshooting

Login Rate Lock

If the account gets locked due to too many login attempts:

# Clear the lock from Redis
redis-cli DEL "login:lock:<identifier>"

Environment Changes

If you change .env variables, you must recreate the container:

docker compose up -d --force-recreate agent

Environment variables are baked at container creation time.

Checking Logs

docker compose logs -f agent

Restarting

docker compose restart agent

Testing

cd agent
 
# Run linting
ruff check src/
 
# Run tests
pytest tests/ -v

Test Coverage

6 tests covering:

  1. All domain tools are registered (>= 109 tools)
  2. Prompts are registered
  3. OpenAI tool schema conversion
  4. Agent loop: tool call then answer
  5. Agent loop: handles tool errors gracefully
  6. HTTP bridge endpoint
  7. Phone number normalization