# Drawbar deploy — `crop-chem-docs` MCP server snippet Drop this into Drawbar's `docker-compose.yml`. Targets the existing trashpanda stack: shared Docker network with `ollama` + `llama-rerank` service containers, Cloudflare Tunnel out front. ## Pre-reqs (one-time on the deploy host) 1. **Login to the Gitea registry** so the host can pull: ```bash docker login git.jpaul.io -u justin # PAT for password ``` 2. **`ollama` and `llama-rerank` services** are already running in the same compose stack on the same Docker network. The MCP container resolves them by service name via Docker's embedded DNS — no IPs to maintain. ## Compose service ```yaml services: crop-chem-docs: image: git.jpaul.io/justin/crop-chem-docs:corpus-2026.05.24 # :latest for dev / Watchtower auto-pull container_name: crop-chem-docs restart: unless-stopped ports: - "8001:8000" # MCP server (streamable-http). Adjust host port. # No environment block needed — the image's defaults handle it: # OLLAMA_URL=http://ollama:11434 # RERANK_URL=http://llama-rerank:8080 # HYBRID_SEARCH=true # PRODUCT_NAME=crop_chem # Override here only if your services have different names. networks: - default # or whichever shared network ollama/llama-rerank are on labels: com.centurylinklabs.watchtower.enable: "true" ``` If your stack uses non-default service names: ```yaml environment: OLLAMA_URL: "http://:11434" RERANK_URL: "http://:8080" ``` ## Test from the host ```bash # Verify counts + indexes from inside the container: docker exec crop-chem-docs python -c \ "from docs_mcp.server import corpus_status; print(corpus_status())" ``` ## What the container exposes | Tool | What it does | |---|---| | `search_docs` | Hybrid+rerank pesticide-label search with optional filters | | `get_page` | Full label markdown + metadata by `(source, source_key)` | | `list_versions` | Discover sources, product classes, signal words, registrants | | `corpus_status` | Counts + freshness; useful for health probes | | `crop_chem_api_lessons` | Curated agronomy / label-handling knowledge — call before recommending | ## Tag scheme | Tag | When | Use for | |---|---|---| | `:latest` | Every monthly refresh + every code push | Dev / Watchtower auto-pull | | `:` | Every build | Rollback pin | | `:corpus-YYYY.MM.DD` | Every build | **Production pin** (frozen corpus version) | ## Updating the corpus - **Monthly cron** — 1st @ 06:00 UTC, full re-scrape of Bayer + EPA PPLS, reindex, image push. Watchtower pulls the new `:latest` automatically. - **Manual** — Gitea Actions UI → `Monthly corpus refresh` → `Run workflow`. Optional `sources` input for single-source refresh (e.g., `bayer` only). ## Switching corpus scope The row-crop filter (corn/soybeans/wheat) is in `scrape/sources/epa_ppls.py` as `ROW_CROP_KEYWORDS`. Edit + push + let the next workflow run pick it up. Same for the registrant allowlist at `scrape/sources/epa_registrant_allowlist.json`.