'use client' import { useDebounce } from '~/hooks/useDebounce' import { useIntersectionObserver } from '~/hooks/useIntersectionObserver' import { getCustomContent } from '~/lib/custom-content/getCustomContent' import { useProjectsInfiniteQuery } from '~/lib/fetch/projects-infinite' import { useSendTelemetryEvent } from '~/lib/telemetry' import { useIsLoggedIn, useIsUserLoading } from 'common' import { Check, ChevronDown } from 'lucide-react' import { useTheme } from 'next-themes' import Link from 'next/link' import { useEffect, useMemo, useRef, useState } from 'react' import { Button, cn, Command, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, ScrollArea, } from 'ui' import { Admonition } from 'ui-patterns/Admonition' import { createMcpCopyHandler, MCP_HOSTED_AUTH_NOTE, McpConfigPanel as McpConfigPanelBase, type McpClient, } from 'ui-patterns/McpUrlBuilder' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' type PlatformType = (typeof PLATFORMS)[number]['value'] const PLATFORMS = [ { value: 'hosted', label: 'Hosted' }, { value: 'local', label: 'CLI' }, ] as const satisfies Array<{ value: string; label: string }> // [Joshen] Ideally we consolidate this component with what's in ProjectConfigVariables - they seem to be doing the same thing function ProjectSelector({ className, selectedProject, onProjectSelect, }: { className?: string selectedProject?: { ref: string; name: string } | null onProjectSelect?: (project: { ref: string; name: string } | null) => void }) { const [open, setOpen] = useState(false) const [search, setSearch] = useState('') const debouncedSearch = useDebounce(search, 500) const scrollRootRef = useRef(null) const [sentinelRef, entry] = useIntersectionObserver({ root: scrollRootRef.current, threshold: 0, rootMargin: '0px', }) const isUserLoading = useIsUserLoading() const isLoggedIn = useIsLoggedIn() const { data: projectsData, isLoading, isError, isFetching, isFetchingNextPage, hasNextPage, fetchNextPage, } = useProjectsInfiniteQuery( { search: search.length === 0 ? search : debouncedSearch }, { enabled: isLoggedIn } ) const projects = useMemo(() => projectsData?.pages.flatMap((page) => page.projects), [projectsData?.pages]) || [] useEffect(() => { if ( !isLoading && !isFetching && !isFetchingNextPage && hasNextPage && entry?.isIntersecting && !!fetchNextPage ) { fetchNextPage() } }, [isLoading, isFetching, isFetchingNextPage, hasNextPage, entry?.isIntersecting, fetchNextPage]) return ( { setOpen(open) if (!open) setSearch('') }} >
Project {!isUserLoading && !isLoggedIn ? ( ) : ( )}
setSearch('')} /> {isLoading ? (
) : ( <> {search.length > 0 && projects.length === 0 && (

No projects found based on your search

)} 7 ? 'h-[210px]' : ''}> {projects?.map((project) => ( { onProjectSelect?.(project.ref === selectedProject?.ref ? null : project) setOpen(false) }} className="flex gap-2 items-center" > {project.name} ))}
{hasNextPage && } )} ) } function PlatformSelector({ className, selectedPlatform, onPlatformSelect, }: { className?: string selectedPlatform: PlatformType onPlatformSelect?: (platform: PlatformType) => void }) { const [open, setOpen] = useState(false) return (
Platform
{PLATFORMS.map((platform) => ( { onPlatformSelect?.(platform.value) setOpen(false) }} className="flex gap-2 items-center" > {platform.label} ))}
) } export function McpConfigPanel() { const [selectedProject, setSelectedProject] = useState<{ ref: string; name: string } | null>(null) const [selectedPlatform, setSelectedPlatform] = useState<'hosted' | 'local'>('hosted') const [selectedClient, setSelectedClient] = useState(null) const { resolvedTheme } = useTheme() const sendTelemetryEvent = useSendTelemetryEvent() const { mcpServers } = getCustomContent(['mcp:servers']) const isPlatform = selectedPlatform === 'hosted' const project = isPlatform ? selectedProject : null const handleCopy = useMemo( () => createMcpCopyHandler({ selectedClient, source: 'docs', onTrack: (event) => { sendTelemetryEvent({ action: event.action, properties: event.properties, groups: (event.groups || {}) as any, }) }, projectRef: project?.ref, }), [selectedClient, sendTelemetryEvent, project?.ref] ) const handleInstall = () => { if (selectedClient?.label) { sendTelemetryEvent({ action: 'mcp_install_button_clicked', properties: { client: selectedClient.label, source: 'docs', }, groups: { ...(project?.ref && { project: project.ref }), } as any, }) } } return ( <>
{isPlatform && ( )}

{isPlatform ? 'Scope the MCP server to a project. If no project is selected, all projects will be accessible.' : 'Project selection is only available for the hosted platform.'}

{isPlatform && (

{MCP_HOSTED_AUTH_NOTE.body}

)} ) }