Skip to main content
Glama

Convex MCP server

Official
by get-convex
IntegrationStatus.tsx5.72 kB
import { useQuery } from "convex/react"; import Link from "next/link"; import udfs from "@common/udfs"; import { useRouter } from "next/router"; import { IntegrationConfig, IntegrationType, } from "system-udfs/convex/_system/frontend/common"; import { ExternalLinkIcon, GearIcon } from "@radix-ui/react-icons"; import { useContext } from "react"; import { HealthCard } from "@common/elements/HealthCard"; import { DeploymentInfoContext } from "@common/lib/deploymentContext"; import { Button } from "@ui/Button"; import { Tooltip } from "@ui/Tooltip"; import { Loading } from "@ui/Loading"; import { integrationName, configToUrl, integrationUsingLegacyFormat, integrationToLogo, } from "@common/lib/integrationHelpers"; export function IntegrationStatus({ integrationTypes, title, notConfiguredSummary, }: { integrationTypes: IntegrationConfig["type"][]; title: string; notConfiguredSummary: React.ReactNode; }) { const { useCurrentDeployment } = useContext(DeploymentInfoContext); const deployment = useCurrentDeployment(); if (deployment?.kind === "local") { return null; } return ( <IntegrationStatusCard integrationTypes={integrationTypes} title={title} notConfiguredSummary={notConfiguredSummary} /> ); } function IntegrationStatusCard({ integrationTypes, title, notConfiguredSummary, }: { integrationTypes: IntegrationConfig["type"][]; title: string; notConfiguredSummary: React.ReactNode; }) { const { useLogDeploymentEvent } = useContext(DeploymentInfoContext); const log = useLogDeploymentEvent(); const integrations = useQuery(udfs.listConfiguredSinks.default); const configuredIntegrations = integrations?.filter( (integration) => "config" in integration && "type" in integration.config && integrationTypes.some((type) => integration.config.type === type), ); const router = useRouter(); const integrationStatus = !configuredIntegrations ? undefined : configuredIntegrations.length === 0 ? "notConfigured" : configuredIntegrations[0].status.type === "active" ? "configured" : "error"; const error = integrationStatus === "error" ? "The integration setup has failed." : undefined; const warning = integrations && integrations.some((integration) => integrationUsingLegacyFormat(integration.config), ) ? `${integrations.length === 1 ? "This integration is" : "Some integrations are"} using a legacy event format. Re-configure the deprecated integration to update the event format.` : undefined; const integrationsPageLink = `${router.asPath}/settings/integrations`; const icons = ( <div className="flex gap-2"> {integrationTypes.map((kind, idx) => ( <IntegrationIcon kind={kind} key={idx} /> ))} </div> ); return ( <HealthCard title={title} error={error} warning={warning} size="sm" action={ <> {configuredIntegrations && configuredIntegrations.length === 0 && icons} {configuredIntegrations && configuredIntegrations[0] && ( <Button tip={`Go to ${integrationName(configuredIntegrations[0].config.type)}`} icon={<ExternalLinkIcon />} href={configToUrl(configuredIntegrations[0].config)} onClickOfAnchorLink={() => log("go to integration via health")} target="_blank" size="xs" inline variant="neutral" /> )} <Button tip="Configure Integrations" icon={<GearIcon />} href={integrationsPageLink} onClickOfAnchorLink={() => log("configure integrations via health")} target="_blank" size="xs" inline variant="neutral" /> </> } > <div className="flex h-full w-full items-center px-2 pb-2 text-pretty"> {integrationStatus === undefined ? ( <Loading className="h-5 w-32" /> ) : integrationStatus === "notConfigured" ? ( <div className="animate-fadeInFromLoading"> {notConfiguredSummary} </div> ) : integrationStatus === "configured" ? ( configuredIntegrations !== undefined ? ( <div className="flex animate-fadeInFromLoading items-start gap-2"> {configuredIntegrations.map((integration, idx) => ( <IntegrationIcon kind={integration.config.type} key={idx} /> ))} {configuredIntegrations.length > 1 ? ( <> There are {configuredIntegrations.length} configured integrations. </> ) : ( <> {integrationName(configuredIntegrations[0].config.type)} is configured. </> )} </div> ) : ( <Loading className="h-5 w-32" /> ) ) : ( <span className="animate-fadeInFromLoading"> Check your{" "} <Link href={integrationsPageLink} className="text-content-link hover:underline" > integration configuration </Link> . </span> )} </div> </HealthCard> ); } function IntegrationIcon({ kind }: { kind: IntegrationType }) { return ( <Tooltip tip={integrationName(kind)} className="shrink-0 animate-fadeInFromLoading cursor-default" > {integrationToLogo(kind, true).logo}{" "} </Tooltip> ); }

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/get-convex/convex-backend'

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