Skip to content

feat(ui): optimize MCP App widgets to reduce chat UI overhead#93

Open
jhuang-tw wants to merge 1 commit into
Waishnav:mainfrom
jhuang-tw:feature/ui-opt-in-default-off
Open

feat(ui): optimize MCP App widgets to reduce chat UI overhead#93
jhuang-tw wants to merge 1 commit into
Waishnav:mainfrom
jhuang-tw:feature/ui-opt-in-default-off

Conversation

@jhuang-tw

@jhuang-tw jhuang-tw commented Jul 21, 2026

Copy link
Copy Markdown

Optimize MCP App widget behavior because tool-result cards can keep accumulating in long conversations. This can make the chat page increasingly slow, crowd the conversation with repeated UI surfaces, and make the information the user actually needs harder to find.

Behavior:

  • default MCP App widgets to off
  • add a persisted widgets setting with off, changes, and full
  • add devspace config set widgets <off|changes|full>
  • keep DEVSPACE_WIDGETS as the highest-priority temporary override
  • report the active mode during init, serve, and doctor commands
  • in off, register native MCP tools without MCP App metadata and do not register the App resource
  • in changes and full, preserve the existing MCP App registration and presentation behavior

Rationale:

  • prevent embedded tool cards from continuously piling up in chat
  • reduce rendering and interaction overhead in long conversations
  • keep tool results readable without hiding important conversation content behind repeated UI containers
  • allow Owners to explicitly enable partial or full UI when needed

Compatibility and security:

  • Owner-password OAuth is unchanged
  • the /mcp endpoint and tool names are unchanged
  • existing DEVSPACE_WIDGETS deployments remain supported
  • persisted configuration is overridden by the environment variable
  • no generated UI assets, helper scripts, workflows, or documentation files are included in the final change

Validation:

  • npm run typecheck
  • npm test
  • npm run build

Scope:

  • src/user-config.ts
  • src/config.ts
  • src/config.test.ts
  • src/cli.ts
  • src/server.ts

Summary by CodeRabbit

  • New Features

    • Added configurable UI widget modes: off, changes, or full.
    • Added devspace config set widgets ... support with validation.
    • Displayed widget status during setup, startup, and diagnostics.
    • Added help documentation for the new configuration command.
    • Widget-enabled UI resources are now available only when configured.
  • Bug Fixes

    • Configuration now correctly persists and loads the selected widget mode.
    • The default widget mode is now off.

Optimize MCP App widget behavior because tool-result cards can keep
accumulating in long conversations. This can make the chat page
increasingly slow, crowd the conversation with repeated UI surfaces,
and make the information the user actually needs harder to find.

Behavior:
- default MCP App widgets to `off`
- add a persisted `widgets` setting with `off`, `changes`, and `full`
- add `devspace config set widgets <off|changes|full>`
- keep `DEVSPACE_WIDGETS` as the highest-priority temporary override
- report the active mode during init, serve, and doctor commands
- in `off`, register native MCP tools without MCP App metadata and do
  not register the App resource
- in `changes` and `full`, preserve the existing MCP App registration
  and presentation behavior

Rationale:
- prevent embedded tool cards from continuously piling up in chat
- reduce rendering and interaction overhead in long conversations
- keep tool results readable without hiding important conversation
  content behind repeated UI containers
- allow Owners to explicitly enable partial or full UI when needed

Compatibility and security:
- Owner-password OAuth is unchanged
- the `/mcp` endpoint and tool names are unchanged
- existing `DEVSPACE_WIDGETS` deployments remain supported
- persisted configuration is overridden by the environment variable
- no generated UI assets, helper scripts, workflows, or documentation
  files are included in the final change

Validation:
- npm run typecheck
- npm test
- npm run build

Scope:
- src/user-config.ts
- src/config.ts
- src/config.test.ts
- src/cli.ts
- src/server.ts
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Widgets configuration and server behavior

Layer / File(s) Summary
Widget configuration contract and loading
src/user-config.ts, src/config.ts, src/config.test.ts
Adds the optional widget mode type, defaults unset values to off, supports config-file values, and verifies environment overrides.
CLI configuration and status reporting
src/cli.ts
Persists widget settings during initialization, adds config set widgets, documents the command, and reports the mode in CLI output.
Widget-aware MCP registration
src/server.ts
Selects UI or native tool registration by widget mode, removes UI metadata when disabled, and conditionally registers the Diff Card resource.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConfigLoader
  participant createMcpServer
  participant registerAppTool
  participant MCPHost
  ConfigLoader->>createMcpServer: config.widgets
  createMcpServer->>registerAppTool: register tool
  registerAppTool->>MCPHost: UI-backed tool or native tool
  createMcpServer->>MCPHost: Diff Card resource when widgets are enabled
Loading

Possibly related PRs

Suggested reviewers: waishnav

Poem

A rabbit tuned the widgets bright,
Then tucked “off” away at night.
Cards may bloom or tools stay plain,
Config remembers every change.
Hop, hop—Diff Cards know the way!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: optimizing MCP App widgets to reduce chat UI overhead.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

🧹 Nitpick comments (1)
src/server.ts (1)

160-164: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Safeguard against accidental array conversion.

While the definition and handler results are always plain objects in this context, using object rest spread on an array would inadvertently convert it into an object with numeric keys (e.g., { 0: item, 1: item }).

As a defensive measure for a generic <T> function, consider explicitly excluding arrays from being destructured.

♻️ Proposed refactor
 function stripAppMeta<T>(value: T): T {
-  if (!value || typeof value !== "object") return value;
+  if (!value || typeof value !== "object" || Array.isArray(value)) return value;
   const { _meta: _discardedMeta, ...nativeValue } = value as Record<string, unknown>;
   return nativeValue as T;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server.ts` around lines 160 - 164, Update stripAppMeta so arrays bypass
the _meta removal and are returned unchanged, preventing object rest spread from
converting them into numeric-keyed objects. Keep the existing primitive/null
handling and plain-object metadata stripping behavior intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/server.ts`:
- Around line 160-164: Update stripAppMeta so arrays bypass the _meta removal
and are returned unchanged, preventing object rest spread from converting them
into numeric-keyed objects. Keep the existing primitive/null handling and
plain-object metadata stripping behavior intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c2f29ab8-0f59-43b3-9fd7-70de576f0d04

📥 Commits

Reviewing files that changed from the base of the PR and between 80423b5 and 82ffd0b.

📒 Files selected for processing (5)
  • src/cli.ts
  • src/config.test.ts
  • src/config.ts
  • src/server.ts
  • src/user-config.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant