import { $fetch } from "@lib/api" import { authClient } from "@lib/auth" import { useAuth } from "@lib/auth-context" import { useForm } from "@tanstack/react-form" import { useMutation } from "@tanstack/react-query" import { Button } from "@ui/components/button" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@ui/components/dialog" import { Input } from "@ui/components/input" import { CopyableCell } from "@ui/copyable-cell" import { Loader2 } from "lucide-react" import { AnimatePresence, motion } from "motion/react" import Image from "next/image" import { generateSlug } from "random-word-slugs" import { useEffect, useState } from "react" import { toast } from "sonner" import { z } from "zod/v4" import { analytics } from "@/lib/analytics" import { InstallationDialogContent } from "./installation-dialog-content" // Validation schemas const mcpMigrationSchema = z.object({ url: z .string() .min(1, "MCP Link is required") .regex( /^https:\/\/mcp\.supermemory\.ai\/[^/]+\/sse$/, "Link must be in format: https://mcp.supermemory.ai/userId/sse", ), }) export function MCPView() { const [isMigrateDialogOpen, setIsMigrateDialogOpen] = useState(false) const projectId = localStorage.getItem("selectedProject") ?? "default" const { org } = useAuth() const [apiKey, setApiKey] = useState() const [isInstallDialogOpen, setIsInstallDialogOpen] = useState(false) useEffect(() => { analytics.mcpViewOpened() }, []) const apiKeyMutation = useMutation({ mutationFn: async () => { if (apiKey) return apiKey const res = await authClient.apiKey.create({ metadata: { organizationId: org?.id, }, name: generateSlug(), prefix: `sm_${org?.id}_`, }) return res.key }, onSuccess: (data) => { setApiKey(data) setIsInstallDialogOpen(true) }, }) // Form for MCP migration const mcpMigrationForm = useForm({ defaultValues: { url: "" }, onSubmit: async ({ value, formApi }) => { const userId = extractUserIdFromMCPUrl(value.url) if (userId) { migrateMCPMutation.mutate({ userId, projectId }) formApi.reset() } }, validators: { onChange: mcpMigrationSchema, }, }) const extractUserIdFromMCPUrl = (url: string): string | null => { const regex = /^https:\/\/mcp\.supermemory\.ai\/([^/]+)\/sse$/ const match = url.trim().match(regex) return match?.[1] || null } // Migrate MCP mutation const migrateMCPMutation = useMutation({ mutationFn: async ({ userId, projectId, }: { userId: string projectId: string }) => { const response = await $fetch("@post/documents/migrate-mcp", { body: { userId, projectId }, }) if (response.error) { throw new Error( response.error?.message || "Failed to migrate documents", ) } return response.data }, onSuccess: (data) => { toast.success("Migration completed!", { description: `Successfully migrated ${data?.migratedCount} documents`, }) setIsMigrateDialogOpen(false) }, onError: (error) => { toast.error("Migration failed", { description: error instanceof Error ? error.message : "Unknown error", }) }, }) return (

Use MCP to create and access memories directly from your AI assistant. Integrate supermemory with Claude Desktop, Cursor, and other AI tools.

Use this URL to configure supermemory in your AI assistant

{apiKey && } Add supermemory MCP server to Cursor
{isMigrateDialogOpen && ( Migrate from MCP v1 Migrate your MCP documents from the legacy system.
{ e.preventDefault() e.stopPropagation() mcpMigrationForm.handleSubmit() }} >
{({ state, handleChange, handleBlur }) => ( <> handleChange(e.target.value)} placeholder="https://mcp.supermemory.ai/your-user-id/sse" value={state.value} /> {state.meta.errors.length > 0 && ( {state.meta.errors.join(", ")} )} )}

Enter your old MCP Link in the format:
https://mcp.supermemory.ai/userId/sse

)}
) }