Skip to content

Conversation

@Agastya18
Copy link
Contributor

Added keyboard shortcut support to execute tools, read resources, and get prompts by pressing Enter, improving workflow efficiency and enabling keyboard-first navigation.

Fix: #885

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. enhancement New feature or request labels Nov 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

Keyboard handling enhancements were implemented across multiple tab components in the application. Enter key listeners were added to PromptsTab, ResourcesTab, and ToolsTab to trigger their respective actions—fetching prompts, reading resources, and executing tools—when Enter is pressed. The ParametersPanel component received similar Enter key handling on form inputs and select elements. All handlers exclude input, textarea, and contenteditable elements from global key event processing, and respect loading states to prevent unintended triggers.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
client/src/components/ResourcesTab.tsx (1)

118-138: Well-implemented Enter key handler with proper safeguards.

The implementation correctly follows accessibility guidelines and prevents unintended triggers with comprehensive exclusions. The cleanup function prevents memory leaks as recommended.

Optional refinement for dependency completeness:

The effect calls readResource, which accesses serverName from the outer scope. While the current implementation works due to component lifecycle patterns (server changes reset selectedResource), wrapping readResource in useCallback would make dependencies explicit and prevent potential stale closures.

Example refactor with useCallback
+ const readResource = useCallback(async (uri: string) => {
+   if (!serverName) return;
    setLoading(true);
    setError("");
    // ... rest of function
- };
+ }, [serverName]);

  // Handle Enter key to read resource globally
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Enter" && !e.shiftKey && selectedResource && !loading) {
        // ... exclusion checks
        e.preventDefault();
        readResource(selectedResource);
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
- }, [selectedResource, loading]);
+ }, [selectedResource, loading, readResource]);
client/src/components/ToolsTab.tsx (1)

332-353: Consistent Enter key implementation with proper accessibility considerations.

The handler correctly excludes editable elements and respects loading state. Cleanup function ensures proper resource management. Based on learnings.

Consider extracting the duplicated global handler pattern:

This implementation is nearly identical to the handlers in ResourcesTab.tsx (lines 118-138) and PromptsTab.tsx (lines 187-206). Extracting into a custom hook would improve maintainability.

Example custom hook
function useEnterKeyAction(
  callback: () => void,
  enabled: boolean,
  loading: boolean
) {
  useEffect(() => {
    if (!enabled) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Enter" && !e.shiftKey && !loading) {
        const target = e.target as HTMLElement;
        const tagName = target.tagName;
        const isEditable = target.isContentEditable;

        if (tagName === "INPUT" || tagName === "TEXTAREA" || isEditable) {
          return;
        }

        e.preventDefault();
        callback();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [callback, enabled, loading]);
}

// Usage in ToolsTab:
useEnterKeyAction(executeTool, !!selectedTool, loading);
client/src/components/PromptsTab.tsx (1)

187-206: Global handler implementation aligns with established pattern.

The implementation matches the handlers in ResourcesTab.tsx and ToolsTab.tsx with correct safeguards. The local handler at line 179 takes precedence for input fields, while this global handler covers interactions elsewhere.

Same refactoring opportunities apply:

The dependency array consideration and custom hook extraction suggestion from ToolsTab.tsx (lines 332-353) apply equally here, consolidating the three identical global handler patterns across PromptsTab, ResourcesTab, and ToolsTab.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70ac6f9 and a648b14.

📒 Files selected for processing (4)
  • client/src/components/PromptsTab.tsx (2 hunks)
  • client/src/components/ResourcesTab.tsx (1 hunks)
  • client/src/components/ToolsTab.tsx (1 hunks)
  • client/src/components/tools/ParametersPanel.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
client/src/components/PromptsTab.tsx (1)
client/src/lib/mcp-prompts-api.ts (1)
  • getPrompt (32-54)
client/src/components/ToolsTab.tsx (1)
sdk/src/mcp-client-manager/index.ts (1)
  • executeTool (504-531)
🔍 Remote MCP

Summary of Key Findings for PR Review

I've gathered additional context on best practices for keyboard event handling in React and accessibility standards. Here are the key findings relevant to this PR:

React Keyboard Event Handling Best Practices

Use onKeyDown or onKeyUp instead of the deprecated onKeyPress for more consistent and inclusive user experience. The PR implementation using onKeyDown aligns with this recommendation.

Use event.key as it's meant to be a cross-platform compatible abstraction of keyboard keys, which appears to be properly used in the implementations.

Critical Event Listener Cleanup Requirement

The cleanup function prevents memory leaks by removing the event listener when the component unmounts or before the effect re-runs. This is important to verify — the PR's global Enter-key listeners in useEffect should include proper cleanup functions that call removeEventListener to avoid memory leaks.

Keeping event listeners around is expensive, taking up memory and processing power from the browser and host computer.

Accessibility Considerations (WCAG 2.1.4)

If a keyboard shortcut uses letter, punctuation, number, or symbol characters, at least one of the following must be true: the shortcut can be turned off, it can be remapped to involve one or more non-printable keyboard characters (like Ctrl or Alt), or it's only active when the component has focus.

The PR uses bare Enter key (a non-printable character exception), which does not affect components like listboxes and drop-down menus where the shortcuts are only active when the components have focus.

If keyboard shortcuts use more than one key (using "alt" or "ctrl" + another key), then no change is needed, though an explanation of each shortcut should be available to users. Since this PR uses only the Enter key in limited contexts, ensure it only activates on the intended components (not in text inputs where user typing shouldn't trigger actions).

Key Review Checkpoints

  1. Verify cleanup functions — All useEffect handlers must return cleanup functions removing the event listeners
  2. Verify input/textarea exclusion — The PR mentions excluding inputs and textareas, confirming focus-only behavior per accessibility guidelines
  3. Dependency array correctness — Ensure dependencies like selectedResource, selectedTool, and loading are properly specified to avoid stale closures
  4. Event prevention — Confirm preventDefault() is called to avoid double-execution with form submissions
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: prettier-and-build
🔇 Additional comments (2)
client/src/components/tools/ParametersPanel.tsx (1)

34-49: Clean implementation of per-field Enter key handling.

Both handlers appropriately prevent default form submission and respect the loading state. The pattern ensures pressing Enter in form controls triggers execution, complementing the global handler in the parent ToolsTab component.

client/src/components/PromptsTab.tsx (1)

178-184: Appropriate local handler for input fields.

The handler provides immediate Enter key response for parameter inputs, preventing default form behavior and triggering prompt retrieval when not loading.

Copy link
Collaborator

@matteo8p matteo8p left a comment

Choose a reason for hiding this comment

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

Ship!

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Nov 19, 2025
@matteo8p matteo8p merged commit 3b26961 into MCPJam:main Nov 19, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Execute tool call upon hitting enter

2 participants