Skip to content

Conversation

@dsarno
Copy link
Owner

@dsarno dsarno commented Sep 7, 2025

Summary

  • add prune_tool_results.py to condense tool_result JSON outputs into one-line summaries
  • trim default Unity MCP tool payloads: find_in_file returns first match positions only, validate_script & get_sha provide condensed counts and hashes, read_console trims entries, and read_resource returns only hash and byte length unless text is requested
  • document lean tool responses and add tests for trimmed outputs
  • split NL/T GitHub workflow into separate NL and T passes to keep conversations lean
  • expose Unity bridge port to the MCP client by sharing the status directory and wiring the port into the workflow
  • guard Unity bridge wait loop against missing status file to prevent premature failures

Testing

  • pytest

https://chatgpt.com/codex/tasks/task_e_68bcbbf232cc832791102f8596bd5683

@coderabbitai
Copy link

coderabbitai bot commented Sep 7, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-tool_result-json-pruner-xnfcl8

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 and usage tips.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR implements a comprehensive optimization strategy for the Unity MCP (Model Context Protocol) system focused on reducing conversation size and improving workflow efficiency. The changes introduce a tool result pruning system that condenses verbose JSON outputs into concise summaries, making AI conversations more manageable and cost-effective.

The core addition is prune_tool_results.py, a utility that processes MCP conversation JSON to transform detailed tool outputs into one-line summaries. For example, SHA256 hashes are truncated to 8 characters with ellipsis, script validation diagnostics become simple warning/error counts, and file search results show only position coordinates rather than full text excerpts.

Complementing this utility, the PR modifies five Unity MCP tools to provide "lean responses" by default:

  • find_in_file now returns only the first match with position coordinates (startLine/Col, endLine/Col) instead of text excerpts
  • validate_script returns diagnostic counts ({warnings: 1, errors: 2}) instead of full diagnostic objects
  • get_sha returns only essential fields (sha256, lengthBytes) without metadata like timestamps or paths
  • read_console defaults to error-only entries with just level and message fields, stripping timestamps
  • read_resource returns only hash and byte length unless text content is explicitly requested via include_text=True

The GitHub CI workflow is restructured into a two-pass approach: an NL (Natural Language) pass using Claude Sonnet for read-only analysis, followed by a T (Tool) pass using Claude Haiku for editing operations. This separation keeps individual AI sessions focused and manageable. The workflow improvements also include better Unity bridge connectivity through shared status directories and more robust port detection using jq for JSON parsing.

Eight new test files validate the trimmed behavior across all modified tools, ensuring the optimization doesn't break functionality while confirming the expected minimal response formats. The changes are designed to be backward-compatible, maintaining the same API contracts while returning condensed data structures.

Changed Files
Filename Score Overview
README-DEV.md 5/5 Documents new pruning utility and lean tool responses feature
prune_tool_results.py 4/5 New utility script that condenses MCP tool results into one-line summaries
tests/test_get_sha.py 5/5 Adds test for trimmed get_sha output validation
UnityMcpBridge/UnityMcpServer~/src/tools/resource_tools.py 4/5 Implements lean responses for read_resource and find_in_file tools
.github/workflows/claude-nl-suite.yml 4/5 Splits workflow into NL and T passes with improved Unity bridge connectivity
UnityMcpBridge/UnityMcpServer~/src/tools/read_console.py 4/5 Trims console output to essential fields and defaults to errors only
tests/test_read_resource_minimal.py 4/5 New test validating minimal read_resource behavior
tests/test_validate_script_summary.py 4/5 New test for condensed script validation diagnostic counts
tests/test_find_in_file_minimal.py 4/5 New test ensuring find_in_file returns position data only
tests/test_read_console_trimmed.py 4/5 New test validating trimmed console log output
UnityMcpBridge/UnityMcpServer~/src/tools/manage_script.py 4/5 Implements condensed responses for validate_script and get_sha tools

Confidence score: 4/5

  • This PR implements thoughtful optimizations that should reduce conversation overhead without breaking functionality
  • Score reflects well-structured changes with comprehensive test coverage, though the complexity of modifications across multiple tool implementations introduces some risk
  • Pay close attention to the workflow changes in .github/workflows/claude-nl-suite.yml and ensure the resource_tools.py modifications don't break existing integrations

Sequence Diagram

sequenceDiagram
    participant User as User/CI Trigger
    participant GitHub as GitHub Actions
    participant Docker as Unity Container
    participant MCP as MCP Server
    participant Unity as Unity Editor
    participant Tools as Unity Bridge Tools
    
    User->>GitHub: "Trigger workflow dispatch"
    GitHub->>GitHub: "Setup Python environment with uv"
    GitHub->>GitHub: "Install MCP server dependencies"
    GitHub->>GitHub: "Configure Unity licensing (ULF/EBL)"
    GitHub->>Docker: "Start Unity container with MCP bridge"
    Docker->>Unity: "Launch Unity Editor in batchmode"
    Unity->>Tools: "Execute MCPForUnityBridge.StartAutoConnect"
    Tools->>Tools: "Start TCP bridge on random port"
    Tools->>GitHub: "Write status JSON with unity_port"
    GitHub->>GitHub: "Wait for Unity bridge readiness"
    GitHub->>GitHub: "Write MCP config (.claude/mcp.json)"
    GitHub->>GitHub: "Create report skeletons and directories"
    
    Note over GitHub,MCP: NL Pass (Natural Language)
    GitHub->>MCP: "Start Claude NL pass with allowed tools"
    MCP->>Unity: "mcp__unity__list_resources"
    Unity->>MCP: "Return minimal CS file URIs"
    MCP->>Unity: "mcp__unity__read_resource (metadata only)"
    Unity->>MCP: "Return SHA256 + lengthBytes only"
    MCP->>Unity: "mcp__unity__find_in_file (first match)"
    Unity->>MCP: "Return startLine/Col, endLine/Col only"
    MCP->>Unity: "mcp__unity__validate_script"
    Unity->>MCP: "Return warnings/errors counts only"
    MCP->>Unity: "mcp__unity__read_console (trimmed)"
    Unity->>MCP: "Return level/message pairs only"
    MCP->>GitHub: "Write NL test results to reports/*_results.xml"
    
    Note over GitHub,MCP: T Pass (Transformational)
    GitHub->>MCP: "Start Claude T pass with editing tools"
    MCP->>Unity: "mcp__unity__apply_text_edits with ranges"
    Unity->>MCP: "Apply atomic text edits"
    MCP->>Unity: "mcp__unity__script_apply_edits with ops"
    Unity->>MCP: "Apply structured method operations"
    MCP->>Unity: "mcp__unity__get_sha for preconditions"
    Unity->>MCP: "Return SHA256 + lengthBytes only"
    MCP->>GitHub: "Write T test results to reports/*_results.xml"
    
    GitHub->>GitHub: "Canonicalize testcase names (NL/T prefixes)"
    GitHub->>GitHub: "Backfill missing test placeholders"
    GitHub->>GitHub: "Merge fragments into single JUnit XML"
    GitHub->>GitHub: "Build markdown summary from JUnit"
    GitHub->>GitHub: "Collect execution transcript"
    GitHub->>GitHub: "Apply prune_tool_results.py to transcript"
    GitHub->>GitHub: "Publish JUnit report and upload artifacts"
    GitHub->>Docker: "Stop Unity container"
    GitHub->>User: "Return Pro license (if used)"
Loading

11 files reviewed, 3 comments

Edit Code Review Bot Settings | Greptile

lines = data["lines"] or []
lvls = {"info":0,"warning":0,"error":0}
for L in lines:
lvls[L.get("level","" ).lower()] = lvls.get(L.get("level","" ).lower(),0)+1
Copy link

Choose a reason for hiding this comment

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

logic: Potential KeyError if level has unexpected value. Consider using lvls.get(L.get('level', '').lower(), 0) consistently.

Suggested change
lvls[L.get("level","" ).lower()] = lvls.get(L.get("level","" ).lower(),0)+1
level_key = L.get("level", "").lower()
lvls[level_key] = lvls.get(level_key, 0) + 1

data = obj.get("data", {}) or {}
msg = obj.get("message") or obj.get("status") or ""
# Common tool shapes
if "sha256" in str(data):
Copy link

Choose a reason for hiding this comment

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

logic: Using str(data) for SHA256 detection is fragile - could match unrelated strings containing 'sha256'. Consider checking data.get('sha256') directly.

Suggested change
if "sha256" in str(data):
if data.get("sha256"):

Comment on lines +57 to +63
loop = asyncio.new_event_loop()
try:
resp = loop.run_until_complete(
read_resource(uri="unity://path/Assets/A.txt", ctx=None, project_root=str(proj))
)
finally:
loop.close()
Copy link

Choose a reason for hiding this comment

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

style: Consider using asyncio.run() instead of manually creating and closing event loop for cleaner async test execution

Suggested change
loop = asyncio.new_event_loop()
try:
resp = loop.run_until_complete(
read_resource(uri="unity://path/Assets/A.txt", ctx=None, project_root=str(proj))
)
finally:
loop.close()
resp = asyncio.run(
read_resource(uri="unity://path/Assets/A.txt", ctx=None, project_root=str(proj))
)

@dsarno dsarno closed this Sep 7, 2025
@dsarno dsarno deleted the codex/add-tool_result-json-pruner-xnfcl8 branch September 7, 2025 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants