Skip to content

fix(mcp): מחרוזת שנראית כמו JSON מגיעה לכלי כמחרוזת — pre_parse_json מדלג על פרמטרי str (#3471) - #3485

Merged
amirbiron merged 2 commits into
mainfrom
claude/laughing-edison-6cxh82
Sep 29, 2026
Merged

amirbiron merged 2 commits into
mainfrom
claude/laughing-edison-6cxh82

Conversation

@amirbiron

@amirbiron amirbiron commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

✨ תיאור קצר

לפני הוולידציה ה-SDK של mcp מריץ FuncMetadata.pre_parse_json: כל מחרוזת שנשלחת לפרמטר שאינו מוצהר str בדיוק עוברת json.loads, ו-None, רשימה או מילון מחליפים אותה. בפרמטר str | None זה היה באג שקט: "null" נהיה "לא נשלח", ולכן query="null" ו-section="null" החזירו את הקובץ המלא. התיקון יושב בתפר שכבר קיים — AdminAwareFastMCP.add_tool — ומוציא מהפענוח כל פרמטר שה-annotation שלו כולל str, כך שהמחרוזת מגיעה לכלי כמו שנשלחה.

Closes #3471

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

  • קוד (Backend)

  • בוט טלגרם

  • מסד נתונים/מיגרציות

  • תיעוד (docs/)

  • DevOps/CI/CD

  • mcp_server/server.py — AdminAwareFastMCP.add_tool מאתר את הכלי שה-SDK יצר זה עתה (השם שלא היה רשום לפני הקריאה — בלי לגזור מחדש את כלל השמות של ה-SDK), ומחליף את tool.fn_metadata ב-_RawStringMetadata: תת-מחלקה של FuncMetadata שמוציאה את מפתחות המחרוזת לפני שה-SDK מפענח, ומעבירה את כל השאר אליו. _offload_to_thread, _declares_write ו-tool.fn לא השתנו.

  • הכלל (_keeps_raw_string) נגזר מ-FieldInfo.annotation — אותו שדה ש-pre_parse_json קורא — ולא מרשימת שמות, ומכריע במפורש על כל צורה:

    • str, לבד או לצד None/int/float/bool ← מדלגים על הפענוח.
    • בלי str ← ה-SDK ממשיך כרגיל (lines, items — Claude Desktop שולח רשימות כמחרוזות JSON).
    • str לצד רשימה/מילון/tuple/set/מודל, Any/object, או צורה שהכלל לא מכיר ← TypeError ברישום, עם הסיבה, והכלי מוסר — כמו כלי כתיבה אסינכרוני.
    • שם השדה וגם ה-alias (ה-SDK משנה שם לפרמטר שמצל על מתודה של BaseModel, למשל json).
    • מטא-דאטה שאינה בדיוק FuncMetadata ← TypeError, כדי שמחלקה חדשה של ה-SDK לא תאבד בהעתקה את מה שהיא מוסיפה.
  • ההערה ב-build_mcp טענה ש-PostHog "no tool schema is touched" — בסתירה ל-instrument_mcp_server, שמזריק context לכל סכימה. תוקנה.

  • docs/mcp-server.rst — נמחקו שתי השורות שתיעדו את "null" (במצבי הקצה של mcp-file-sections, ובטבלת "פתרון תקלות"), והפסקה על pre_parse_json בסעיף content_changed עודכנה: מעכשיו זה נכון לכל פרמטר שמקבל מחרוזת.

  • docs/whats-new.rst — רשומה ל-2026-09-29.

  • tests/test_mcp_content_sha256.py — רק ה-docstring: המוטציה code: str | None הפילה שם שלוש בדיקות לפני התיקון, ועכשיו עוברת (נמדד בשני הכיוונים). הטסט עצמו לא השתנה.

🧪 בדיקות

  • Unit
  • Integration (session אמיתי של הפרוטוקול, PostHog אמיתי עם send=False)
  • Manual

tests/test_mcp_pre_parse_json.py (55 בדיקות), כולן דרך call_tool:

  1. כל פרמטר מחרוזת בכל כלי רשום מקבל את "null", "[1, 2]" ו-'{"a": 1}' כמו שנשלחו. הפרמטרים נגזרים מהסכימה שמוצהרת ללקוח (קוד של pydantic) ולא מהכלל שנבדק, ולכן הרשימה אינה טאוטולוגית. המספר 28 לא מקובע; נבדק רק שרשימת האישו מוכלת במה שכוסה.
  2. בקרה שלילית: lines="[5, 10]" ב-get_file וב-get_repo_file, ו-items כמחרוזת JSON ב-read_batch, עדיין מפוענחים.
  3. קצה-לקצה עם גוף אמיתי: query="null" מחפש את המילה; "[1, 2]"/'{"a": 1}' הם חיפוש מילולי; כותרת ששמה null נקראת בשמה; קובץ ששמו null נמצא; docs_get_section(section="null") מחזיר סעיף ולא מפה; update_note(content="null") כותב את המילה — נבדק במצב שהגיע לשכבת הכתיבה, לא בתשובת הכלי.
  4. PostHog דלוק: build_mcp אמיתי, לקוח Posthog אמיתי, וכל הקריאות ב-session אמיתי. נבדק ש-context מופיע כחובה בכל סכימה (כלומר אלו הסכימות של הייצור), שהמחרוזות מגיעות כמו שנשלחו, ושה-context המוזרק לא מגיע לכלי.
  5. הכלל ברישום: str | list[str] (ועוד תשע צורות) מפיל את הרישום עם הסיבה הנכונה, והכלי אינו רשום אחרי הסירוב.
  6. ה-SDK: הגרסה הנעוצה ב-requirements/base.txt = המותקנת; ה-SDK עדיין קורא ל-self.pre_parse_json (נספר); וה-SDK לבדו עדיין ממיר "null" ל-None (אם יתקנו upstream — הטסט ייפול, וזה הסימן לבדוק אם השכבה עדיין נחוצה).

ריצת בקרה על הקוד שלפני התיקון (5d7fdc2, ב-worktree נפרד): 43 נופלות, 12 עוברות. ה-12 הן בדיוק מה שאמור לעבור בשני המצבים: הבקרה השלילית, str בדיוק, שני שומרי ה-SDK, ובדיקת ההכלה של רשימת האישו. הנפילה בטסט הפרמטרי היא 28 שורות של sent 'null', the tool received None — הבאג כלשונו.

מוטציות (על עותק ב-git worktree, כל אחת החלפה מדויקת אחת):

מוטציה תוצאה
M1 לבטל את הפענוח לכל המפתחות 7 נופלות — הבקרה השלילית, ריצת PostHog, ו-list/dict/מודל
M2 str לצד container לא מסורב 5 נופלות
M3 Any מאבד את הסירוב המפורש שלו 3 נופלות (לפי הסיבה בהודעה)
M4 ה-alias לא מוחזק 1 נופלת
M5 add_tool לא מחליף מטא-דאטה 43 נופלות
M6 כלי מסורב נשאר רשום 10 נופלות
M7 צורה לא מוכרת נשמרת (ניחוש) 2 נופלות
M8 רק str | None נחשב טקסט 9 נופלות
M9 מודל לא נחשב container 2 נופלות
M10 Annotated לא מקולף 14 נופלות
M11 typing.Union לא מטופל 17 נופלות
M12 מחלקת המטא-דאטה לא נבדקת 1 נופלת
M13 str | list[str] | None בכלי אמיתי (codekeeper_list_versions) השרת לא נבנה; TypeError נוקב בכלי ובפרמטר

שאר הסוויטה (-n auto --dist=loadscope, כמו ב-CI, Python 3.11):

  • כל טסטי ה-MCP: 1723 עברו, 36 דולגו (לפני: 1668 עברו, 36 דולגו — אותם דילוגים של "דורש מונגו אמיתי").
  • הסוויטה כולה: 6787 עברו, 5 נפלו — כולן ב-tests/test_infrastructure.py::TestEnvironmentTools, ובודקות ש-isort/autopep8 ב-PATH. אומת שהן נופלות זהה על הבסיס, ועוברות כשה-venv ב-PATH — סביבתי, לא קשור.
  • כל 1460 הטסטים שקוראים קובצי תיעוד רצו שוב אחרי עריכת ה-rst — עברו.
  • flake8 (החוסם) נקי; ruff ו-mypy — אותם ממצאים בדיוק כמו בבסיס, אין חדשים.
  • לא אומת: ריצה על Python 3.12 (ה-CI מריץ גם אותו); הטסטים נשענים על typing ו-pydantic באופן שזהה בשתי הגרסאות, אבל לא הרצתי.

🧪 בדיקות נדרשות ב‑PR

  • 🔍 Code Quality & Security
  • Unit Tests (3.11)
  • Unit Tests (3.12)

📝 סוג שינוי

  • feat: פיצ'ר חדש
  • fix: תיקון באג
  • docs: שינוי תיעוד בלבד
  • refactor: שינוי קוד ללא שינוי התנהגות
  • perf: שיפור ביצועים
  • chore/ci: תשתית/CI
  • breaking change: שינוי שובר תאימות

✅ צ'קליסט

  • הקוד עוקב אחרי הסגנון (Black/isort/flake8/mypy)
  • בדיקות רצות ועוברות
  • תיעוד עודכן (README/Docs)
  • אם נוספו ג'ובים חדשים (Background Jobs) — לא רלוונטי
  • אם נוספו/שונו משתני סביבה — לא רלוונטי
  • אם נוספו/השתנו טוקנים — לא רלוונטי
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות/פעולות על root
  • הודעת הקומיט תואמת Conventional Commits
  • CHANGELOG עודכן אם נדרש (docs/whats-new.rst)
  • כל ה‑Required Checks לעיל ירוקים — ממתין ל-CI
  • צילום/וידאו UI — לא רלוונטי
  • עיינתי במסמכי אתר התיעוד — נתיב: docs/mcp-server.rst | המשפט: "הקולבק מקבל את מילון הארגומנטים הגולמי — לפני ש-pydantic מסלק ממנו מפתחות שאינם בסכימה של הכלי"

עיון ב-CodeBot – Project Docs: AI-MAP.md; ב-docs/mcp-server.rst — "מצבי הקצה" של mcp-file-sections, "פתרון תקלות", "טביעת אצבע לתוכן" › "תשובות הכתיבה: content_changed", "מדידת שימוש" › "לכידת הכוונה (context)" ו"מצב הקריאה (ck_read_mode)"; docs/doc-authoring.rst (לפני עריכת ה-rst — כולל "ספירות בפרוזה"); docs/versioning-stable-anchors.rst (לא נמחק ולא שונה אף עוגן). מחוץ לריפו (Ck): Ck-MCP-Handoff.md — "מודל הריצה של הכלים" כולו, "מוסכמות" כולו, "הערך שהכלי מקבל אינו תמיד הערך שנשלח", "שער הפרטיות", "run_in_executor אינו מעתיק contextvars"; לקחי-RST-להרחבת-האאוטליין-ל-md.md סעיפים 10 ו-13.

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

  • שינוי התנהגות מכוון: מחרוזת שנשלחת לפרמטר מסוג "מחרוזת או null" מגיעה לכלי כמחרוזת. סוכן ששלח "null" כדי לומר "לא נשלח" (אין סיבה לעשות זאת — משמיטים את הפרמטר, או שולחים null של JSON) יקבל עכשיו חיפוש של המילה.
  • שדרוג ה-SDK: הבדיקה ב-pre_parse_json זהה גם ב-mcp 1.30.0 וגם ב-2.2.0 (נקרא מהמקור, 29.09) — שדרוג לא מייתר את התיקון. ב-2.x mcp.server.fastmcp מוחלף במודול שזורק ModuleNotFoundError בכוונה, כלומר שדרוג כזה ייפול בייבוא ולא יחזיר את הבאג בשקט.
  • ביצועים: שתי קריאות list_tools() לכל רישום (בעלייה בלבד), ובכל קריאת כלי — שני dict comprehension על הארגומנטים. גוף טקסט גדול (פתק, למשל) כבר לא עובר json.loads.
  • ממצא שלא טופל כאן: FastMCP(tools=[...]) רושם כלים בלי לעבור ב-add_tool, כך שכלי שיירשם כך יעקוף גם את _offload_to_thread וגם את התיקון הזה. אף אחד לא משתמש בזה היום, ושני טסטים מבניים (test_every_registered_tool_is_a_coroutine_function, test_every_registered_tool_carries_the_string_preserving_metadata) תופסים את זה ב-build_mcp.

🔗 קישורים

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

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

🤖 Generated with Claude Code

https://claude.ai/code/session_01MEsSHNcaSFuF5dKwQkQcLC


Generated by Claude Code

Review in cubic

Summary by Sourcery

Preserve text arguments at the MCP boundary while retaining JSON parsing for collection-oriented parameters.

Bug Fixes:

  • Preserve JSON-looking strings for MCP tool parameters that accept text, including optional and scalar-union string annotations, so values such as "null", arrays, and objects reach tools unchanged.

Enhancements:

  • Retain SDK JSON parsing for parameters that do not accept strings and reject ambiguous annotation shapes during tool registration instead of guessing.
  • Update MCP documentation and changelog entries to reflect the corrected string-handling behavior and PostHog schema instrumentation.

Documentation:

  • Remove outdated documentation describing JSON-looking "null" values as omitted and clarify the scope of MCP pre-parsing behavior.

Tests:

  • Add comprehensive MCP tests covering tool calls, production PostHog sessions, registration validation, SDK behavior, aliases, and regression scenarios.

…מדלג על פרמטרי str (#3471)

ה-SDK מריץ FuncMetadata.pre_parse_json לפני הוולידציה: כל מחרוזת שנשלחת
לפרמטר שאינו מוצהר str בדיוק עוברת json.loads, ו-None, רשימה או מילון
מחליפים אותה (נמדד על mcp 1.28.1). בפרמטר str | None המחרוזת "null" נהייתה
"לא נשלח" — query="null" ו-section="null" החזירו את הקובץ המלא — ו-"[1, 2]"
ו-'{"a": 1}' נדחו כ"לא מחרוזת".

AdminAwareFastMCP.add_tool, שכבר עוטף כל כלי ב-_offload_to_thread, מחליף
עכשיו את מטא-הדאטה של הארגומנטים ב-_RawStringMetadata: פרמטר שה-annotation
שלו כולל str (לבד, או לצד None/int/float/bool) יוצא מהפענוח, וכל השאר נשאר
אצל ה-SDK — lines ו-items ממשיכים לקבל JSON כמחרוזת (Claude Desktop).
str לצד רשימה/מילון/tuple/set/מודל, Any, או צורה לא מוכרת — TypeError ברישום,
והכלי מוסר. ההכרעה נגזרת מ-FieldInfo.annotation, אותו שדה ש-pre_parse_json
קורא, ולא מרשימת שמות.

tests/test_mcp_pre_parse_json.py עובר על כל הכלים הרשומים (הפרמטרים נגזרים
מהסכימה המוצהרת), בקרה שלילית, קצה-לקצה עם גוף אמיתי, ריצה עם PostHog דלוק
ב-session אמיתי, הכלל ברישום, והתפר של ה-SDK. על 5d7fdc2: 43 נופלות, 12 בקרות
עוברות. 13 מוטציות על עותק — כולן נתפסות.

תיעוד: שתי השורות על "null" נמחקו מ-mcp-server.rst, ההסבר על pre_parse_json
בסעיף content_changed עודכן, ו-whats-new. ההערה ב-build_mcp שטענה ש-PostHog
אינו נוגע בסכימה תוקנה. ארגומנט שאינו בסכימה — #3484.

Closes #3471

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEsSHNcaSFuF5dKwQkQcLC
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @amirbiron, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 15 hours and 9 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 5 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: bd99dbcd-8b45-4612-935b-c163a2c1e2d4

📥 Commits

Reviewing files that changed from the base of the PR and between c5cda21 and c9724a3.

📒 Files selected for processing (5)
  • docs/mcp-server.rst
  • docs/whats-new.rst
  • mcp_server/server.py
  • tests/test_mcp_content_sha256.py
  • tests/test_mcp_pre_parse_json.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@sourcery-ai

sourcery-ai Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The PR fixes MCP argument corruption by selectively bypassing the SDK’s JSON pre-parser for parameters whose annotations accept strings, while preserving decoding for list/object-oriented parameters. It validates unsupported annotation shapes and metadata changes at registration, adds extensive end-to-end and mutation-oriented regression coverage, and updates related documentation.

Sequence diagram for preserving raw MCP string arguments

sequenceDiagram
    participant Client
    participant MCP as AdminAwareFastMCP
    participant Tool as MCP Tool
    participant SDK as FuncMetadata

    Client->>MCP: call_tool(name, arguments)
    MCP->>Tool: invoke tool
    Tool->>SDK: call_fn_with_arg_validation(arguments)
    SDK->>SDK: pre_parse_json(arguments)
    Note over SDK: _RawStringMetadata removes raw string keys first
    SDK-->>Tool: validate and call with original string values
    Tool-->>Client: tool result
Loading

Flow diagram for MCP argument annotation decisions

flowchart TD
    A[Tool registration] --> B[Read arg_model.model_fields]
    B --> C{Annotation includes str?}
    C -->|No| D[Keep SDK JSON pre-parse]
    C -->|Yes| E{Only scalar alternatives?}
    E -->|str, None, int, float, bool| F[Mark field and alias as raw string]
    E -->|Container or model| G[Reject registration with TypeError]
    E -->|Any, object, or unknown shape| G
    F --> H[Replace fn_metadata with _RawStringMetadata]
    D --> I[Register tool]
    H --> I
Loading

File-Level Changes

Change Details Files
Preserve raw string arguments while retaining the SDK’s JSON decoding for non-string parameters.
  • Add explicit annotation analysis for unions, Annotated types, aliases, scalar combinations, containers, models, Any/object, and unsupported shapes.
  • Wrap the SDK metadata with a subclass that removes only designated string keys before delegating the remaining arguments to FuncMetadata.pre_parse_json.
  • Integrate metadata replacement into tool registration by identifying newly created SDK tools, rejecting unsupported metadata or annotations, and removing refused tools.
  • Update build_mcp documentation to accurately describe PostHog’s schema/context injection behavior.
mcp_server/server.py
Add broad regression and compatibility coverage for the pre-parse behavior.
  • Verify JSON-looking strings remain strings across registered tools, real end-to-end file/docs/note flows, and PostHog-enabled protocol sessions.
  • Verify list and model parameters without str continue to decode JSON text.
  • Test registration-time refusal behavior, aliases, annotation forms, metadata type changes, SDK hook usage, and bypassing registration paths.
  • Add SDK pin/runtime and upstream-behavior guard tests.
tests/test_mcp_pre_parse_json.py
Align existing documentation and test commentary with the corrected string handling behavior.
  • Remove obsolete documentation describing 'null' string edge cases.
  • Clarify that all string-accepting parameters are protected from SDK pre-parsing.
  • Add the fix to the changelog and update the content hash test docstring.
docs/mcp-server.rst
docs/whats-new.rst
tests/test_mcp_content_sha256.py

Assessment against linked issues

Issue Objective Addressed Explanation
#3471 Prevent MCP's pre-parse JSON conversion from changing string values for parameters whose annotations include str, including str None, so values such as "null", "[1, 2]", and "{"a": 1}" reach tools unchanged. ✅
#3471 Preserve the existing JSON pre-parsing behavior for parameters that do not accept strings, while handling aliases and rejecting ambiguous annotation shapes rather than silently choosing incorrect behavior. ✅
#3471 Add regression coverage and update documentation so all affected registered string parameters are tested, representative read/write behaviors are verified, and the old "null" behavior is no longer documented. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

Copy link
Copy Markdown
Contributor

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 128

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]
./README.md:829:find . -name "__pycache__" -exec rm -rf {} +
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build
./docs/Makefile:24:	rm -rf $(BUILDDIR)

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

📖 Documentation Preview

The documentation has been built successfully!

To view locally:

  1. Download the artifacts
  2. Extract the zip file
  3. Open index.html in your browser

@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kilo-code-bot

kilo-code-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • mcp_server/server.py - Core fix: _RawStringMetadata, annotation analysis, registration logic
  • tests/test_mcp_pre_parse_json.py - 55 new tests (6 groups)
  • tests/test_mcp_content_sha256.py - Docstring update
  • docs/mcp-server.rst - Removed outdated null troubleshooting, updated content_sha256 docs
  • docs/whats-new.rst - Changelog entry

Reviewed by nemotron-3-ultra-550b-a55b:free · Input: 0 · Output: 0 · Cached: 0

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@amirbiron
amirbiron merged commit b6000d4 into main Sep 29, 2026
30 checks passed
amirbiron pushed a commit that referenced this pull request Sep 29, 2026
…הלקוח ממיר אותו לפני השליחה

אחרי ש-#3485 עלה לייצור, query="null" ו-section="null" מהלקוחות האלה
עדיין מחזירים את הקובץ המלא, וקובץ ששמו null אינו נמצא לפי file_name.
השרת תקין: המחרוזת פשוט לא מגיעה אליו. בפרמטר שהסכימה שלו מתירה null,
הלקוח ממיר את המילה null ל-null של JSON עוד לפני שהבקשה יוצאת.

נמדד ב-29.09.2026 מול claude-code 2.1.284 ו-Anthropic/ClaudeAI 1.0.0:
- Claude Code: ה-input של קריאת הכלי בתמליל הוא {"query": null},
  {"section": null}, {"file_name": null}, {"content": null}. בפרמטר
  שהסכימה שלו string בלבד (create_note, save_file.description) המילה
  יוצאת כמחרוזת, ו-[1, 2] / {"a": 1} יוצאים כמחרוזות גם לפרמטר שמתיר
  null. "null" עם מירכאות יוצא עם המירכאות — אין דרך לשלוח את המילה לבדה.
- claude.ai: ck_read_mode ב-PostHog נגזר מהארגומנטים כמו שהגיעו לשרת.
  כיול על Claude Code: {"query": null} תויג full, ומחרוזת תויגה query.
  שתי הקריאות של claude.ai ל-query="null" תויגו full.

השורות על "null" שהוסרו ב-#3485 מ-mcp-file-sections ומטבלת "פתרון
תקלות" חוזרות, עם הסיבה הנכונה ועם העקיפה: כותרת ששמה null נקראת ב-lines
לפי ה-line_range מהמפה, וקובץ ששמו null לפי file_id — שתיהן נבדקו מול
השרת. ורשומה ב-whats-new.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEsSHNcaSFuF5dKwQkQcLC
amirbiron added a commit that referenced this pull request Sep 29, 2026
…הלקוח ממיר אותו לפני השליחה (#3488)

אחרי ש-#3485 עלה לייצור, query="null" ו-section="null" מהלקוחות האלה
עדיין מחזירים את הקובץ המלא, וקובץ ששמו null אינו נמצא לפי file_name.
השרת תקין: המחרוזת פשוט לא מגיעה אליו. בפרמטר שהסכימה שלו מתירה null,
הלקוח ממיר את המילה null ל-null של JSON עוד לפני שהבקשה יוצאת.

נמדד ב-29.09.2026 מול claude-code 2.1.284 ו-Anthropic/ClaudeAI 1.0.0:
- Claude Code: ה-input של קריאת הכלי בתמליל הוא {"query": null},
  {"section": null}, {"file_name": null}, {"content": null}. בפרמטר
  שהסכימה שלו string בלבד (create_note, save_file.description) המילה
  יוצאת כמחרוזת, ו-[1, 2] / {"a": 1} יוצאים כמחרוזות גם לפרמטר שמתיר
  null. "null" עם מירכאות יוצא עם המירכאות — אין דרך לשלוח את המילה לבדה.
- claude.ai: ck_read_mode ב-PostHog נגזר מהארגומנטים כמו שהגיעו לשרת.
  כיול על Claude Code: {"query": null} תויג full, ומחרוזת תויגה query.
  שתי הקריאות של claude.ai ל-query="null" תויגו full.

השורות על "null" שהוסרו ב-#3485 מ-mcp-file-sections ומטבלת "פתרון
תקלות" חוזרות, עם הסיבה הנכונה ועם העקיפה: כותרת ששמה null נקראת ב-lines
לפי ה-line_range מהמפה, וקובץ ששמו null לפי file_id — שתיהן נבדקו מול
השרת. ורשומה ב-whats-new.


Claude-Session: https://claude.ai/code/session_01MEsSHNcaSFuF5dKwQkQcLC

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants