feat(mcp): הודעות שגיאה, הפרדת אאוטליין מקריאת תוכן, וטור כוונה ב-/admin/mcp

Merged
AM
2mo ago
+2075-481

✨ תיאור קצר

מסך /admin/mcp הציג עד עכשיו מספרים בלי סיבות: "20% שגיאות" בלי לומר למה, עמודה אחת שסופרת אאוטליין וקריאת תוכן יחד, ומזהי סשן אטומים. ה-PR מוסיף את שלושת החלקים החסרים, ומרחיב את שער הפרטיות ב-mcp_server/analytics.py — שהוא מה שפותח את כל השאר.

📦 שינויים עיקריים

  • קוד (Backend)
  • בוט טלגרם
  • מסד נתונים/מיגרציות
  • תיעוד (docs/)
  • DevOps/CI/CD

פירוט:

  • השער. $mcp_error_message נשלח על כל סוג שגיאה ולא רק על ValidationError, ו-$mcp_intent על כל אירוע ולא רק על $mcp_missing_capability. שניהם עדיין עוברים רק כשהערך מחרוזת — מילון תחת אותם שמות עבר גרסה קודמת של השער עם גוף קובץ בתוכו. $mcp_parameters ו-$mcp_response חסומים בכל מסלול, ו-$exception_list[*].value נשאר מושחר בכל אירוע. שני המנגנונים המותנים (_ALLOWED_BY_EVENT, _ALLOWED_BY_ERROR_TYPE) נמחקו ולא רוקנו: מילון ריק ששורד נראה כמו שער שעוד מחליט משהו, והבא שירצה להרחיב היה מושיט אליו יד.
  • לכידת הכוונה (context=True). $mcp_intent לא נוצר מעצמו — posthog.mcp מייצר אותו רק כשהאופציה דלוקה. פתיחת המאפיין בשער לבדה לא הייתה משנה דבר, ולכן האופציה נדלקה, עם תיאור פרמטר משלנו במקום ברירת המחדל של ה-SDK.
  • ck_read_mode. ההבחנה בין outline=true ל-lines= חיה בפרמטרים, והם חסומים ונשארים חסומים. במקום לפתוח אותם, השרת מחשב בעצמו תווית מקבוצה סגורה — outline / range / full — לפי נוכחות הפרמטר ולא לפי ערכו, והשער אוכף את הקבוצה.
  • העמוד. טבלת הקריאות שנכשלו מתחת לטבלת הכלים באותו טאב (היא הפירוט של עמודת השגיאות שכבר שם, לא טאב רביעי), שתי עמודות קריאה במקום אחת, טור כוונה מקוצץ עם הטקסט המלא ב-title, וההערה שאין להשוות בין סשנים בלי לדעת מה הייתה המשימה. בנוסף קישורים יוצאים לאשכולות הכוונות ולסיכומי הסשן ב-PostHog.
  • ב-PostHog: נוספו ck_mcp_tool_failures ו-ck_mcp_navigation_cost_v2. ck_mcp_navigation_cost (v1) נשאר חי כבסיס להשוואה; שום אנדפוינט לא נמחק.

🧪 בדיקות

  • Unit

  • Integration

  • Manual

  • tests/test_mcp_analytics_privacy.py — 68 עוברים.

  • tests/test_admin_mcp_page.py — 27 עוברים, דרך בקשת HTTP ומול ה-DOM המרונדר.

  • tests/test_mcp_analytics_service.py — 62 עוברים.

  • tests/test_admin_mcp_tabs_browser.py — 10 עוברים ב-Chromium אמיתי, כולל שלוש בדיקות חדשות: הטבלה הרחבה גוללת בתוך הכרטיס שלה ולא בגוף העמוד, title נושא את הכוונה המלאה, ותגית script בכוונה נשארת צומת טקסט ב-DOM.

  • הסוויטה המשולבת של קבצי ה-MCP: 319 עוברים.

מוטציות — 15, כל אחת מפילה טסט. context=False, הסרת event_properties, read_mode שנופל ל-full על כל אירוע, הסרת הוולידציה על המאפיין שלנו, ביטול בדיקת המחרוזת על הטקסט החופשי, החזרת החסימה על intent ועל error_message, חזרה לטור מאוחד, |safe על הכוונה, הסרת rel="noopener", הודעה ריקה שמוצגת כמילה "שגיאה", חזרה ל-v1, ובניית קישור בלי ולידציה.

מדידה מקצה לקצה מול השרת האמיתי (build_mcp + אינסטרומנטציה): אישרה שאין דליפת $mcp_parameters/$mcp_response, שהתוויות נכונות (outline ואז range), ושקריאה בלי context מגיעה לגוף הכלי.

בילד תיעוד: sphinx -b html יצא 0, אפס אזהרות Sphinx, והעוגן החדש mcp-read-mode נבנה ומקושר.

📝 סוג שינוי

  • feat: פיצ'ר חדש
  • breaking change: שינוי שובר תאימות (ראו "השפעות/סיכונים")

✅ צ'קליסט

  • הקוד עוקב אחרי הסגנון — flake8 --select=E9,F63,F7,F82 נקי; ממצאי ruff שנשארו קיימים מלפני ה-PR
  • בדיקות רצות ועוברות
  • תיעוד עודכן
  • ג'ובים חדשים — לא רלוונטי
  • משתני סביבה — לא נוספו ולא השתנו
  • טוקנים — לא נוספו. ה-CSS החדש משתמש בטוקנים קיימים בלבד (--card-bg, --code-text, --primary), עם fallback, לפי theming_and_css
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות
  • הודעת הקומיט תואמת Conventional Commits
  • docs/whats-new.rst עודכן
  • עיינתי במסמכי אתר התיעוד — נתיב: docs/mcp-server.rst (במלואו), docs/webapp/mcp-analytics.rst, docs/webapp/theming_and_css.rst, docs/doc-authoring.rst, docs/versioning-stable-anchors.rst, AI-MAP.md | המשפט: "התיעוד הוא התמצאות, לא סמכות. כל טענה עובדתית בו — התנהגות, נתיב, פרמטר, "נתמך" — קודם תאמת מול הקוד לפני שתסתמך עליה."

🧩 השפעות/סיכונים

1. שינוי חוזה מול לקוחות MCP. context=True מוסיף פרמטר context לסכימה המוצהרת של כל כלי, ומוסיף אותו לרשימת ה-required שלו. נמדד מול השרת האמיתי: קריאה שאינה מעבירה אותו אינה נדחית — הכלי רץ בדיוק כמו קודם, והפרמטר המוזרק אינו מגיע לגוף הכלי כלל (ה-SDK מסיר אותו). כלומר לקוח קיים אינו נשבר; מה שמשתנה הוא מה שרשימת הכלים מצהירה, ושסוכנים מתבקשים למשפט שלא התבקשו לו קודם. סומן כ-breaking בגלל שינוי הסכימה הפומבית, לא בגלל התנהגות שנשברה.

2. הרחבת הפרטיות — מודעת, ומתועדת במלואה. הודעת שגיאה של Pydantic נושאת את input_value ושומרת ראש וזנב סביב קיצוץ ל-50 תווים, ובשדה חובה חסר היא מדווחת את אובייקט הארגומנטים כולו. מאז הסרת הגידור לסוג אחד, גם הודעה של ספרייה יוצאת — חריגת pymongo יכולה לנקוב בכותרת שחיפשנו, ושגיאת מערכת בנתיב. מה שמצמצם את זה בפועל אינו השער אלא הקוד: repo_backend.py תופס רחב ומחזיר {"ok": false, ...} במקום לזרוק, ולכן רוב הכשלים אינם מגיעים לשם כחריגה — תכונה של הקוד היום, לא הבטחה של השער. האזהרה המלאה יושבת גם ב-docstring של המודול וגם ב-docs/mcp-server.rst, כדי שמסלול חדש שנותן לחריגה לעלות ייתקל בה.

3. שני הטורים החדשים ריקים לנתונים היסטוריים. בסשן שנרשם לפני הדיפלוי אין כוונה שמורה, ולא נשמר מצב קריאה — ולכן כל קריאות הקובץ שלו נספרות כקריאת תוכן. באותו אופן, קריאה שנכשלה לפני שההודעות נשמרו מוצגת עם —: הצינזור קרה בזמן השליחה ואינו הפיך. תא ריק אינו כשל, וההבחנה הזו נבדקת במפורש.

4. סטייה מהתוכנית, לדיווח. התוכנית אמרה "$mcp_error_message נחסם היום ויש לפתוח אותו". בפועל הוא כבר נפתח ב-PR #3319, מגודר ל-ValidationError; מה שנעשה כאן הוא הסרת הגידור. וההערה בתוכנית ש"שתיים מחמש השגיאות לא נושאות $mcp_error_type" אינה מדויקת — נבדק מול הנתונים: כל החמש נושאות, ושלוש מהן יציגו — כי הן נקלטו לפני שההודעות נשמרו כלל. המסקנה שבתוכנית נכונה, הנימוק והמספר לא.

🔗 קישורים

  • קשור לאזור של #3327 (הרחבת האינטגרציה עם PostHog)
  • docs/mcp-server.rst → mcp-analytics, mcp-read-mode
  • docs/webapp/mcp-analytics.rst → mcp-analytics-columns

🧯 סיכון / החזרה לאחור (Rollback)

הכל הפיך ובלי מיגרציה. revert של הקומיט מחזיר את context=False (הסכימות חוזרות לקדמותן), את הגידור על ההודעה, ואת הטור המאוחד. שני האנדפוינטים החדשים ב-PostHog נשארים שם ופשוט מפסיקים להיקרא, ו-ck_mcp_navigation_cost (v1) ממשיך לעבוד כי מעולם לא נגענו בו. שום נתון שנאסף אינו נמחק.


🤖 Generated with Claude Code

https://claude.ai/code/session_018YKyee3UAYEbTKFjxdmBjs


Generated by Claude Code

Summary by Sourcery

Expand MCP analytics privacy-safe observability and improve the admin dashboard with actionable failure, intent, and navigation metrics.

New Features:

  • Add MCP intent capture and expose session intent in the admin analytics dashboard.
  • Add read-mode analytics distinguishing outline, range, and full content reads without exposing tool parameters.
  • Add failure details, PostHog navigation links, and expanded navigation metrics to the MCP admin page.

Bug Fixes:

  • Prevent malformed or non-string analytics properties from bypassing privacy filtering.
  • Ensure outbound PostHog links reject hosts containing embedded credentials.
  • Share secret redaction across the MCP primer and analytics payloads.

Enhancements:

  • Broaden error-message reporting to all MCP error types while continuing to block parameters, responses, and exception values.
  • Enforce closed allowlists for free-text metadata, intent sources, and derived read-mode values.
  • Improve admin dashboard accessibility, responsive table behavior, safe rendering, and handling of missing historical data.

Documentation:

  • Update MCP server and analytics documentation with privacy behavior, intent capture, read-mode metrics, and dashboard changes.
  • Add the changes to the What's New documentation.

Tests:

  • Expand privacy, analytics-service, admin-page, and browser coverage for intent capture, read modes, error details, safe links, redaction, and responsive rendering.

Chores:

  • Document development workflow guidance for pull-request follow-up and local documentation builds.