Skip to content

feat: collapse large MCP servers' tool rows into an expandable summary - #293

Merged
cbeaulieu-gt merged 3 commits into
mainfrom
issue-283-group-server-tools
Aug 30, 2026
Merged

feat: collapse large MCP servers' tool rows into an expandable summary#293
cbeaulieu-gt merged 3 commits into
mainfrom
issue-283-group-server-tools

Conversation

@cbeaulieu-gt

@cbeaulieu-gt cbeaulieu-gt commented Aug 30, 2026

Copy link
Copy Markdown
Member

Summary

Servers like GitHub expose 20+ individual mcp__github__* tools, each rendered as its own row in the MCP Tool Usage dashboard view, dominating the card and making cross-server comparison hard.

  • New TOOL_COLLAPSE_THRESHOLD = 8 (named constant). Once a server's by_method entry count exceeds it, the existing per-method breakdown (renderMethodRows, unchanged) is wrapped in a native <details><summary>N tools, TOTAL calls</summary>...</details> disclosure instead of rendering every row directly.
  • TOTAL calls is Object.values(by_method).reduce(...), which is always equal to the server card's existing "Total calls" stat by construction (verified against aggregator.py's single-loop accumulation of server_calls/server_methods), so the summary can never diverge from the stat above it.
  • Native <details>/<summary> — no JS event wiring, no custom disclosure styling (kept the browser's default marker as the only "this is clickable" affordance, per simplicity-first).
  • Servers at or under the threshold are rendered exactly as before — no behavior change for the common case.
  • The <details> wrapper sits outside .methods, so .methods' shared 3-column CSS grid contract (issue Usage count / est. tokens columns misaligned in dashboard cells #284) is unchanged in both collapsed and expanded states.

Built test-first: tests/test_mcp_usage_view_tool_grouping.py was written and confirmed red before any implementation, then the implementation went green against it without editing the frozen tests.

Closes #283

Test plan

  • pytest tests/test_mcp_usage_view_tool_grouping.py tests/test_mcp_usage_view_column_alignment.py tests/test_mcp_usage_view.py tests/test_mcp_usage_view_guid_filter.py tests/test_mcp_usage_view_zero_call_filter.py tests/test_mcp_usage_view_cost_proxy.py -v — 49 passed, no regressions (especially the Usage count / est. tokens columns misaligned in dashboard cells #284 3-column grid contract)
  • pytest tests/ (full suite) — 920 passed, 1 failed (pre-existing, unrelated date-boundary flake: test_tool_usage.py::TestWindowBoundsToAnchor::test_days_only_default_path_is_unaffected), 2 skipped
  • ruff check . — clean
  • ruff format --check . — clean

🤖 Generated by Claude Code on behalf of @cbeaulieu-gt

Summary by CodeRabbit

  • New Features

    • Added collapsible method breakdowns for servers with more than eight MCP tools.
    • Collapsed summaries display aggregate and tool call counts, with the option to expand for full details.
    • Smaller breakdowns retain their existing layout.
  • Style

    • Added styling for the expandable disclosure and its open state.
  • Tests

    • Added coverage for thresholds, aggregate summaries, expand controls, and full breakdown visibility.

Servers like GitHub expose 20+ individual mcp__github__* tools, each
rendered as its own row in the MCP Tool Usage dashboard, dominating the
card. Once a server exceeds TOOL_COLLAPSE_THRESHOLD (8) distinct
methods, wrap the existing renderMethodRows breakdown in a native
<details>/<summary> disclosure showing "N tools, TOTAL calls" instead
-- no JS event wiring needed, and the native marker/triangle is the
expand affordance. Servers at or under the threshold are unaffected.

The <details> wrapper sits outside .methods (not inside it), so
.methods' shared 3-column grid contract (#284) is unchanged in both
the collapsed and expanded states.

Closes #283

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNU12ST32LtQf2GPDPrZB5
@cbeaulieu-gt cbeaulieu-gt added this to the v0.13.0 milestone Aug 30, 2026
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9255ef3b-128e-4d6a-8986-563c8b0ce0a2

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The MCP usage view now collapses per-server method lists with more than eight tools. The collapsed summary shows tool and aggregate call counts. Users can expand the summary to view detailed method rows. Source-containment tests verify the implementation.

Changes

MCP tool grouping

Layer / File(s) Summary
Conditional methods rendering
src/claude_prospector/static/views/mcp-usage.js
Adds styling and an eight-tool threshold. Large method lists render in a collapsed <details> element with aggregate counts. Smaller lists retain the existing expanded layout.
Server card integration and validation
src/claude_prospector/static/views/mcp-usage.js, tests/test_mcp_usage_view_tool_grouping.py
renderServerCard uses renderMethodsBlock. Source checks verify threshold logic, aggregate rendering, an expansion affordance, and continued use of renderMethodRows.

Sequence Diagram(s)

sequenceDiagram
  participant renderServerCard
  participant renderMethodsBlock
  participant renderMethodRows
  participant detailsElement
  renderServerCard->>renderMethodsBlock: pass server method data
  alt fewer than or equal to eight tools
    renderMethodsBlock->>renderMethodRows: render expanded method rows
  else more than eight tools
    renderMethodsBlock->>detailsElement: render collapsed aggregate summary
    detailsElement->>renderMethodRows: reveal detailed method rows
  end
Loading

Merge Risk: ⚪ Minimal · up to 7c91a

The change only collapses large server tool lists behind a native disclosure while preserving existing rendering for smaller lists. Merge readiness risk is minimal, but the new regression test should verify that the threshold constant actually controls the collapsed-versus-direct rendering decision.

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements grouped MCP tool rows, an expandable per-tool breakdown, an eight-tool threshold, and aggregate call counts for issue #283. The provided summaries do not show aggregation or display … Add and verify aggregate token calculation and display in the collapsed server summary, or provide evidence that the existing implementation already includes it.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: large MCP server tool rows become grouped and expandable.
Out of Scope Changes check ✅ Passed The implementation and source-containment tests directly support the MCP tool grouping objective. The CSS changes and preservation of the existing method-row layout are in scope.
Full details: Linked Issues check

Explanation

The PR implements grouped MCP tool rows, an expandable per-tool breakdown, an eight-tool threshold, and aggregate call counts for issue #283. The provided summaries do not show aggregation or display of aggregate tokens, which issue #283 also requires.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch issue-283-group-server-tools

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

@cbeaulieu-gt

Copy link
Copy Markdown
Member Author

Reopening to trigger CodeRabbit review with needs-review already applied.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fdb13c1a-6d14-4e06-a1d2-8b94d93ece48

📥 Commits

Reviewing files that changed from the base of the PR and between cfd1f49 and 7c91ace.

📒 Files selected for processing (2)
  • src/claude_prospector/static/views/mcp-usage.js
  • tests/test_mcp_usage_view_tool_grouping.py

Included review availability: 6 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

Comment on lines +129 to +132
named_constant_pattern = re.compile(
r"const\s+\w*(?:THRESHOLD|COLLAPSE|MAX)\w*\s*=\s*\d+",
re.IGNORECASE,
)

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Require the threshold constant to control a render branch.

Lines 129-132 accept an unused threshold constant. The test can pass when no method-count condition selects between direct and collapsed rendering. Assert that the declared threshold is used in a .length comparison and that the under-threshold branch returns the direct method markup.

Proposed test direction
-        named_constant_pattern = re.compile(
-            r"const\s+\w*(?:THRESHOLD|COLLAPSE|MAX)\w*\s*=\s*\d+",
-            re.IGNORECASE,
-        )
+        threshold_match = re.search(
+            r"const\s+(?P<name>\w*(?:THRESHOLD|COLLAPSE|MAX)\w*)\s*=\s*\d+",
+            content,
+            re.IGNORECASE,
+        )
+        assert threshold_match
+        threshold_name = re.escape(threshold_match.group("name"))
+        assert re.search(
+            rf"\b\w+\.length\s*(?:>=|>|<=|<)\s*{threshold_name}\b",
+            content,
+        )

CodeRabbit flagged that the collapsed <details> summary row only
aggregated call counts ("N tools, TOTAL calls"), not tokens, even
though issue #283 asks to aggregate "calls/tokens" and
info.by_method_tokens was already available. renderMethodsBlock now
also reduces by_method_tokens (guarded for its absence when
--track-mcp-call-sizes was off) and appends a "~N tokens" clause to
the summary text when present.

Includes the accompanying frozen test additions to
tests/test_mcp_usage_view_tool_grouping.py
(TestCollapsedSummaryAggregatesTokensAlongsideCalls).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MNU12ST32LtQf2GPDPrZB5
@cbeaulieu-gt

Copy link
Copy Markdown
Member Author

Addressed both items from CodeRabbit's review in 1710216:

  1. Test loophole (inline comment on test_mcp_usage_view_tool_grouping.py): tightened test_a_method_or_tool_count_is_compared_against_a_threshold so a declared-but-unused threshold constant no longer satisfies it — it must now be referenced in an actual .length comparison. Confirmed the current implementation (TOOL_COLLAPSE_THRESHOLD used in entries.length <= TOOL_COLLAPSE_THRESHOLD) already passes the tightened check.
  2. Linked Issues check (aggregate tokens missing): issue Collapse/group per-server MCP tools (e.g. GitHub's 20+ tools) into one row #283's request explicitly asks for "aggregate calls/tokens" — the collapsed summary now also computes and displays an aggregate token total from by_method_tokens when that data is present (guarded — omitted entirely when --track-mcp-call-sizes was off, matching this file's existing guard convention).

All 5 CI gates re-verified green after the fix (CodeRabbit shows "incremental reviews are disabled" on the follow-up push per this repo's config, so no new automated pass — verification was done manually, see commit message for full gate output).


🤖 Generated by Claude Code on behalf of @cbeaulieu-gt

…r-tools

# Conflicts:
#	src/claude_prospector/static/views/mcp-usage.js
@cbeaulieu-gt
cbeaulieu-gt merged commit 487406b into main Aug 30, 2026
6 checks passed
@cbeaulieu-gt
cbeaulieu-gt deleted the issue-283-group-server-tools branch August 30, 2026 02:16
@cbeaulieu-gt cbeaulieu-gt mentioned this pull request Aug 30, 2026
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collapse/group per-server MCP tools (e.g. GitHub's 20+ tools) into one row

1 participant