הסוכן הקידוד שלך טוב מאוד במציאת דברים במאגר, כל עוד הם טקסט. שאל את Claude Code או Cursor מה אומר גיליון הנתונים של החיישן לגבי טמפרטורת הפעולה והוא מריץ grep, לא מוצא דבר, ויכול לנחש או לוותר, מכיוון שהגיליון הוא קובץ PDF ורשומת ההחלטה היא קובץ Word. GroupDocs.Search.Mcp פועל מקומית ב‑Docker ומספק לסוכן אינדקס טקסט מלא על המסמכים האלה, עם לולאת חיפוש‑ואז‑קריאה זהה לזו שכבר הוא משתמש בקוד:

אינדקס את תיקיית docs, ואז אמור לי מה אומר גיליון הנתונים של החיישן לגבי טמפרטורת הפעולה ואיזה ADR קבע את אחסון הטלמטריה.

הגרסה שלב‑אחר‑שלב עם תצורה ופתרון בעיות נמצאת בתיעוד: כיצד לאפשר ל‑Claude Code או Cursor לחפש בקבצי PDF ו‑Word במאגר.

למה grep מחזיר תוצאה ריקה?

מפני ש‑PDF ו‑DOCX אינם מאחסנים את המילים שלהם כטקסט פשוט. קובץ DOCX הוא ארכיון zip; קובץ PDF מכווץ את זרמי הטקסט שלו. חיפוש בתים‑ב‑תים לא ימצא את המילים. בדקנו זאת במאגר קטן: גיליון נתונים PDF אחד, רשומת החלטת ארכיטקטורה ומסמך דרישות ב‑DOCX, וקובץ מקור.

$ grep -ri "TimescaleDB\|operating temperature\|I2C" docs/
$ grep -rn "datasheet" src/
src/sensor.py:1:MAX_TEMP_C = 85  # see docs/datasheet

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

מה משתנה עם אינדקס?

הסוכן מקבל כלי אחזור למסמכים. רשום את השרת משורש המאגר, כך שהמאגר יותקן כתיקיית האחסון:

claude mcp add groupdocs-search -- docker run --rm -i \
  -v "$(pwd)":/data ghcr.io/groupdocs-search/search-net-mcp:latest

לאחר מכן אותן שאלות מחזירות תשובות. זה מה שהשרת החזיר במאגר הבדיקה שלנו (נתיבים מוצגים יחסית לשורש המאגר):

-> add_to_index {"documentsPath":"docs","indexName":"gateway"}
<- Indexed 'docs' into index 'gateway': 3 document(s) added,
   3 in the index.

-> search {"query":"TimescaleDB","indexName":"gateway"}
<- documentsFound 1: docs/adr-007-telemetry-storage.docx

-> get_text_fragments {"query":"I2C","indexName":"gateway"}
<- === docs/requirements-v2.docx (1 occurrence(s)) ===
     …REQ-15: the I2C bus runs at 400 kHz.…
   === docs/tmp117-sensor-datasheet.pdf (1 occurrence(s)) ===
     …I2C address selection: ADD0 pin to GND gives 0x48…

שאילתה אחת מצאה את הדרישה ואת השורה בגיליון הנתונים יחד, שזה סוג של הפנייה חוצת‑קבצים שמאוד מעייפת לבצע ידנית ובלתי אפשרית עם grep. באינדקס הקטן שלנו, חיפושים חזרו בתוך 80 עד 240 מילישניות אחרי הקריאה הראשונה.

הלולאה שהסוכן כבר יודע

user              agent                         Search MCP server
 |  "What does the datasheet say about I2C addresses?"         |
 |---------------->|                                           |
 |                 |-- search {"query":"I2C"} --------------->|
 |                 |<- requirements-v2.docx,                   |
 |                 |   tmp117-sensor-datasheet.pdf ------------|
 |                 |-- get_text_fragments {"query":"I2C"} --->|
 |                 |<- "...ADD0 pin to GND gives 0x48..." -----|
 |<- "0x48 with ADD0 to GND, 0x49 to V+ (datasheet, p.1);      |
 |    REQ-15 runs the bus at 400 kHz."                         |

search משיב אילו קבצים, get_text_fragments מחזיר את השורות המתאימות עם כמה מילים של הקשר, והסוכן מצטט את שניהם. זהו המבנה של grep, מורחב ל‑82 פורמטים: PDF, DOCX, XLSX, PPTX, HTML, Markdown, אפילו שרשורי האימייל שמישהו ייצא למאגר.

הודע לסוכן מתי להשתמש בו

סוכנים פועלים לפי הוראות הפרויקט מתי להשתמש בכלי. שלוש שורות ב‑CLAUDE.md או AGENTS.md יוצרות את ההבדל בין סוכן שמנסה grep, נכשל ונותן up, לבין סוכן שמחפש באינדקס תחילה:

PDF, DOCX and XLSX files under docs/ are indexed in the groupdocs-search MCP index
'docs'. grep cannot read them: use search (quote phrases) and get_text_fragments
for anything in specs, datasheets or ADRs, and cite the file.
Run update_index (indexName: docs) after pulling changes.

שתי נקודות תחזוקה. האינדקס נכתב ל‑.groupdocs-search-index/ בשורש התיקייה המותקנת, ולכן יש להוסיף זאת ל‑.gitignore. ולאחר משיכה, update_index קורא מחדש רק מה שהשתנה, כך שהשמירה על האינדקס עדכני עולה קריאה אחת.

Cursor ו‑VS Code

הקונטיינר זהה עובד בכל לקוח MCP. ב‑VS Code, סביבת עבודה .vscode/mcp.json יכולה להתקין כל תיקייה פתוחה, ולכן האינדקס עוקב אחרי הפרויקט:

{
  "servers": {
    "groupdocs-search": {
      "type": "stdio",
      "command": "docker",
      "args": [ "run", "--rm", "-i",
                "-v", "${workspaceFolder}:/data",
                "ghcr.io/groupdocs-search/search-net-mcp:latest" ]
    }
  }
}

Cursor משתמש באותו command ו‑args תחת mcpServers ב‑.cursor/mcp.json. בצע commit לקובץ התצורה וכל מפתח בפרויקט יקבל את הכלי; שמור את האינדקס עצמו מחוץ ל‑git.

למה לא להמיר הכל לטקסט תחילה?

אפשר: לתת לסוכן להמיר כל PDF כשצריך, או לבדוק עותקי Markdown במאגר. שני הפתרונות עובדים למספר מצומצם של קבצים. האינדקס מבצע את ההמרה פעם אחת, משמר אותו עדכני בקריאה אחת, ומשיב איזו קובץ חשוב לפני שהסוכן קורא כלום, וזה הצעד שמקטין את הקשר של סשן ארוך. המנוע שמאחורי זה הוא GroupDocs.Search, הקורא מסמכי Office ו‑PDF ישירות במקום דרך ממיר שעליך לתחזק.

מגבלות כנות

  • במצב הערכה אינדקס מכיל לכל היותר 100 מסמכים וחיפוש מחזיר לכל היותר 10; קרא get_license_status תחילה.
  • טקסט מלא, לא סמנטי: על הסוכן להשתמש במילים שהמסמכים משתמשים בהן, או לנסות וריאנטים.
  • אין OCR: גיליון נתונים סרוק ללא שכבת טקסט מאונדקס רק לפי מאפייני הקובץ.
  • Docker בלבד. בלינוקס, הוסף --user "$(id -u):$(id -g)" כדי שהקונטיינר יוכל לכתוב את האינדקס למאגר שאתה בעליו.

שאלות נפוצות

האם Claude Code יכול לקרוא קבצי PDF במאגר שלי?
לא עם grep. עם שרת GroupDocs.Search MCP הוא יכול לחפש ולצטט אותם, מקומית, ללא צורך להמיר אותם תחילה.

האם זה עובד גם ב‑Cursor וב‑VS Code?
כן. השתמש באותם ארגומנטים של docker run ב‑.cursor/mcp.json או ב‑.vscode/mcp.json; VS Code יכול להתקין את ${workspaceFolder}.

האם האינדקס יגיע למחויבות שלי?
רק אם תאפשר זאת. הוסף .groupdocs-search-index/ ל‑.gitignore.

צלילה עמוקה