Skip to content

Performance: Reduce round-trips for common agent workflows #35

@Joxx0r

Description

@Joxx0r

Summary

After an exhaustive stress test of all unreal-index MCP tools (find_type, find_children, find_member, find_file, grep, browse_module, list_modules, find_asset), the query performance is excellent — all queries return sub-second. However, the main bottleneck for Claude Code agent speed is the number of sequential MCP round-trips needed for common workflows.

A typical "understand this class" workflow requires 3-5 sequential tool calls:

find_type("ADiscoveryGameMode")          → get path + line
Read(path, line)                          → see the actual code
find_children("ADiscoveryGameMode")       → understand hierarchy
find_member("BeginPlay", containingType=...) → find the method
Read(path2, line2)                        → read the method body

Each round-trip adds latency. The suggestions below aim to reduce the number of calls needed for common patterns.


Suggestion 1: contextLines / includeSource on find_type and find_member (Highest Impact)

Problem: find_type and find_member return file paths and line numbers, but the agent almost always needs to follow up with a Read call to see the actual code. This is the single most common source of extra round-trips (~40% of follow-up Read calls).

Suggestion: Add an optional contextLines: N parameter (like grep already has) to find_type and find_member. When provided, include N lines of source code around the definition in the response.

Example — current behavior (2 calls):

find_type("ADiscoveryGameMode") → { path: "...", line: 92 }
Read("...", offset: 92, limit: 30) → actual code

Example — proposed (1 call):

find_type("ADiscoveryGameMode", contextLines: 15)
→ { path: "...", line: 92, source: "class ADiscoveryGameMode : AEmbarkGameModeRoot\n{\n  default bUseSeamlessTravel = true;\n  ..." }

This is consistent with how grep already supports contextLines and would feel natural.


Suggestion 2: Full function signatures in find_member results (High Impact)

Problem: find_member returns the member name, line number, and specifiers, but not the actual function signature (parameters, return type). The agent almost always needs to Read the file to see the full signature before it can use or call the function.

Current response:

{
  "name": "TakeDamage",
  "member_kind": "function",
  "line": 3412,
  "specifiers": "virtual",
  "type_name": "AActor"
}

Proposed enhancement — add signature and/or returnType/params:

{
  "name": "TakeDamage",
  "member_kind": "function",
  "line": 3412,
  "specifiers": "virtual",
  "type_name": "AActor",
  "signature": "float TakeDamage(float DamageAmount, FDamageEvent& DamageEvent, AController* EventInstigator, AActor* DamageCauser)",
  "returnType": "float"
}

This would eliminate the most common "look up a method → immediately read the file to see its parameters" pattern.


Suggestion 3: Compound "explain type" query (High Impact)

Problem: The most common agent workflow is "tell me about this type" which requires 3-4 separate calls: find_type + find_member (for key members) + find_children + Read.

Suggestion: A single compound tool like unreal_explain_type that returns in one call:

  • Type definition (file, line, parent class, kind)
  • Key members (properties + functions, first N — configurable via maxMembers)
  • Direct children (first N — configurable via maxChildren)
  • Source snippet around the definition (first N lines)

Example:

unreal_explain_type(name: "ADiscoveryGameMode", maxMembers: 20, maxChildren: 10, contextLines: 20)

Returns everything the agent needs to understand the type in a single round-trip. This would collapse the most common 3-4 call workflow into 1.


Suggestion 4: Eager tool loading instead of deferred

Problem: Every Claude Code conversation starts with a ToolSearch("+unreal-index") call to load the 9 index tools. This is guaranteed overhead on every session — one extra round-trip before any actual work can begin.

Suggestion: Register the unreal-index tools as eagerly loaded rather than deferred. Since these are the primary search tools for the codebase (per project CLAUDE.md instructions), they're used in virtually every conversation. The startup cost of loading them eagerly would be negligible compared to the per-conversation ToolSearch overhead.


Suggestion 5: Grep "enclosing scope" mode

Problem: When grepping for a pattern and finding matches, the agent frequently needs to understand the surrounding context (which class/function contains the match). The contextLines parameter helps but is line-count-based — it may cut off mid-function or include irrelevant code from adjacent functions.

Suggestion: An optional contextMode: "enclosing_function" or contextMode: "enclosing_class" parameter that returns the enclosing scope around each match rather than a fixed number of context lines. This would give the agent semantically meaningful context in one call.

Example:

grep(pattern: "GameModeTagExclusionFilter", contextMode: "enclosing_function")

Returns each match with its full enclosing function body, rather than N arbitrary lines.


Suggestion 6: Batch/compound query endpoint

Problem: Agents often need to look up 3-5 related things simultaneously. While Claude Code can call multiple MCP tools in parallel, each still incurs separate MCP protocol overhead (connection, serialization, etc.).

Suggestion: A batch endpoint that accepts multiple queries in a single MCP call:

{
  "tool": "unreal_batch",
  "queries": [
    { "tool": "find_type", "name": "ADiscoveryGameMode" },
    { "tool": "find_type", "name": "AEmbarkGameModeRoot" },
    { "tool": "find_children", "parentClass": "ADiscoveryGameMode" }
  ]
}

Returns all results in a single response. This reduces MCP protocol overhead for parallel lookups and is especially valuable when the agent needs to build a picture of a subsystem (multiple related types, their members, their children).


Priority Ranking

Based on how frequently each pattern occurs in real agent workflows:

Priority Suggestion Estimated Round-Trip Reduction
P0 #1 — contextLines on find_type/find_member ~30-40% of follow-up Reads eliminated
P0 #2 — Full signatures in find_member ~20% of follow-up Reads eliminated
P1 #3 — Compound explain_type query Collapses 3-4 calls → 1 for the most common workflow
P1 #4 — Eager tool loading Saves 1 round-trip per conversation (guaranteed)
P2 #5 — Enclosing scope context mode Reduces grep → read follow-ups
P2 #6 — Batch query endpoint Reduces protocol overhead for parallel lookups

Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions