-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/claude-icon.svg b/apps/studio/public/img/mcp-clients/claude-icon.svg
deleted file mode 100644
index 7b9c0252ed7..00000000000
--- a/apps/studio/public/img/mcp-clients/claude-icon.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/apps/studio/public/img/mcp-clients/cursor-icon.svg b/apps/studio/public/img/mcp-clients/cursor-icon.svg
deleted file mode 100644
index 48f85eb4d5a..00000000000
--- a/apps/studio/public/img/mcp-clients/cursor-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/studio/public/img/mcp-clients/factory-icon-dark.svg b/apps/studio/public/img/mcp-clients/factory-icon-dark.svg
deleted file mode 100644
index 16b99b68b64..00000000000
--- a/apps/studio/public/img/mcp-clients/factory-icon-dark.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/factory-icon.svg b/apps/studio/public/img/mcp-clients/factory-icon.svg
deleted file mode 100644
index 445aa4518c9..00000000000
--- a/apps/studio/public/img/mcp-clients/factory-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/gemini-cli-icon.svg b/apps/studio/public/img/mcp-clients/gemini-cli-icon.svg
deleted file mode 100644
index 7e457a00a77..00000000000
--- a/apps/studio/public/img/mcp-clients/gemini-cli-icon.svg
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/goose-icon-dark.svg b/apps/studio/public/img/mcp-clients/goose-icon-dark.svg
deleted file mode 100644
index e37b75328ed..00000000000
--- a/apps/studio/public/img/mcp-clients/goose-icon-dark.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/goose-icon.svg b/apps/studio/public/img/mcp-clients/goose-icon.svg
deleted file mode 100644
index 1808de11575..00000000000
--- a/apps/studio/public/img/mcp-clients/goose-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/kiro-icon.svg b/apps/studio/public/img/mcp-clients/kiro-icon.svg
deleted file mode 100644
index ef4abd2d85d..00000000000
--- a/apps/studio/public/img/mcp-clients/kiro-icon.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/openai-icon-dark.svg b/apps/studio/public/img/mcp-clients/openai-icon-dark.svg
deleted file mode 100644
index 73c2f3fc76d..00000000000
--- a/apps/studio/public/img/mcp-clients/openai-icon-dark.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/openai-icon.svg b/apps/studio/public/img/mcp-clients/openai-icon.svg
deleted file mode 100644
index 316440a338d..00000000000
--- a/apps/studio/public/img/mcp-clients/openai-icon.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/opencode-icon-dark.svg b/apps/studio/public/img/mcp-clients/opencode-icon-dark.svg
deleted file mode 100644
index b79c7332e20..00000000000
--- a/apps/studio/public/img/mcp-clients/opencode-icon-dark.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/opencode-icon.svg b/apps/studio/public/img/mcp-clients/opencode-icon.svg
deleted file mode 100644
index b79140a5070..00000000000
--- a/apps/studio/public/img/mcp-clients/opencode-icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/studio/public/img/mcp-clients/vscode-icon.svg b/apps/studio/public/img/mcp-clients/vscode-icon.svg
deleted file mode 100644
index c453e633f34..00000000000
--- a/apps/studio/public/img/mcp-clients/vscode-icon.svg
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/windsurf-icon-dark.svg b/apps/studio/public/img/mcp-clients/windsurf-icon-dark.svg
deleted file mode 100644
index 2e4e4e4921d..00000000000
--- a/apps/studio/public/img/mcp-clients/windsurf-icon-dark.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/studio/public/img/mcp-clients/windsurf-icon.svg b/apps/studio/public/img/mcp-clients/windsurf-icon.svg
deleted file mode 100644
index 386f8c035dc..00000000000
--- a/apps/studio/public/img/mcp-clients/windsurf-icon.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/packages/ui-patterns/src/McpUrlBuilder/McpConfigPanel.tsx b/packages/ui-patterns/src/McpUrlBuilder/McpConfigPanel.tsx
index 7ae5e4767aa..ed0c2193ba9 100644
--- a/packages/ui-patterns/src/McpUrlBuilder/McpConfigPanel.tsx
+++ b/packages/ui-patterns/src/McpUrlBuilder/McpConfigPanel.tsx
@@ -12,7 +12,6 @@ import type { McpClient, McpOnCopyCallback } from './types'
import { getMcpUrl } from './utils/getMcpUrl'
export interface McpConfigPanelProps {
- basePath: string
baseUrl?: string
projectRef?: string
initialSelectedClient?: McpClient
@@ -26,7 +25,6 @@ export interface McpConfigPanelProps {
}
export function McpConfigPanel({
- basePath,
projectRef,
initialSelectedClient,
onClientSelect,
@@ -109,7 +107,6 @@ export function McpConfigPanel({
clients={MCP_CLIENTS}
selectedClient={selectedClient}
onClientChange={handleClientChange}
- basePath={basePath}
theme={theme}
/>
@@ -124,7 +121,6 @@ export function McpConfigPanel({
diff --git a/apps/docs/public/img/mcp-clients/claude-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/claude-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/claude-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/claude-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/cursor-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/cursor-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/cursor-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/cursor-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/factory-icon-dark.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/factory-icon-dark.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/factory-icon-dark.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/factory-icon-dark.svg
diff --git a/apps/docs/public/img/mcp-clients/factory-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/factory-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/factory-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/factory-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/gemini-cli-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/gemini-cli-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/gemini-cli-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/gemini-cli-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/goose-icon-dark.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/goose-icon-dark.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/goose-icon-dark.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/goose-icon-dark.svg
diff --git a/apps/docs/public/img/mcp-clients/goose-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/goose-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/goose-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/goose-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/kiro-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/kiro-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/kiro-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/kiro-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/openai-icon-dark.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/openai-icon-dark.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/openai-icon-dark.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/openai-icon-dark.svg
diff --git a/apps/docs/public/img/mcp-clients/openai-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/openai-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/openai-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/openai-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/opencode-icon-dark.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/opencode-icon-dark.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/opencode-icon-dark.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/opencode-icon-dark.svg
diff --git a/apps/docs/public/img/mcp-clients/opencode-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/opencode-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/opencode-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/opencode-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/vscode-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/vscode-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/vscode-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/vscode-icon.svg
diff --git a/apps/docs/public/img/mcp-clients/windsurf-icon-dark.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/windsurf-icon-dark.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/windsurf-icon-dark.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/windsurf-icon-dark.svg
diff --git a/apps/docs/public/img/mcp-clients/windsurf-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/windsurf-icon.svg
similarity index 100%
rename from apps/docs/public/img/mcp-clients/windsurf-icon.svg
rename to packages/ui-patterns/src/McpUrlBuilder/assets/windsurf-icon.svg
diff --git a/packages/ui-patterns/src/McpUrlBuilder/components/ClientSelectDropdown.tsx b/packages/ui-patterns/src/McpUrlBuilder/components/ClientSelectDropdown.tsx
index e4978036472..f11e0beaff1 100644
--- a/packages/ui-patterns/src/McpUrlBuilder/components/ClientSelectDropdown.tsx
+++ b/packages/ui-patterns/src/McpUrlBuilder/components/ClientSelectDropdown.tsx
@@ -20,7 +20,6 @@ import type { McpClient } from '../types'
import { ConnectionIcon } from './ConnectionIcon'
interface ClientSelectDropdownProps {
- basePath: string
theme?: 'light' | 'dark'
label?: string
clients: McpClient[]
@@ -29,7 +28,6 @@ interface ClientSelectDropdownProps {
}
export const ClientSelectDropdown = ({
- basePath,
theme = 'light',
label = 'Client',
clients,
@@ -64,8 +62,6 @@ export const ClientSelectDropdown = ({
{selectedClient?.icon ? (
{client.icon ? (
{
const src = getMcpClientIconSrc({
- basePath,
- iconFolder,
icon: connection,
useDarkVariant: theme === 'dark',
hasDistinctDarkIcon,
diff --git a/packages/ui-patterns/src/McpUrlBuilder/components/McpConfigurationDisplay.tsx b/packages/ui-patterns/src/McpUrlBuilder/components/McpConfigurationDisplay.tsx
index 13aef8b1f79..7ef4e4bc0c5 100644
--- a/packages/ui-patterns/src/McpUrlBuilder/components/McpConfigurationDisplay.tsx
+++ b/packages/ui-patterns/src/McpUrlBuilder/components/McpConfigurationDisplay.tsx
@@ -15,7 +15,6 @@ interface McpConfigurationDisplayProps {
clientConfig: McpClientConfig
className?: string
theme?: 'light' | 'dark'
- basePath: string
onCopyCallback: (type?: McpOnCopyCallback) => void
onInstallCallback?: () => void
isPlatform?: boolean
@@ -28,13 +27,11 @@ export function McpConfigurationDisplay({
clientConfig,
className,
theme = 'dark',
- basePath,
onCopyCallback,
onInstallCallback,
isPlatform,
}: McpConfigurationDisplayProps) {
const mcpButtonData = getMcpButtonData({
- basePath,
theme,
client: selectedClient,
clientConfig,
diff --git a/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpButtonData.ts b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpButtonData.ts
index 415ccd23de2..b3e386c2883 100644
--- a/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpButtonData.ts
+++ b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpButtonData.ts
@@ -2,7 +2,6 @@ import type { McpClient, McpClientConfig } from '../types'
import { getMcpClientIconSrc } from './getMcpIconSrc'
interface GetMcpButtonDataOptions {
- basePath: string
theme?: 'light' | 'dark'
client: McpClient
clientConfig: McpClientConfig
@@ -10,7 +9,6 @@ interface GetMcpButtonDataOptions {
}
export function getMcpButtonData({
- basePath,
theme,
client,
clientConfig,
@@ -22,8 +20,6 @@ export function getMcpButtonData({
// If the theme is dark, the button background will be light and vice-versa
const imageSrc = getMcpClientIconSrc({
- basePath,
- iconFolder: 'mcp-clients',
icon: client.icon!,
useDarkVariant: theme === 'light',
hasDistinctDarkIcon: client.hasDistinctDarkIcon,
diff --git a/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.test.ts b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.test.ts
new file mode 100644
index 00000000000..d5b2c9fbff7
--- /dev/null
+++ b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.test.ts
@@ -0,0 +1,50 @@
+import { describe, expect, it } from 'vitest'
+
+import { getMcpClientIconSrc } from './getMcpIconSrc'
+
+describe('getMcpClientIconSrc', () => {
+ it('returns the default icon when only one asset variant exists', () => {
+ const lightSrc = getMcpClientIconSrc({
+ icon: 'cursor',
+ useDarkVariant: false,
+ })
+ const darkSrc = getMcpClientIconSrc({
+ icon: 'cursor',
+ useDarkVariant: true,
+ })
+
+ expect(lightSrc).toBeTruthy()
+ expect(darkSrc).toBe(lightSrc)
+ })
+
+ it('returns the dark icon when a distinct dark variant exists', () => {
+ const lightSrc = getMcpClientIconSrc({
+ icon: 'openai',
+ useDarkVariant: false,
+ hasDistinctDarkIcon: true,
+ })
+ const darkSrc = getMcpClientIconSrc({
+ icon: 'openai',
+ useDarkVariant: true,
+ hasDistinctDarkIcon: true,
+ })
+
+ expect(darkSrc).toBeTruthy()
+ expect(darkSrc).not.toBe(lightSrc)
+ })
+
+ it('falls back to the default icon when no distinct dark variant should be used', () => {
+ const lightSrc = getMcpClientIconSrc({
+ icon: 'factory',
+ useDarkVariant: false,
+ hasDistinctDarkIcon: true,
+ })
+ const src = getMcpClientIconSrc({
+ icon: 'factory',
+ useDarkVariant: true,
+ hasDistinctDarkIcon: false,
+ })
+
+ expect(src).toBe(lightSrc)
+ })
+})
diff --git a/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.ts b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.ts
index bac98a6a6c1..45012cbcd52 100644
--- a/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.ts
+++ b/packages/ui-patterns/src/McpUrlBuilder/utils/getMcpIconSrc.ts
@@ -1,21 +1,17 @@
+import { getMcpClientIconAssetUrl } from './mcpIconAssets'
+
/**
- * Returns the path to an MCP client icon.
- * Light: {icon}-icon.svg, dark (when hasDistinctDarkIcon): {icon}-icon-dark.svg.
- * Only uses the dark variant when useDarkVariant is true AND hasDistinctDarkIcon is set.
+ * Returns the URL to an imported MCP client icon asset.
+ * Dark variants are only used when the client has a distinct dark asset.
*/
export function getMcpClientIconSrc({
- basePath,
- iconFolder,
icon,
useDarkVariant,
hasDistinctDarkIcon,
}: {
- basePath: string
- iconFolder: string
icon: string
useDarkVariant: boolean
hasDistinctDarkIcon?: boolean
}): string {
- const suffix = useDarkVariant && hasDistinctDarkIcon ? '-dark' : ''
- return `${basePath}/img/${iconFolder}/${icon.toLowerCase()}-icon${suffix}.svg`
+ return getMcpClientIconAssetUrl(icon, useDarkVariant && Boolean(hasDistinctDarkIcon))
}
diff --git a/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts b/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts
new file mode 100644
index 00000000000..9641d13370b
--- /dev/null
+++ b/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts
@@ -0,0 +1,52 @@
+///
+
+import antigravityIcon from '../assets/antigravity-icon.svg'
+import claudeIcon from '../assets/claude-icon.svg'
+import cursorIcon from '../assets/cursor-icon.svg'
+import factoryDarkIcon from '../assets/factory-icon-dark.svg'
+import factoryIcon from '../assets/factory-icon.svg'
+import geminiCliIcon from '../assets/gemini-cli-icon.svg'
+import gooseDarkIcon from '../assets/goose-icon-dark.svg'
+import gooseIcon from '../assets/goose-icon.svg'
+import kiroIcon from '../assets/kiro-icon.svg'
+import openaiDarkIcon from '../assets/openai-icon-dark.svg'
+import openaiIcon from '../assets/openai-icon.svg'
+import opencodeDarkIcon from '../assets/opencode-icon-dark.svg'
+import opencodeIcon from '../assets/opencode-icon.svg'
+import vscodeIcon from '../assets/vscode-icon.svg'
+import windsurfDarkIcon from '../assets/windsurf-icon-dark.svg'
+import windsurfIcon from '../assets/windsurf-icon.svg'
+
+type ImportedAssetModule = string | { src: string }
+
+type McpClientIconAsset = {
+ light: ImportedAssetModule
+ dark: ImportedAssetModule
+}
+
+const MCP_CLIENT_ICON_ASSETS = {
+ antigravity: { light: antigravityIcon, dark: antigravityIcon },
+ claude: { light: claudeIcon, dark: claudeIcon },
+ cursor: { light: cursorIcon, dark: cursorIcon },
+ factory: { light: factoryIcon, dark: factoryDarkIcon },
+ 'gemini-cli': { light: geminiCliIcon, dark: geminiCliIcon },
+ goose: { light: gooseIcon, dark: gooseDarkIcon },
+ kiro: { light: kiroIcon, dark: kiroIcon },
+ openai: { light: openaiIcon, dark: openaiDarkIcon },
+ opencode: { light: opencodeIcon, dark: opencodeDarkIcon },
+ vscode: { light: vscodeIcon, dark: vscodeIcon },
+ windsurf: { light: windsurfIcon, dark: windsurfDarkIcon },
+} satisfies Record
+
+export type McpClientIconName = keyof typeof MCP_CLIENT_ICON_ASSETS
+
+function normalizeAssetUrl(asset: ImportedAssetModule): string {
+ return typeof asset === 'string' ? asset : asset.src
+}
+
+export function getMcpClientIconAssetUrl(icon: string, useDarkVariant: boolean): string {
+ const iconAssets = MCP_CLIENT_ICON_ASSETS[icon.toLowerCase() as McpClientIconName]
+ if (!iconAssets) return ''
+
+ return normalizeAssetUrl(useDarkVariant ? iconAssets.dark : iconAssets.light)
+}
diff --git a/packages/ui-patterns/src/types/assets.d.ts b/packages/ui-patterns/src/types/assets.d.ts
index a4a9b8157f7..adb1bc31dbb 100644
--- a/packages/ui-patterns/src/types/assets.d.ts
+++ b/packages/ui-patterns/src/types/assets.d.ts
@@ -2,3 +2,8 @@ declare module '*.css' {
export const styles: Record
export default styles
}
+
+declare module '*.svg' {
+ const content: any
+ export default content
+}