diff --git a/frontend/src/app/pages/Tools/cards/CustomToolCard.tsx b/frontend/src/app/pages/Tools/cards/CustomToolCard.tsx index d6c7da39..571eb681 100644 --- a/frontend/src/app/pages/Tools/cards/CustomToolCard.tsx +++ b/frontend/src/app/pages/Tools/cards/CustomToolCard.tsx @@ -111,7 +111,7 @@ const CustomToolCard: React.FC = ({ {ig && ( {ig.icon} diff --git a/frontend/src/app/pages/Tools/cards/IntegrationGalleryCard.tsx b/frontend/src/app/pages/Tools/cards/IntegrationGalleryCard.tsx index 5b1bcbc1..b4cbbc77 100644 --- a/frontend/src/app/pages/Tools/cards/IntegrationGalleryCard.tsx +++ b/frontend/src/app/pages/Tools/cards/IntegrationGalleryCard.tsx @@ -27,7 +27,7 @@ const IntegrationGalleryCard: React.FC = ({ integra {ig.icon} diff --git a/frontend/src/app/pages/Tools/integrationIcons.tsx b/frontend/src/app/pages/Tools/integrationIcons.tsx new file mode 100644 index 00000000..a07c4cc7 --- /dev/null +++ b/frontend/src/app/pages/Tools/integrationIcons.tsx @@ -0,0 +1,94 @@ +import React from 'react'; + +export const XIcon = ( + + + +); + +export const SpotifyIcon = ( + + + + +); + +export const TikTokIcon = ( + + + +); + +export const RedditIcon = ( + + + + +); + +export const YouTubeIcon = ( + + + + +); + +export const GitHubIcon = ( + + + +); + +export const GoogleWorkspaceIcon = ( + + + + + + +); + +export const Microsoft365Icon = ( + + + +); + +export const NotionIcon = ( + + + + +); + +export const AirtableIcon = ( + + + + + + +); + +export const HubSpotIcon = ( + + + +); + +export const SlackIcon = ( + + + + + + +); + +export const DiscordIcon = ( + + + +); diff --git a/frontend/src/app/pages/Tools/integrations.tsx b/frontend/src/app/pages/Tools/integrations.tsx index af0be2f5..c928a1a3 100644 --- a/frontend/src/app/pages/Tools/integrations.tsx +++ b/frontend/src/app/pages/Tools/integrations.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { AirtableIcon, DiscordIcon, GitHubIcon, GoogleWorkspaceIcon, HubSpotIcon, Microsoft365Icon, NotionIcon, RedditIcon, SlackIcon, SpotifyIcon, TikTokIcon, XIcon, YouTubeIcon } from './integrationIcons'; export interface CredentialField { key: string; @@ -34,11 +35,7 @@ export const INTEGRATIONS: Integration[] = [ connectLabel: 'Sign in to X', loginUrl: 'https://x.com/i/flow/login', connectInstructions: 'Uses your own X account: open x.com in an OpenSwarm browser card and sign in once. Nothing is stored, the integration borrows your live session per request and paces itself to stay within human limits.', - icon: ( - - - - ), + icon: XIcon, }, { id: 'spotify', @@ -50,13 +47,8 @@ export const INTEGRATIONS: Integration[] = [ authType: 'browser_login', connectLabel: 'Instructions', loginUrl: '#', - connectInstructions: 'IMPORTANT: Spotify DRM blocks internal browsers. When you run a command for the first time, an external Google Chrome window will automatically open. Please sign into Spotify in that external window. Do NOT log in via the internal OpenSwarm browser, as playback will fail.', - icon: ( - - - - - ), + connectInstructions: 'IMPORTANT: Spotify DRM blocks internal browsers. When you run a command for the first time, an external browser window will automatically open. Please sign into Spotify in that external window. Do NOT log in via the internal OpenSwarm browser, as playback will fail.', + icon: SpotifyIcon, }, { id: 'tiktok', @@ -69,11 +61,7 @@ export const INTEGRATIONS: Integration[] = [ connectLabel: 'Sign in to TikTok', loginUrl: 'https://www.tiktok.com/login', connectInstructions: 'Uses your own TikTok account: open tiktok.com in an OpenSwarm browser card and sign in once. Nothing is stored. Note: TikTok signs every request, so signed writes and uploads route to the OpenSwarm browser agent (also free, using your real session).', - icon: ( - - - - ), + icon: TikTokIcon, }, { id: 'reddit', @@ -86,12 +74,7 @@ export const INTEGRATIONS: Integration[] = [ connectLabel: 'Sign in to Reddit', loginUrl: 'https://www.reddit.com/login', connectInstructions: 'Uses your own Reddit account: open reddit.com in an OpenSwarm browser card and sign in once. Nothing is stored, the integration borrows your live session per request and paces itself to stay within human limits.', - icon: ( - - - - - ), + icon: RedditIcon, }, { id: 'youtube', @@ -100,12 +83,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'npx', args: ['-y', '@kirbah/mcp-youtube'] }, color: '#FF0000', website: 'https://www.npmjs.com/package/@kirbah/mcp-youtube', - icon: ( - - - - - ), + icon: YouTubeIcon, }, { id: 'github', @@ -114,11 +92,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'http', url: 'https://api.githubcopilot.com/mcp/x/all' }, color: '#181717', website: 'https://github.com/github/github-mcp-server', - icon: ( - - - - ), + icon: GitHubIcon, authType: 'oauth2', }, { @@ -128,14 +102,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'uvx', args: ['--from', 'google-workspace-mcp', 'google-workspace-worker'] }, color: '#4285F4', website: 'https://developers.google.com/gemini-api/docs/mcp', - icon: ( - - - - - - - ), + icon: GoogleWorkspaceIcon, authType: 'oauth2', }, { @@ -145,11 +112,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'npx', args: ['-y', '@softeria/ms-365-mcp-server'] }, color: '#0078D4', website: 'https://www.npmjs.com/package/@softeria/ms-365-mcp-server', - icon: ( - - - - ), + icon: Microsoft365Icon, authType: 'device_code', }, { @@ -159,11 +122,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'npx', args: ['-y', '@notionhq/notion-mcp-server'] }, color: '#000000', website: 'https://www.npmjs.com/package/@notionhq/notion-mcp-server', - icon: ( - - - - ), + icon: NotionIcon, authType: 'oauth2', }, { @@ -173,14 +132,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'http', url: 'https://mcp.airtable.com/mcp' }, color: '#18BFFF', website: 'https://airtable.com/developers/web/api/introduction', - icon: ( - - - - - - - ), + icon: AirtableIcon, authType: 'oauth2', }, { @@ -190,11 +142,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'npx', args: ['-y', '@hubspot/mcp-server'] }, color: '#FF7A59', website: 'https://developers.hubspot.com/docs/guides/apps/developer-platform/build-apps/integrate-with-the-remote-hubspot-mcp-server', - icon: ( - - - - ), + icon: HubSpotIcon, authType: 'oauth2', }, { @@ -204,14 +152,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'npx', args: ['-y', 'slack-mcp-server@latest', '--transport', 'stdio'], env: { SLACK_MCP_ADD_MESSAGE_TOOL: 'true' } }, color: '#4A154B', website: 'https://github.com/korotovsky/slack-mcp-server', - icon: ( - - - - - - - ), + icon: SlackIcon, connectLabel: 'Connect Slack', connectInstructions: 'On macOS with Chrome, tokens are auto-extracted. Otherwise: open app.slack.com in Chrome → F12 → Console → type `JSON.stringify({token: boot_data.api_token, cookie: document.cookie.match(/d=([^;]+)/)?.[1]})` → copy the result.', credentialFields: [ @@ -226,11 +167,7 @@ export const INTEGRATIONS: Integration[] = [ mcp_config: { type: 'stdio', command: 'python', args: ['-m', 'backend.apps.discord_mcp_shim'] }, color: '#5865F2', website: 'https://github.com/barryyip0625/mcp-discord', - icon: ( - - - - ), + icon: DiscordIcon, authType: 'oauth2', }, ];