Skip to main content
Glama
index.tsx5.5 kB
import Link from "fumadocs-core/link"; import { LanguageToggle, LanguageToggleText, } from "fumadocs-ui/components/layout/language-toggle"; import { LargeSearchToggle, SearchToggle, } from "fumadocs-ui/components/layout/search-toggle"; // import { ThemeToggle } from "fumadocs-ui/components/layout/theme-toggle"; import { NavigationMenuList } from "fumadocs-ui/components/ui/navigation-menu"; import type { HomeLayoutProps } from "fumadocs-ui/layouts/home"; import { NavbarLink, NavbarMenu, NavbarMenuContent, NavbarMenuTrigger, } from "fumadocs-ui/layouts/home/navbar"; import type { LinkItemType } from "fumadocs-ui/layouts/links"; import { SearchOnly } from "fumadocs-ui/provider"; import { ChevronDown, Languages } from "lucide-react"; import { ThemeToggle } from "../theme-toggle"; import { Menu, MenuContent, MenuLinkItem, MenuTrigger } from "./menu"; import { Navbar, NavbarMenuLink } from "./navbar"; export const Header = ({ nav: { enableSearch = true, ...nav } = {}, i18n = false, finalLinks, }: HomeLayoutProps & { finalLinks: LinkItemType[]; }) => { const navItems = finalLinks.filter((item) => ["nav", "all"].includes(item.on ?? "all") ); const menuItems = finalLinks.filter((item) => ["menu", "all"].includes(item.on ?? "all") ); return ( <Navbar> <Link href={nav.url ?? "/"} className="inline-flex items-center gap-2.5 font-semibold" > {nav.title} </Link> {nav.children} <NavigationMenuList className="ml-2 flex flex-row items-center gap-2 max-sm:hidden"> {navItems .filter((item) => !isSecondary(item)) .map((item, i) => ( <NavbarLinkItem key={i.toString()} item={item} className="text-sm" /> ))} </NavigationMenuList> <div className="flex flex-1 flex-row items-center justify-end lg:gap-1.5"> {enableSearch ? ( <SearchOnly> <SearchToggle className="lg:hidden" /> <LargeSearchToggle className="w-full max-w-[240px] max-lg:hidden" /> </SearchOnly> ) : null} {/* <ThemeToggle className='max-lg:hidden' /> */} <ThemeToggle className="max-lg:hidden" /> {navItems.filter(isSecondary).map((item, i) => ( <NavbarLinkItem key={i.toString()} item={item} className="-me-1.5 max-lg:hidden" /> ))} <Menu className="lg:hidden"> <MenuTrigger className="group -me-2"> <ChevronDown className="size-3 transition-transform duration-300 group-data-[state=open]:rotate-180" /> </MenuTrigger> <MenuContent className="sm:flex-row sm:items-center sm:justify-end"> {menuItems .filter((item) => !isSecondary(item)) .map((item, i) => ( <MenuLinkItem key={i.toString()} item={item} className="sm:hidden" /> ))} <div className="-ms-1.5 flex flex-row items-center gap-1.5 max-sm:mt-2"> {menuItems.filter(isSecondary).map((item, i) => ( <MenuLinkItem key={i.toString()} item={item} className="-me-1.5" /> ))} <div className="flex-1" /> {i18n ? ( <LanguageToggle> <Languages className="size-5" /> <LanguageToggleText /> <ChevronDown className="size-3 text-fd-muted-foreground" /> </LanguageToggle> ) : null} <ThemeToggle /> </div> </MenuContent> </Menu> </div> </Navbar> ); }; const NavbarLinkItem = ({ item, ...props }: { item: LinkItemType; className?: string; }) => { if (item.type === "custom") return <div {...props}>{item.children}</div>; if (item.type === "menu") { const children = item.items.map((child, j) => { if (child.type === "custom") return <div key={j.toString()}>{child.children}</div>; const { banner, footer, ...rest } = child.menu ?? {}; return ( <NavbarMenuLink key={j.toString()} href={child.url} {...rest}> {banner ?? (child.icon ? ( <div className="w-fit rounded-md border bg-fd-muted p-1 [&_svg]:size-4"> {child.icon} </div> ) : null)} <p className="-mb-1 font-medium text-sm">{child.text}</p> {child.description ? ( <p className="text-[13px] text-fd-muted-foreground"> {child.description} </p> ) : null} {footer} </NavbarMenuLink> ); }); return ( <NavbarMenu> <NavbarMenuTrigger {...props}> {item.url ? <Link href={item.url}>{item.text}</Link> : item.text} </NavbarMenuTrigger> <NavbarMenuContent>{children}</NavbarMenuContent> </NavbarMenu> ); } return ( <NavbarLink {...props} item={item} variant={item.type} aria-label={item.type === "icon" ? item.label : undefined} > {item.type === "icon" ? item.icon : item.text} </NavbarLink> ); }; const isSecondary = (item: LinkItemType): boolean => { return ( ("secondary" in item && item.secondary === true) || item.type === "icon" ); };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/metacode0602/open-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server