Skip to content

Conversation

HarshMN2345
Copy link
Member

@HarshMN2345 HarshMN2345 commented Sep 8, 2025

What does this PR do?

  • Onboarding overview adds Auth preview visuals, a new MCP server card with one-click install, docs link, and external tool buttons (Cursor, Claude Desktop, VS Code, Windsurf).
    • New theme-aware 16×16 icon components for tool buttons; installation settings use updated action buttons and render tools dynamically.

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)

Related PRs and Issues

(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)

Have you read the Contributing Guidelines on issues?

yes

Summary by CodeRabbit

  • New Features

    • Onboarding overview shows Auth preview visuals, a new MCP server card with one-click install, docs link, and external tool buttons (Cursor, Claude Desktop, VS Code, Windsurf).
    • New theme-aware 16×16 icon components for those tool buttons; installation settings render tools dynamically and use updated action buttons.
  • Style / Layout

    • Redesigned Discord header with right-aligned arrow; tightened two-column layouts, responsive card heights, and auth image background-position and alignment tweaks.

Copy link

appwrite bot commented Sep 8, 2025

Console

Project ID: 688b7bf400350cbd60e9

Sites (2)
Site Status Logs Preview QR
 console-qa
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code
 console-cloud
688b7c18002b9b871a8f
Ready Ready View Logs Preview URL QR Code

Note

Appwrite has a Discord community with over 16 000 members.

Copy link
Contributor

coderabbitai bot commented Sep 8, 2025

Walkthrough

Replaced previous user imagery with AuthPreview/AuthPreviewDark and updated auth-image background positioning and responsive heights. Converted the auth block to a fixed horizontal row on large viewports with a ~30/70 split. Added an MCP server card that renders tools from a new exported mcpTools array and introduced four theme-aware icon components: CursorIcon, ClaudeIcon, VSCodeIcon, WindsurfIcon. Redesigned the Discord tile to a horizontal header with a right-aligned arrow and added breakpoint-specific height rules and other flex/layout alignment tweaks.

Pre-merge checks and finishing touches

✅ 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 "feat: add Appwrite MCP install cards to onboarding and project settings" succinctly and accurately summarizes the primary change in this PR — adding MCP install cards to both the onboarding overview and project settings — and matches the raw_summary and pr_objectives. It is concise, uses a conventional-commit prefix, and clearly communicates the intent to teammates scanning history. The title is specific and not vague or misleading.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-SER-288-Increase-MCP-visibility

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c414cb0 and b14d831.

📒 Files selected for processing (1)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte
⏰ 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). (2)
  • GitHub Check: e2e
  • GitHub Check: build

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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: 2

🧹 Nitpick comments (5)
src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (5)

482-487: Inline layout styles: consider moving to a CSS class.

Functionally fine; moving the flex/min-width logic into a named class improves readability and keeps markup cleaner.


551-553: Add analytics + rel to docs link.

Track the MCP docs click and add rel for security on the external target.

Apply this diff:

-                                                    <Typography.Text
+                                                    <Typography.Text
                                                         color="--fgcolor-neutral-secondary">
-                                                        Deploy the Appwrite MCP server with a single
-                                                        click, or view the <Link.Anchor
-                                                            href="https://appwrite.io/docs"
-                                                            target="_blank">docs</Link.Anchor> for instructions.
+                                                        Deploy the Appwrite MCP server with a single
+                                                        click, or view the <Link.Anchor
+                                                            href="https://appwrite.io/docs"
+                                                            target="_blank"
+                                                            rel="noopener noreferrer"
+                                                            on:click={() => trackEvent(Click.OnboardingMcpDocsClick)}
+                                                        >docs</Link.Anchor> for instructions.
                                                     </Typography.Text>

586-587: Open Discord in a new tab and add rel.

Keep users in Console and follow external-link best practices.

Apply this diff:

-                                    <Card.Link
-                                        href="https://appwrite.io/discord"
+                                    <Card.Link
+                                        href="https://appwrite.io/discord"
+                                        target="_blank"
+                                        rel="noopener noreferrer"

704-707: Avoid fixed heights to prevent content clipping; prefer min-height/clamp.

Fixed heights risk overflow with larger fonts/translations. Use min-height and scale down at breakpoints.

Apply this diff:

-        .double-width-card .full-height-card {
-            height: 240px;
-            width: 100%;
-        }
+        .double-width-card .full-height-card {
+            min-height: 240px;
+            width: 100%;
+        }
@@
-            .double-width-card .full-height-card {
-                height: 220px;
-            }
+            .double-width-card .full-height-card {
+                min-height: 220px;
+            }
@@
-            .double-width-card .full-height-card {
-                height: auto;
-            }
+            .double-width-card .full-height-card {
+                min-height: unset;
+            }

Also applies to: 710-717, 720-727


539-547: Copy: consider clarifying value prop.

“MCP server” might be unfamiliar. A short “Connect your IDE to Appwrite via MCP” subheading can improve comprehension.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8eeae54 and 36159cc.

⛔ Files ignored due to path filters (2)
  • src/routes/(console)/project-[region]-[project]/overview/assets/auth-preview-dark.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/auth-preview.svg is excluded by !**/*.svg
📒 Files selected for processing (1)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (5 hunks)
⏰ 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). (2)
  • GitHub Check: e2e
  • GitHub Check: build
🔇 Additional comments (4)
src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (4)

15-16: AuthPreview asset swap looks good.

Imports align with usage below and correctly support theme variants.


524-529: Auth image: theme-aware background is correct.

The flex grow and background-image swap per theme are sound.


591-595: Discord header layout looks good.

The horizontal header with icon/title improves scanability.


692-692: Auth image positioning change is appropriate.

Right-bottom works better with the new asset.

Comment on lines +551 to +553
href="https://appwrite.io/docs"
target="_blank">docs</Link.Anchor> for instructions.
</Typography.Text>
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify analytics enums and deep links exist.

Ensure Click.OnboardingMcpDocsClick and Click.OnboardingMcpInstallClick (or equivalents) are defined and captured; confirm deep-link destinations before merge.

Run:

Also applies to: 563-575


🏁 Script executed:

#!/bin/bash
# Verify analytics event enums and any MCP deep-link utilities
rg -nP 'OnboardingMcp(Docs|Install)Click|McpInstall|MCP_INSTALLS|deep.?link' -C2

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Locate analytics definitions and deep-link utilities

echo "=== Files and paths containing 'analytics' ==="
fd -t f analytics || echo "(no analytics-named files found)"

echo

echo "=== Searching for OnboardingMcp event enums ==="
rg -nP 'OnboardingMcp(Docs|Install)Click' -C2 || echo "(no matches)"

echo

echo "=== Searching for deep link utilities (deepLink, deep-link) ==="
rg -nP 'deepLink|deep-?link' -C2 || echo "(no matches)"

Length of output: 215


Define missing analytics events and deep-link utilities

  • Add Click.OnboardingMcpDocsClick and Click.OnboardingMcpInstallClick to the analytics enum in src/lib/actions/analytics.ts
  • Implement or import the deep-link helpers for the MCP docs and install pages referenced in this component

Comment on lines 556 to 575
<Typography.Text
color="--fgcolor-neutral-tertiary"
size="s">One-click install</Typography.Text>
<Layout.Stack
direction="row"
gap="s"
wrap="wrap">
<Button.Button size="s" variant="secondary">
Cursor
</Button.Button>
<Button.Button size="s" variant="secondary">
Claude Desktop
</Button.Button>
<Button.Button size="s" variant="secondary">
VS code
</Button.Button>
<Button.Button size="s" variant="secondary">
Windsurf editor
</Button.Button>
</Layout.Stack>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

MCP “One‑click install” buttons are inert; wire them up + fix casing.

Currently these buttons have no href/on:click, so they don’t perform installs and provide no telemetry. Also, “VS code” and “Windsurf editor” casing is off.

Apply this diff to render actionable links with tracking and corrected labels:

-                                                    <Layout.Stack
-                                                        direction="row"
-                                                        gap="s"
-                                                        wrap="wrap">
-                                                        <Button.Button size="s" variant="secondary">
-                                                            Cursor
-                                                        </Button.Button>
-                                                        <Button.Button size="s" variant="secondary">
-                                                            Claude Desktop
-                                                        </Button.Button>
-                                                        <Button.Button size="s" variant="secondary">
-                                                            VS code
-                                                        </Button.Button>
-                                                        <Button.Button size="s" variant="secondary">
-                                                            Windsurf editor
-                                                        </Button.Button>
-                                                    </Layout.Stack>
+                                                    <Layout.Stack direction="row" gap="s" wrap="wrap">
+                                                        {#each MCP_INSTALLS as item}
+                                                            <Link.Button
+                                                                size="s"
+                                                                variant="secondary"
+                                                                href={item.href}
+                                                                target="_blank"
+                                                                rel="noopener noreferrer"
+                                                                title={`Install for ${item.label}`}
+                                                                on:click={() => trackEvent(Click.OnboardingMcpInstallClick, { client: item.id })}
+                                                            >
+                                                                {item.label}
+                                                            </Link.Button>
+                                                        {/each}
+                                                    </Layout.Stack>

Add this helper in the <script> block (near other constants):

const MCP_INSTALLS = [
  // TODO: replace hrefs with real deep links before merge
  { id: 'cursor',          label: 'Cursor',          href: 'https://appwrite.io/mcp/install/cursor' },
  { id: 'claude-desktop',  label: 'Claude Desktop',  href: 'https://appwrite.io/mcp/install/claude-desktop' },
  { id: 'vscode',          label: 'VS Code',         href: 'https://appwrite.io/mcp/install/vscode' },
  { id: 'windsurf',        label: 'Windsurf Editor', href: 'https://appwrite.io/mcp/install/windsurf' }
];

If deep links differ per environment/region, derive href at runtime from config and include region/project params.

I can wire this to actual deep links once you share the target URIs.

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 (10)
src/routes/(console)/project-[region]-[project]/overview/components/WindsurfIcon.svelte (2)

7-7: Make size and a11y configurable (alt/aria), add non-blocking decode

Expose props for size and accessibility; keep default decorative behavior. Also add decoding="async" and draggable="false".

 <script lang="ts">
     import { app } from '$lib/stores/app';
     import Light from '../assets/windsurf.svg';
     import Dark from '../assets/dark/windsurf.svg';
+    export let size: number = 16;
+    export let altText: string = 'Windsurf';
+    export let decorative: boolean = true;
 </script>

-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="16" height="16" alt="" />
+<img
+    src={$app.themeInUse === 'dark' ? Dark : Light}
+    width={size}
+    height={size}
+    alt={decorative ? '' : altText}
+    aria-hidden={decorative ? 'true' : 'false'}
+    decoding="async"
+    draggable="false"
+/>

1-7: Avoid duplication across icon components

If Cursor/Claude/VSCode icons follow the same pattern, consider a tiny generic ThemedIcon component to reduce repetition.

Example (new file ThemedIcon.svelte):

<script lang="ts">
  import { app } from '$lib/stores/app';
  export let light: string;
  export let dark: string;
  export let size: number = 16;
  export let altText: string = '';
  export let decorative: boolean = true;
</script>

<img
  src={$app.themeInUse === 'dark' ? dark : light}
  width={size}
  height={size}
  alt={decorative ? '' : altText}
  aria-hidden={decorative ? 'true' : 'false'}
  decoding="async"
  draggable="false"
/>

Then each icon becomes a 3–5 line wrapper passing assets/alt.

src/routes/(console)/project-[region]-[project]/overview/components/CursorIcon.svelte (2)

7-7: Expose size and alt props for reuse.
Keeps default 16px while allowing overrides and better a11y.

 <script lang="ts">
     import { app } from '$lib/stores/app';
     import Light from '../assets/cursor-ai.svg';
     import Dark from '../assets/dark/cursor-ai.svg';
+    export let size: number = 16;
+    export let alt = '';
 </script>
 
-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="16" height="16" alt="" />
+<img
+  src={$app.themeInUse === 'dark' ? Dark : Light}
+  width={size}
+  height={size}
+  alt={alt}
+  decoding="async"
+/>

7-7: Optional: avoid SSR theme flicker without store.
If you support “system”/SSR, consider prefers-color-scheme via .

-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="16" height="16" alt="" />
+<picture>
+  <source srcset={Dark} media="(prefers-color-scheme: dark)" />
+  <img src={Light} width={16} height={16} alt="" decoding="async" />
+</picture>
src/routes/(console)/project-[region]-[project]/overview/components/VSCodeIcon.svelte (3)

7-7: Make the icon accessible and customizable (alt/size + rest props).

If this icon is the only content inside a link/button, alt="" will make it invisible to screen readers. Expose alt (default empty for decorative use), size, and forward $$restProps so callers can set aria-label, class, etc.

 <script lang="ts">
     import { app } from '$lib/stores/app';
     import Light from '../assets/vscode.svg';
     import Dark from '../assets/dark/vscode.svg';
+    export let alt: string = '';
+    export let size: number | string = 16;
 </script>
 
-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="16" height="16" alt="" />
+<img
+    {...$$restProps}
+    src={$app.themeInUse === 'dark' ? Dark : Light}
+    width={size}
+    height={size}
+    alt={alt}
+    aria-hidden={alt === ''}
+    decoding="async"
+/>

Action: If this icon appears inside an anchor without visible text, ensure the anchor has an accessible name (e.g., aria-label="Open in VS Code"), or pass a non-empty alt. Please confirm.


1-5: Verify SSR/hydration behavior for theme-based asset swap.

Using $app.themeInUse at render-time can cause a server–client mismatch if the initial theme differs between SSR and the browser. If you’ve seen hydration warnings or a brief light/dark swap, consider one of:

  • Client-only switch (render light by default; update src in onMount).
  • OS-driven <picture> fallback (avoids store coupling but won’t track in-app toggles).

Alternative (OS-driven) for reference:

<picture>
  <source srcset={Dark} media="(prefers-color-scheme: dark)" />
  <img {...$$restProps} src={Light} width={size} height={size} alt={alt} aria-hidden={alt === ''} />
</picture>

1-7: Deduplicate: extract a reusable ThemedIcon base.

You’ve added four similar icon components. A single ThemedIcon that accepts light, dark, alt, and size would reduce duplication and ensure consistent a11y and SSR handling across all icons.

Happy to sketch ThemedIcon.svelte and update the four call sites—want me to do that?

src/routes/(console)/project-[region]-[project]/overview/components/ClaudeIcon.svelte (3)

7-7: Expose alt/size props and mark decorative usage for a11y.

Empty alt makes this decorative; offer props so callers can provide accessible text when the icon stands alone.

 <script lang="ts">
   import { app } from '$lib/stores/app';
   import Light from '../assets/claude.svg';
   import Dark from '../assets/dark/claude.svg';
+  export let alt: string = '';
+  export let size: number = 16;
 </script>

-<img src={$app.themeInUse === 'dark' ? Dark : Light} width="16" height="16" alt="" />
+<img
+  src={$app.themeInUse === 'dark' ? Dark : Light}
+  width={size}
+  height={size}
+  alt={alt}
+  aria-hidden={!alt}
+  decoding="async"
+/>

1-7: Consider a tiny shared ThemeIcon to de-duplicate Cursor/Claude/VSCode/Windsurf.

All four components share the same logic. A single base Icon reduces churn and ensures consistent a11y.

Example base:

<!-- ThemeIcon.svelte -->
<script lang="ts">
  import { app } from '$lib/stores/app';
  export let light: string;
  export let dark: string;
  export let alt: string = '';
  export let size: number = 16;
</script>

<img src={$app.themeInUse === 'dark' ? dark : light}
     width={size} height={size} alt={alt} aria-hidden={!alt} decoding="async" />

Usage in ClaudeIcon:

<script lang="ts">
  import ThemeIcon from './ThemeIcon.svelte';
  import Light from '../assets/claude.svg';
  import Dark from '../assets/dark/claude.svg';
  export let alt = '';
  export let size = 16;
</script>

<ThemeIcon light={Light} dark={Dark} {alt} {size} />

2-5: Optional: avoid store dependency if OS theme is sufficient.

If syncing to OS theme is acceptable for these tiny assets, removes the store subscription and avoids potential SSR/hydration flips.

<picture>
  <source srcset={Dark} media="(prefers-color-scheme: dark)" />
  <img src={Light} width={16} height={16} alt="" aria-hidden="true" decoding="async" />
</picture>

Also applies to: 7-7

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36159cc and d56c17b.

⛔ Files ignored due to path filters (8)
  • src/routes/(console)/project-[region]-[project]/overview/assets/claude.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/cursor-ai.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/dark/claude.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/dark/cursor-ai.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/dark/vscode.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/dark/windsurf.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/vscode.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/assets/windsurf.svg is excluded by !**/*.svg
📒 Files selected for processing (5)
  • src/routes/(console)/project-[region]-[project]/overview/components/ClaudeIcon.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/components/CursorIcon.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/components/VSCodeIcon.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/components/WindsurfIcon.svelte (1 hunks)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte
⏰ 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). (2)
  • GitHub Check: e2e
  • GitHub Check: build
🔇 Additional comments (6)
src/routes/(console)/project-[region]-[project]/overview/components/WindsurfIcon.svelte (2)

1-5: LGTM: theme-aware asset switch is correct

Using the store to flip Light/Dark assets is consistent and straightforward.


7-7: No usages of WindsurfIcon found in any .svelte files—no risk of unlabeled links.

src/routes/(console)/project-[region]-[project]/overview/components/CursorIcon.svelte (2)

1-5: LGTM: simple theme-based icon.
Pattern matches other icons; safe import usage.


2-4: Assets and theme contract verified. Both SVGs are present under src/routes/.../overview/assets, and themeInUse only ever yields 'light' or 'dark' (no 'system'/'auto'), so no changes needed.

src/routes/(console)/project-[region]-[project]/overview/components/ClaudeIcon.svelte (2)

2-5: LGTM on theme-aware asset import.

Imports and store usage look fine and consistent with other components.


3-4: Assets verified: both SVGs present and non-empty
Both src/routes/(console)/project-[region]-[project]/overview/assets/claude.svg and its dark variant in …/assets/dark/claude.svg exist and are non-zero byte files.

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: 6

🧹 Nitpick comments (4)
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte (4)

33-36: Avoid cross-route coupling for icons

These icons live under overview/components; consider moving to a shared location (e.g., $lib/icons) to prevent route-to-route imports and ease reuse.


190-194: Inconsistent OAuth link behavior

“Connect to GitHub” uses external (new tab) while “Add installation” does not. Pick one approach for the OAuth flow to reduce confusion and potential popup blockers.


219-256: DRY up the four action anchors

Consider a data-driven loop to cut duplication and keep labels/links/icons consistent.

-                    <Layout.Stack direction="row" gap="s" wrap="wrap" justifyContent="center">
-                        <Button.Anchor ...
-                        </Button.Anchor>
-                        <Button.Anchor ...
-                        </Button.Anchor>
-                        <Button.Anchor ...
-                        </Button.Anchor>
-                        <Button.Anchor ...
-                        </Button.Anchor>
-                    </Layout.Stack>
+                    <Layout.Stack direction="row" gap="s" wrap="wrap" justifyContent="center">
+                        {#each [
+                            { label: 'Cursor', href: 'https://apwr.dev/docs-mcp-cursor?ref=docs', icon: CursorIcon, key: 'cursor' },
+                            { label: 'Claude Desktop', href: 'https://appwrite.io/docs/tooling/mcp/claude', icon: ClaudeIcon, key: 'claude' },
+                            { label: 'VS Code', href: 'https://apwr.dev/docs-mcp-vscode?ref=docs', icon: VSCodeIcon, key: 'vscode' },
+                            { label: 'Windsurf Editor', href: 'https://appwrite.io/docs/tooling/mcp/windsurf', icon: WindsurfIcon, key: 'windsurf' }
+                        ] as a}
+                            <Button.Anchor
+                                href={a.href}
+                                target="_blank"
+                                rel="noopener noreferrer"
+                                size="s"
+                                variant="secondary"
+                                on:click={() => trackEvent(Click.SettingsMcpActionClick, { target: a.key })}>
+                                <Icon slot="start" icon={a.icon} size="xs" />
+                                {a.label}
+                            </Button.Anchor>
+                        {/each}
+                    </Layout.Stack>

219-256: Standardize domains/UTM across MCP links (optional)

Links mix appwrite.io and apwr.dev and inconsistent ref params. Standardize domains and tracking parameters for reliable analytics and SEO.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d56c17b and 65f046e.

📒 Files selected for processing (1)
  • src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte (7 hunks)
⏰ 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). (2)
  • GitHub Check: e2e
  • GitHub Check: build
🔇 Additional comments (4)
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte (4)

18-21: Imports look good

Importing Table and Button (for Button.Anchor) and aliasing Link as PinkLink is consistent with usage below.


92-101: LGTM: swapped to FormButton for “Add installation”

Matches page styling and keeps analytics hook. No issues spotted.


205-209: MCP block copy is clear

Nice, concise value prop. No change requested.


5-5: Ensure FormButton forwards target/rel for anchor links
FormButton exports href/external but doesn’t expose target or rel; verify it applies correct link attributes (e.g. _blank/noopener noreferrer) to avoid a11y regressions, or use Button.Anchor for all anchors.

Comment on lines +213 to +217
Deploy the Appwrite MCP server with a single click, or view the <PinkLink.Anchor
href="https://appwrite.io/docs"
target="_blank"
rel="noreferrer">docs</PinkLink.Anchor> for instructions.
</svelte:fragment>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add noopener to external docs link

Prevent tabnabbing; align with best practices.

-                    Deploy the Appwrite MCP server with a single click, or view the <PinkLink.Anchor
-                        href="https://appwrite.io/docs"
-                        target="_blank"
-                        rel="noreferrer">docs</PinkLink.Anchor> for instructions.
+                    Deploy the Appwrite MCP server with a single click, or view the <PinkLink.Anchor
+                        href="https://appwrite.io/docs"
+                        target="_blank"
+                        rel="noopener noreferrer">docs</PinkLink.Anchor> for instructions.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Deploy the Appwrite MCP server with a single click, or view the <PinkLink.Anchor
href="https://appwrite.io/docs"
target="_blank"
rel="noreferrer">docs</PinkLink.Anchor> for instructions.
</svelte:fragment>
Deploy the Appwrite MCP server with a single click, or view the <PinkLink.Anchor
href="https://appwrite.io/docs"
target="_blank"
rel="noopener noreferrer">docs</PinkLink.Anchor> for instructions.
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte
around lines 213 to 217, the external docs link uses target="_blank" with
rel="noreferrer" only; add noopener to the rel attribute to prevent tabnabbing
by changing rel to "noreferrer noopener" (or "noopener noreferrer") while
keeping the existing target and other attributes intact.

Comment on lines 219 to 229
<Layout.Stack direction="row" gap="s" wrap="wrap" justifyContent="center">
<Button.Anchor
href="https://apwr.dev/docs-mcp-cursor?ref=docs"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={CursorIcon} size="xs" />
Cursor
</Button.Anchor>
<Button.Anchor
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Harden external link (Cursor) and add analytics (optional)

Add noopener; consider tracking clicks for adoption metrics.

-                        <Button.Anchor
+                        <Button.Anchor
                             href="https://apwr.dev/docs-mcp-cursor?ref=docs"
                             target="_blank"
-                            rel="noreferrer"
+                            rel="noopener noreferrer"
                             size="s"
                             variant="secondary">
                             <Icon slot="start" icon={CursorIcon} size="xs" />
                             Cursor
                         </Button.Anchor>

Optionally:

<Button.Anchor ... on:click={() => trackEvent(Click.SettingsMcpActionClick, { target: 'cursor' })}>

Comment on lines 230 to 237
href="https://appwrite.io/docs/tooling/mcp/claude"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={ClaudeIcon} size="xs" />
Claude Desktop
</Button.Anchor>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Harden external link (Claude) and consider tracking

-                        <Button.Anchor
+                        <Button.Anchor
                             href="https://appwrite.io/docs/tooling/mcp/claude"
                             target="_blank"
-                            rel="noreferrer"
+                            rel="noopener noreferrer"
                             size="s"
                             variant="secondary">
                             <Icon slot="start" icon={ClaudeIcon} size="xs" />
                             Claude Desktop
                         </Button.Anchor>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
href="https://appwrite.io/docs/tooling/mcp/claude"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={ClaudeIcon} size="xs" />
Claude Desktop
</Button.Anchor>
<Button.Anchor
href="https://appwrite.io/docs/tooling/mcp/claude"
target="_blank"
rel="noopener noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={ClaudeIcon} size="xs" />
Claude Desktop
</Button.Anchor>
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte
around lines 230–237, the external Claude link should be hardened and
instrumented for tracking: add rel="noopener noreferrer" (not just noreferrer)
to prevent window.opener attacks, ensure target="_blank" remains, and either
append safe tracking query params (e.g.,
utm_source=app&utm_medium=console&utm_campaign=installations) or add an on:click
handler that calls your analytics tracker with a clear event name (e.g.,
"external_link_click" with label "claude_desktop") before navigating; ensure the
handler still opens the link in a new tab if you use programmatic navigation,
and keep accessibility attributes intact.

Comment on lines 239 to 246
href="https://apwr.dev/docs-mcp-vscode?ref=docs"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={VSCodeIcon} size="xs" />
VS code
</Button.Anchor>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix product casing and harden link (VS Code)

-                        <Button.Anchor
+                        <Button.Anchor
                             href="https://apwr.dev/docs-mcp-vscode?ref=docs"
                             target="_blank"
-                            rel="noreferrer"
+                            rel="noopener noreferrer"
                             size="s"
                             variant="secondary">
                             <Icon slot="start" icon={VSCodeIcon} size="xs" />
-                            VS code
+                            VS Code
                         </Button.Anchor>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
href="https://apwr.dev/docs-mcp-vscode?ref=docs"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={VSCodeIcon} size="xs" />
VS code
</Button.Anchor>
<Button.Anchor
href="https://apwr.dev/docs-mcp-vscode?ref=docs"
target="_blank"
rel="noopener noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={VSCodeIcon} size="xs" />
VS Code
</Button.Anchor>
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte
around lines 239 to 246, fix the product casing and harden the external link:
change the visible label from "VS code" to "VS Code" (capitalize "Code"), and
update the anchor rel attribute to include "noopener" in addition to
"noreferrer" (rel="noopener noreferrer") so the external link is hardened
against window.opener attacks while preserving existing attributes.

Comment on lines 248 to 255
href="https://appwrite.io/docs/tooling/mcp/windsurf"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={WindsurfIcon} size="xs" />
Windsurf editor
</Button.Anchor>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix product casing and harden link (Windsurf)

-                        <Button.Anchor
+                        <Button.Anchor
                             href="https://appwrite.io/docs/tooling/mcp/windsurf"
                             target="_blank"
-                            rel="noreferrer"
+                            rel="noopener noreferrer"
                             size="s"
                             variant="secondary">
                             <Icon slot="start" icon={WindsurfIcon} size="xs" />
-                            Windsurf editor
+                            Windsurf Editor
                         </Button.Anchor>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
href="https://appwrite.io/docs/tooling/mcp/windsurf"
target="_blank"
rel="noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={WindsurfIcon} size="xs" />
Windsurf editor
</Button.Anchor>
<Button.Anchor
href="https://appwrite.io/docs/tooling/mcp/windsurf"
target="_blank"
rel="noopener noreferrer"
size="s"
variant="secondary">
<Icon slot="start" icon={WindsurfIcon} size="xs" />
Windsurf Editor
</Button.Anchor>
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte
around lines 248 to 255, the button text uses incorrect product casing and the
external link rel is too weak; update the visible label to use the correct
product casing "Windsurf Editor" (capitalized) and harden the anchor by changing
rel to "noopener noreferrer" (keep target="_blank") and ensure the href is a
fully-qualified, https URL without interpolated user data; optionally add an
accessible aria-label matching the visible text.

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

♻️ Duplicate comments (2)
src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (2)

544-552: Point docs link to MCP docs, add telemetry, and harden external link.

  • Link directly to the MCP docs section.
  • Track click (e.g., Click.OnboardingMcpDocsClick).
  • Add rel="noopener noreferrer".

Apply:

-                                                        Deploy the Appwrite MCP server with a single
-                                                        click, or view the <Link.Anchor
-                                                            href="https://appwrite.io/docs"
-                                                            target="_blank">docs</Link.Anchor> for instructions.
+                                                        Deploy the Appwrite MCP server with a single
+                                                        click, or view the <Link.Anchor
+                                                            href="https://appwrite.io/docs/tooling/mcp"
+                                                            target="_blank"
+                                                            rel="noopener noreferrer"
+                                                            on:click={() => trackEvent(Click.OnboardingMcpDocsClick)}
+                                                        >docs</Link.Anchor> for instructions.

562-575: Install buttons: add analytics + noopener; use tool IDs.

  • Emit Click.OnboardingMcpInstallClick with { client: tool.id }.
  • Use rel="noopener noreferrer" for target="_blank".
  • Optionally add title for hover text.

Apply:

-                                                        {#each mcpTools as tool}
+                                                        {#each mcpTools as tool}
                                                             <Button.Anchor
                                                                 href={tool.href}
                                                                 target="_blank"
-                                                                rel="noreferrer"
+                                                                rel="noopener noreferrer"
+                                                                title={`Install ${tool.label}`}
+                                                                on:click={() =>
+                                                                    trackEvent(Click.OnboardingMcpInstallClick, {
+                                                                        client: tool.id
+                                                                    })
+                                                                }
                                                                 size="s"
                                                                 variant="secondary">

Please confirm the analytics enums exist. You can run:

#!/bin/bash
rg -nP 'OnboardingMcp(Install|Docs)Click' -C2 src || true
🧹 Nitpick comments (4)
src/routes/(console)/project-[region]-[project]/store.ts (2)

6-9: Icon imports OK; consider centralizing for maintainability.

Optional: export these from an overview/components/icons/index.ts barrel to reduce fragile relative paths across files.


81-102: MCP tools: fix casing, add stable IDs for analytics, and tighten types.

  • Labels: “VS code” → “VS Code”, “Windsurf editor” → “Windsurf Editor”.
  • Add an id per tool so UI can emit trackEvent(..., { client: tool.id }).
  • Type the array and freeze it to avoid accidental mutation.
  • Verify mixed domains (apwr.dev vs appwrite.io) are intended and allowed by policy/CSP; consider consistent UTM (e.g., utm_source=console&utm_medium=onboarding).

Apply:

 export const mcpTools = [
-    {
-        href: 'https://apwr.dev/docs-mcp-cursor?ref=docs',
-        icon: CursorIcon,
-        label: 'Cursor'
-    },
-    {
-        href: 'https://appwrite.io/docs/tooling/mcp/claude',
-        icon: ClaudeIcon,
-        label: 'Claude Desktop'
-    },
-    {
-        href: 'https://apwr.dev/docs-mcp-vscode?ref=docs',
-        icon: VSCodeIcon,
-        label: 'VS code'
-    },
-    {
-        href: 'https://appwrite.io/docs/tooling/mcp/windsurf',
-        icon: WindsurfIcon,
-        label: 'Windsurf editor'
-    }
-];
+    // Tip: keep hrefs consistent domain/UTM; confirm deep-linking behavior.
+] as const;
+
+type McpTool = {
+    id: 'cursor' | 'claude-desktop' | 'vscode' | 'windsurf';
+    href: string;
+    icon: typeof CursorIcon | typeof ClaudeIcon | typeof VSCodeIcon | typeof WindsurfIcon;
+    label: string;
+};
+
+export const mcpTools: readonly McpTool[] = [
+    { id: 'cursor',         href: 'https://apwr.dev/docs-mcp-cursor?ref=docs', icon: CursorIcon,  label: 'Cursor' },
+    { id: 'claude-desktop', href: 'https://appwrite.io/docs/tooling/mcp/claude', icon: ClaudeIcon, label: 'Claude Desktop' },
+    { id: 'vscode',         href: 'https://apwr.dev/docs-mcp-vscode?ref=docs', icon: VSCodeIcon,  label: 'VS Code' },
+    { id: 'windsurf',       href: 'https://appwrite.io/docs/tooling/mcp/windsurf', icon: WindsurfIcon, label: 'Windsurf Editor' }
+];
src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (2)

481-487: Move inline layout styles to CSS classes.

Inline style=\flex: ...`` sprinkled in JSX complicates overrides and increases style recalcs. Prefer BEM-ish classes in the SCSS block for the 30/70 split and the auth image flex.

Also applies to: 523-528


556-558: Copy check: “One‑click install” vs docs links.

If the hrefs are docs (not deep‑link installers), revise copy to “Install guides” or wire real one‑click deep links before merge.

Also applies to: 548-549

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65f046e and ffa03ac.

📒 Files selected for processing (3)
  • src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (8 hunks)
  • src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte (6 hunks)
  • src/routes/(console)/project-[region]-[project]/store.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/routes/(console)/project-[region]-[project]/settings/updateInstallations.svelte
🔇 Additional comments (2)
src/routes/(console)/project-[region]-[project]/overview/onboard.svelte (2)

15-16: Auth preview assets swap looks good.


710-733: Viewport tweaks: sanity‑check overflow and layout jumps.

With .double-width-card { width: 250% } and the new 30/70 split, verify no horizontal scroll on ≥768px and smooth height transitions at 1024px/768px.

Copy link
Member

@ItzNotABug ItzNotABug left a comment

Choose a reason for hiding this comment

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

lgtm, one quality related comment.

@Meldiron Meldiron merged commit c320871 into main Sep 17, 2025
5 checks passed
@Meldiron Meldiron deleted the feat-SER-288-Increase-MCP-visibility branch September 17, 2025 07:29
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.

3 participants