From 95571e0f05bce2b2cdcb226e8c6733886e0d1f21 Mon Sep 17 00:00:00 2001 From: Chaim Date: Wed, 5 Aug 2026 13:58:08 +0000 Subject: [PATCH] =?UTF-8?q?fix(ops):=20=D7=99=D7=99=D7=A9=D7=95=D7=A8=20MU?= =?UTF-8?q?LTIMODAL=5FENABLED=20=D7=91=D7=A9=D7=A8=D7=AA=20=D7=94-MCP=20+?= =?UTF-8?q?=20=D7=AA=D7=99=D7=A2=D7=95=D7=93=20=D7=93=D7=A8=D7=99=D7=A4?= =?UTF-8?q?=D7=98=20=D7=94=D7=90=D7=97=D7=A1=D7=95=D7=9F=20=D7=A9=D7=A0?= =?UTF-8?q?=D7=95=D7=AA=D7=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit הקונטיינר והשרת ה-HTTP הם שתי דלתות לאותו קורפוס, ולכן חייבים לדרג אותו. הם לא עשו זאת: הקונטיינר רץ `MULTIMODAL_ENABLED=true`, בעוד שרת ה-MCP נפל לברירת-המחדל `false` — `~/.env` אינו מגדיר את הדגל כלל. סוכן ו-UI יכלו לענות על אותה שאלה מתוך קבוצות-תוצאות שונות, בלי שאיש ידע (G2 — מסלול מקביל שמתפצל בשקט). מה שונה - `MULTIMODAL_ENABLED: "true"` בקונפיג ה-pm2 של legal-mcp-http. - תיעוד השירות ב-operations-runbook (פורט, שער-Bearer, ו**האזהרה שהחשובה מכולן**: קוד ב-`mcp-server/` לא נכנס לתוקף עד restart — זהו תהליך ארוך-חיים, בניגוד ל-stdio שנטען בכל סשן. שלושה מיזוגים היום רצו על קוד ישן עד שהבחנתי). מה **לא** שונה, ולמה `STORAGE_BACKEND` נשאר לא-מוגדר. הקונטיינר רץ `s3`, השרת נופל ל-`filesystem`, וזה דריפט אמיתי — סוכן שכותב דרך MCP כותב לדיסק בעוד ה-web קורא מ-S3. אבל הפיכת הדגל דורשת `MINIO_ENDPOINT`/`ACCESS_KEY`/ `SECRET_KEY`, ואלה **אינם ב-Infisical** — רק ב-env של Coolify. בלעדיהם `MINIO_ENDPOINT` נפתר לברירת-המחדל `http://minio:9000` (שם-רשת פנימי של דוקר, לא נגיש מהמארח) וכל פעולת-בלוב נשברת. יצירת סוד חדש מחייבת אישור חיים לשם/תיקייה/תגית, ולכן הדריפט מתועד בבירור ב-runbook עם בדיוק מה שצריך כדי לסגור אותו — במקום להישאר ידיעה שבעל-פה. MinIO **כן** נגיש מהמארח: `https://s3.nautilus.marcusgroup.org` מחזיר 200 ב-`/minio/health/live` (אומת), כך שהחסם היחיד הוא הסודות. invariants: G2 (שתי דלתות, דירוג אחד) · §6 (הדריפט הנותר מתועד, לא נבלע) --- docs/operations-runbook.md | 22 ++++++++++++++++++++++ scripts/legal-mcp-http.config.cjs | 14 ++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/operations-runbook.md b/docs/operations-runbook.md index 19acd85..6755e07 100644 --- a/docs/operations-runbook.md +++ b/docs/operations-runbook.md @@ -52,6 +52,28 @@ - **אפס עלות API** — claude CLI משתמש ב-claude.ai subscription של chaim. הנחת היסוד של `claude_session.py` (claude CLI מקומי בלבד) נשמרת. - Coolify dependency: ה-Service Definition של legal-ai חייב להכיל `extra_hosts: host.docker.internal:host-gateway` (אחרת ה-proxy יקבל ConnectError). +### legal-mcp-http — שרת ה-MCP ב-HTTP (מאוגוסט 2026) +- פורט: `127.0.0.1:8790` (loopback בלבד) · קונפיג: [`scripts/legal-mcp-http.config.cjs`](../scripts/legal-mcp-http.config.cjs) +- **הדלת של סוכני הפלטפורמה** אל 108 כלי ה-MCP. סשן אינטראקטיבי מגיע לאותו שרת ב-stdio דרך `~/.claude.json` — **אותו קוד, שתי תחבורות** (G2). +- שער Bearer (`MCP_HTTP_SHARED_SECRET`); השרת **מסרב לעלות** בלי טוקן. בדיקה: ללא טוקן → `401`, עם טוקן → `200`. +- **⚠️ שינוי קוד ב-`mcp-server/` לא נכנס לתוקף עד `pm2 restart legal-mcp-http`.** זה תהליך ארוך-חיים, בניגוד ל-stdio שנטען מחדש בכל סשן. אחרי מיזוג שנוגע ב-`mcp-server/` — להפעיל מחדש, אחרת הסוכנים ירוצו על קוד ישן בשקט. + +> #### 🚨 דריפט תצורה פתוח — `STORAGE_BACKEND` +> הקונטיינר רץ `STORAGE_BACKEND=s3`; שרת ה-MCP נופל לברירת-המחדל `filesystem`, כי +> `~/.env` אינו מגדיר אותו. כלומר **סוכן שכותב קובץ דרך MCP כותב לדיסק, בעוד ה-web +> קורא מ-S3** — שני מסלולים שמתפצלים (G2 / INV-STG1). +> +> **למה זה עדיין לא תוקן:** ההעברה ל-s3 דורשת `MINIO_ENDPOINT` + `MINIO_ACCESS_KEY` + +> `MINIO_SECRET_KEY`, ואלה **אינם קיימים ב-Infisical** — רק ב-env של Coolify. הפיכת +> הדגל בלעדיהם תפתור את `MINIO_ENDPOINT` לברירת-המחדל `http://minio:9000` (שם-רשת +> פנימי של דוקר, לא נגיש מהמארח) ותשבור כל פעולת-בלוב. +> +> **מה שצריך כדי לסגור:** ליצור את שלושת המפתחות ב-Infisical תחת `/apps/legal-ai` +> (תגית `credentials`, באישור חיים — ראה כלל "Saving a NEW secret" ב-`~/CLAUDE.md`), +> לטעון אותם בקונפיג ה-pm2 כמו `MCP_HTTP_SHARED_SECRET`, ואז להוסיף +> `STORAGE_BACKEND: "s3"`. MinIO **כן** נגיש מהמארח: `https://s3.nautilus.marcusgroup.org` +> (אומת — `/minio/health/live` מחזיר 200). + --- ## מבנה תיקיות diff --git a/scripts/legal-mcp-http.config.cjs b/scripts/legal-mcp-http.config.cjs index ed34ff5..f0708f2 100644 --- a/scripts/legal-mcp-http.config.cjs +++ b/scripts/legal-mcp-http.config.cjs @@ -56,6 +56,20 @@ const env = { // transports read exactly the same corpus. DOTENV_PATH: "/home/chaim/.env", DATA_DIR: "/home/chaim/legal-ai/data", + // Retrieval flags must match the container's, or the two doors into the same + // corpus rank differently (G2 — a parallel path that drifts). The container + // runs MULTIMODAL_ENABLED=true; without this the MCP door skipped the + // page-image merge entirely, so an agent and the web UI could answer the same + // question from different result sets. ~/.env sets neither, so both fell to + // the code defaults (false) — the drift was silent. + // + // NOT set here: STORAGE_BACKEND. The container runs `s3`, this service falls + // back to `filesystem`, and closing that gap needs MinIO credentials that do + // not exist in Infisical yet (only in Coolify's env). Flipping the flag + // without them would resolve MINIO_ENDPOINT to the in-cluster default + // `http://minio:9000` — unreachable from the host — and break every blob + // read. Tracked separately; see the note in docs/operations-runbook.md. + MULTIMODAL_ENABLED: "true", MCP_TRANSPORT: "streamable-http", MCP_HTTP_HOST: "127.0.0.1", MCP_HTTP_PORT: "8790", -- 2.49.1