Skip to content

fix(site): fix MCP page interactions and links#7756

Merged
AmanVarshney01 merged 5 commits intomainfrom
fix-mcp-page
Apr 2, 2026
Merged

fix(site): fix MCP page interactions and links#7756
AmanVarshney01 merged 5 commits intomainfrom
fix-mcp-page

Conversation

@AmanVarshney01
Copy link
Copy Markdown
Member

@AmanVarshney01 AmanVarshney01 commented Apr 2, 2026

Summary

  • Agent cards: Added Radix tooltips on hover, click-to-copy for Cursor, VS Code, Warp, Claude Code, and Gemini cards. ChatGPT and Windsurf open external links in new tab.
  • Prompt bubbles: Made copyable with tooltip feedback ("Copy prompt" / "Copied!"), fixed text left-alignment
  • CTA section: "Add MCP Server" and "Read Docs" now link to different pages (https://www.prisma.io/docs/postgres/integrations/mcp-server and https://www.prisma.io/docs/ai)
  • "Want to see your tool listed?": Opens a Tally form modal (matching live site behavior)
  • All cross-app links use absolute URLs since this is a monorepo

Summary by CodeRabbit

Release Notes

  • New Features

    • Added copy-to-clipboard functionality to agent cards and prompts with visual confirmation feedback
    • Added form dialog for documentation reference
    • Integrated platform-specific setup instructions for multiple IDEs and tools
  • UI/UX Improvements

    • Added "Read Docs" navigation button
    • Enhanced interactive feedback with tooltips

- Agent cards: add tooltips, copy-to-clipboard, correct deep links for Cursor/VS Code, and proper external links
- Prompt bubbles: make copyable with tooltip feedback
- CTA section: differentiate "Add MCP Server" and "Read Docs" hrefs
- "Want to see your tool listed?": open Tally form modal instead of broken link
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Apr 2, 2026 3:39pm
docs Ready Ready Preview, Comment Apr 2, 2026 3:39pm
eclipse Ready Ready Preview, Comment Apr 2, 2026 3:39pm
site Ready Ready Preview, Comment Apr 2, 2026 3:39pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ddcfce43-d894-4934-82cd-3711fd727832

📥 Commits

Reviewing files that changed from the base of the PR and between 34824d2 and 3090799.

📒 Files selected for processing (1)
  • apps/site/src/app/mcp/page.tsx

Walkthrough

Converted several MCP UI components to client components, added copy-to-clipboard and tooltip behavior, introduced a Tally feedback dialog, updated types to allow optional href and added copyText, and adjusted page data and CTA props to use the new fields.

Changes

Cohort / File(s) Summary
Agent card & prompt UI
apps/site/src/app/mcp/_components/agent-card.tsx, apps/site/src/app/mcp/_components/mcp-bubble.tsx
Made components client-side ("use client"), added useState for transient copied state, implemented click-to-copy logic (clipboard API) with tooltip text switching, and conditional rendering for copy-button vs anchor in AgentCard.
Agents section & dialog
apps/site/src/app/mcp/_components/mcp-agents-section.tsx
Converted to client component, added TooltipProvider, replaced docs link with a Dialog trigger embedding a Tally form via <iframe> and next/script, and changed McpAgent typing to accept optional href and new copyText.
CTA and page integration
apps/site/src/app/mcp/_components/mcp-cta-section.tsx, apps/site/src/app/mcp/page.tsx
Added readDocsHref prop to CTA component; updated page.tsx agents list to use copyText for several agents (deep links/commands/JSON) and pass readDocsHref to McpCtaSection; imports condensed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: fixing MCP page interactions (tooltips, copy behavior, modals) and correcting links across multiple components.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@argos-ci
Copy link
Copy Markdown

argos-ci bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Apr 2, 2026, 3:47 PM

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (4)
apps/site/src/app/mcp/_components/mcp-bubble.tsx (1)

104-112: Same clipboard and timeout concerns apply here.

This follows the same pattern as agent-card.tsx. For consistency, consider applying the same improvements: handle the clipboard Promise rejection and clean up the timeout on unmount.

♻️ Proposed fix mirroring agent-card.tsx
-import { useId, useState, type ReactNode } from "react";
+import { useEffect, useId, useRef, useState, type ReactNode } from "react";

// Inside McpPromptBubble:
+  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
+
+  useEffect(() => {
+    return () => {
+      if (timeoutRef.current) clearTimeout(timeoutRef.current);
+    };
+  }, []);

   const handleCopy = () => {
     if (typeof children === "string") {
-      navigator.clipboard.writeText(children);
-      setCopied(true);
-      setTimeout(() => setCopied(false), 1500);
+      navigator.clipboard.writeText(children).then(() => {
+        setCopied(true);
+        timeoutRef.current = setTimeout(() => setCopied(false), 1500);
+      }).catch((err) => {
+        console.error("Failed to copy:", err);
+      });
     }
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/mcp/_components/mcp-bubble.tsx` around lines 104 - 112, The
handleCopy logic in mcp-bubble.tsx should mirror agent-card.tsx: make
navigator.clipboard.writeText(children) asynchronous and handle Promise
rejection (catch and log/handle error) instead of assuming success, store the
timeout ID returned by setTimeout in a ref (or variable) so you can clearTimeout
on unmount, and add a useEffect cleanup that clears the timeout to avoid state
updates after unmount; update the copied state only on successful write and
ensure handleCopy early-returns if children is not a string as currently
checked.
apps/site/src/app/mcp/_components/mcp-agents-section.tsx (2)

59-65: Consider adding a loading state for the iframe.

The Tally iframe may take a moment to load, especially on slower connections. Users might see a blank area inside the dialog initially. A loading skeleton or spinner could improve the perceived experience.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/mcp/_components/mcp-agents-section.tsx` around lines 59 -
65, The iframe in the MCP Agents Section should show a loading state: add a
local loading boolean (e.g., useState(true)) in the MCPAgentsSection component,
render a spinner/skeleton overlay while loading, attach an onLoad handler to the
iframe element to set loading to false, and ensure the iframe has
aria-busy/aria-label updates for accessibility; reference the existing iframe
JSX (data-tally-src="https://tally.so/r/wA1R1N", title="Tool listing request")
to add the onLoad and conditional rendering so users see the spinner until the
iframe finishes loading.

40-42: Consider using a dedicated identifier or index as the React key instead of agent.alt.

While all current alt values are unique, alt is semantically for accessibility text, not identification. For a static list like this, using the index is acceptable; for dynamic lists, add an id field to each agent object. This ensures keys reflect the component's identity rather than relying on human-readable labels that could change without breaking React's reconciliation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/mcp/_components/mcp-agents-section.tsx` around lines 40 -
42, The list currently uses agent.alt as the React key which is meant for
accessibility, not stable identification; update the map to use a stable
identifier (preferably an id field) or the index for this static list: modify
the agents data to include an id for each agent and use key={agent.id} in the
AgentCard render (or if truly static use key={index} temporarily), ensuring the
change is applied where agents.map and <AgentCard ... /> are used so keys
reflect component identity rather than the alt text.
apps/site/src/app/mcp/_components/agent-card.tsx (1)

26-32: Consider handling clipboard API failures and cleaning up the timeout.

Two potential issues here:

  1. navigator.clipboard.writeText() returns a Promise and can fail (e.g., permission denied, insecure context). Silently ignoring this could leave users confused when copy doesn't work.

  2. The setTimeout isn't cleaned up on unmount. If the component unmounts before 1500ms elapse, React will warn about setting state on an unmounted component.

♻️ Proposed fix with error handling and cleanup
+import { useEffect, useRef, useState } from "react";
-import { useState } from "react";

// Inside the component:
+  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
+
+  useEffect(() => {
+    return () => {
+      if (timeoutRef.current) clearTimeout(timeoutRef.current);
+    };
+  }, []);

   const handleClick = (e: React.MouseEvent) => {
     if (!isCopyAction) return;
     e.preventDefault();
-    navigator.clipboard.writeText(copyText);
-    setCopied(true);
-    setTimeout(() => setCopied(false), 1500);
+    navigator.clipboard.writeText(copyText).then(() => {
+      setCopied(true);
+      timeoutRef.current = setTimeout(() => setCopied(false), 1500);
+    }).catch((err) => {
+      console.error("Failed to copy:", err);
+    });
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/site/src/app/mcp/_components/agent-card.tsx` around lines 26 - 32,
handleClick currently calls navigator.clipboard.writeText without handling
failures and starts a timeout that isn't cleared on unmount; update handleClick
to await or handle the Promise returned by navigator.clipboard.writeText (wrap
in try/catch or use .then/.catch) and only call setCopied(true) on success (log
or surface an error on failure), store the timeout id in a ref (e.g.,
timeoutRef) instead of a plain setTimeout call, and add a useEffect cleanup that
clears the timeout (clearTimeout(timeoutRef.current)) to avoid setting state
after unmount; reference the handleClick function,
navigator.clipboard.writeText, setCopied, and the new timeoutRef/useEffect
cleanup when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/site/src/app/mcp/_components/mcp-agents-section.tsx`:
- Line 24: The McpAgentsSection component's props type includes an unused
docsHref string; remove docsHref from the props signature of McpAgentsSection
(change from { docsHref: string; agents: readonly McpAgent[] } to only the
agents prop) and update any call sites that pass docsHref (e.g., the page.tsx
invocation around where McpAgentsSection is used) to stop supplying that
argument or to pass only agents; ensure the exported function signature and its
usages (McpAgentsSection) are consistent so TypeScript errors are resolved.

---

Nitpick comments:
In `@apps/site/src/app/mcp/_components/agent-card.tsx`:
- Around line 26-32: handleClick currently calls navigator.clipboard.writeText
without handling failures and starts a timeout that isn't cleared on unmount;
update handleClick to await or handle the Promise returned by
navigator.clipboard.writeText (wrap in try/catch or use .then/.catch) and only
call setCopied(true) on success (log or surface an error on failure), store the
timeout id in a ref (e.g., timeoutRef) instead of a plain setTimeout call, and
add a useEffect cleanup that clears the timeout
(clearTimeout(timeoutRef.current)) to avoid setting state after unmount;
reference the handleClick function, navigator.clipboard.writeText, setCopied,
and the new timeoutRef/useEffect cleanup when making the change.

In `@apps/site/src/app/mcp/_components/mcp-agents-section.tsx`:
- Around line 59-65: The iframe in the MCP Agents Section should show a loading
state: add a local loading boolean (e.g., useState(true)) in the
MCPAgentsSection component, render a spinner/skeleton overlay while loading,
attach an onLoad handler to the iframe element to set loading to false, and
ensure the iframe has aria-busy/aria-label updates for accessibility; reference
the existing iframe JSX (data-tally-src="https://tally.so/r/wA1R1N", title="Tool
listing request") to add the onLoad and conditional rendering so users see the
spinner until the iframe finishes loading.
- Around line 40-42: The list currently uses agent.alt as the React key which is
meant for accessibility, not stable identification; update the map to use a
stable identifier (preferably an id field) or the index for this static list:
modify the agents data to include an id for each agent and use key={agent.id} in
the AgentCard render (or if truly static use key={index} temporarily), ensuring
the change is applied where agents.map and <AgentCard ... /> are used so keys
reflect component identity rather than the alt text.

In `@apps/site/src/app/mcp/_components/mcp-bubble.tsx`:
- Around line 104-112: The handleCopy logic in mcp-bubble.tsx should mirror
agent-card.tsx: make navigator.clipboard.writeText(children) asynchronous and
handle Promise rejection (catch and log/handle error) instead of assuming
success, store the timeout ID returned by setTimeout in a ref (or variable) so
you can clearTimeout on unmount, and add a useEffect cleanup that clears the
timeout to avoid state updates after unmount; update the copied state only on
successful write and ensure handleCopy early-returns if children is not a string
as currently checked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3bb9dfdf-60c7-4e2b-9cc5-747015f776a2

📥 Commits

Reviewing files that changed from the base of the PR and between b919d81 and 34824d2.

📒 Files selected for processing (5)
  • apps/site/src/app/mcp/_components/agent-card.tsx
  • apps/site/src/app/mcp/_components/mcp-agents-section.tsx
  • apps/site/src/app/mcp/_components/mcp-bubble.tsx
  • apps/site/src/app/mcp/_components/mcp-cta-section.tsx
  • apps/site/src/app/mcp/page.tsx

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

Converted several MCP UI components to client components, added copy-to-clipboard and tooltip behavior, introduced a Tally feedback dialog, updated types to allow optional href and added copyText, and adjusted page data and CTA props to use the new fields.

Changes

Cohort / File(s) Summary
Agent card & prompt UI
apps/site/src/app/mcp/_components/agent-card.tsx, apps/site/src/app/mcp/_components/mcp-bubble.tsx
Made components client-side ("use client"), added useState for transient copied state, implemented click-to-copy logic (clipboard API) with tooltip text switching, and conditional rendering for copy-button vs anchor in AgentCard.
Agents section & dialog
apps/site/src/app/mcp/_components/mcp-agents-section.tsx
Converted to client component, added TooltipProvider, replaced docs link with a Dialog trigger embedding a Tally form via <iframe> and next/script, and changed McpAgent typing to accept optional href and new copyText.
CTA and page integration
apps/site/src/app/mcp/_components/mcp-cta-section.tsx, apps/site/src/app/mcp/page.tsx
Added readDocsHref prop to CTA component; updated page.tsx agents list to use copyText for several agents (deep links/commands/JSON) and pass readDocsHref to McpCtaSection; imports condensed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: fixing MCP page interactions (tooltips, copy behavior, modals) and correcting links across multiple components.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

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.

2 participants