Skip to main content
Glama

Convex MCP server

Official
by get-convex
FunctionSummary.tsx6.05 kB
import { PlayIcon } from "@radix-ui/react-icons"; import { useQuery } from "convex/react"; import { useContext, useState } from "react"; import { useSessionStorage } from "react-use"; import { lt } from "semver"; import udfs from "@common/udfs"; import { UdfType } from "system-udfs/convex/_system/frontend/common"; import { CopyTextButton } from "@common/elements/CopyTextButton"; import { FunctionRunnerDisabledWhilePaused } from "@common/features/functions/components/FunctionRunnerDisabledWhilePaused"; import { DeploymentInfoContext } from "@common/lib/deploymentContext"; import { useShowGlobalRunner } from "@common/features/functionRunner/lib/functionRunner"; import { ModuleFunction } from "@common/lib/functions/types"; import { Loading } from "@ui/Loading"; import { ProductionEditsConfirmationDialog } from "@common/elements/ProductionEditsConfirmationDialog"; import { Button } from "@ui/Button"; export function FunctionSummary({ currentOpenFunction, }: { currentOpenFunction: ModuleFunction; }) { const [prodEditsEnabled, setProdEditsEnabled] = useSessionStorage( "prodEditsEnabled", false, ); const [showEnableProdEditsModal, setShowEnableProdEditsModal] = useState(false); const npmPackageVersion = useQuery(udfs.getVersion.default); const versionTooOld = !!npmPackageVersion && lt(npmPackageVersion, "0.13.0"); const { useCurrentDeployment, useHasProjectAdminPermissions, useIsDeploymentPaused, } = useContext(DeploymentInfoContext); const deployment = useCurrentDeployment(); const isProd = deployment?.deploymentType === "prod"; const hasAdminPermissions = useHasProjectAdminPermissions( deployment?.projectId, ); const canRunFunction = currentOpenFunction.udfType === "Query" || !isProd || hasAdminPermissions; const showGlobalRunner = useShowGlobalRunner(); const showFunctionRunner = () => { showGlobalRunner(currentOpenFunction, "click"); }; const isPaused = useIsDeploymentPaused(); if (isPaused === undefined) { return <Loading />; } return ( <div className="flex h-full flex-col overflow-hidden"> <div className="flex flex-wrap items-end justify-between gap-2 pb-2"> {showEnableProdEditsModal && ( <ProductionEditsConfirmationDialog onClose={() => { setShowEnableProdEditsModal(false); }} onConfirm={async () => { setProdEditsEnabled(true); setShowEnableProdEditsModal(false); showFunctionRunner(); }} /> )} <div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-x-2"> <h3 className="font-mono">{currentOpenFunction.name}</h3> <div className={`rounded-sm p-1 text-xs font-semibold ${getFunctionTypeStyles(currentOpenFunction.udfType).text} ${getFunctionTypeStyles(currentOpenFunction.udfType).background}`} > {currentOpenFunction.visibility.kind === "internal" && "Internal "} {functionTypeLabel(currentOpenFunction.udfType)} </div> </div> {currentOpenFunction.displayName !== currentOpenFunction.name && ( <CopyTextButton className="font-mono" text={currentOpenFunction.displayName} /> )} </div> { // Supported UDF types for in-dashboard testing ["Query", "Mutation", "Action"].some( (udfType) => udfType === currentOpenFunction.udfType, ) && ( <Button tip={ !canRunFunction ? ( "You do not have permission to run this function in production." ) : isPaused ? ( <FunctionRunnerDisabledWhilePaused /> ) : ( versionTooOld && ( <div> The function runner is only available on deployments using Convex version 0.13.0 or greater. </div> ) ) } disabled={isPaused || versionTooOld || !canRunFunction} onClick={() => !isProd || prodEditsEnabled || currentOpenFunction.udfType === "Query" ? showFunctionRunner() : setShowEnableProdEditsModal(true) } icon={<PlayIcon />} size="xs" variant="primary" > Run Function </Button> ) } </div> </div> ); } export const functionTypeLabel = (udfType: UdfType) => { let text = ""; switch (udfType) { case "Query": text = "Query"; break; case "Mutation": text = "Mutation"; break; case "Action": text = "Action"; break; case "HttpAction": text = "HTTP"; break; default: // eslint-disable-next-line no-case-declarations, @typescript-eslint/no-unused-vars udfType satisfies never; text = "Function"; } return text; }; export const getFunctionTypeStyles = (udfType: UdfType) => { switch (udfType) { case "Query": return { text: "text-yellow-700 dark:text-yellow-200", background: "bg-yellow-100/50 dark:bg-yellow-900/50", }; case "Mutation": return { text: "text-blue-700 dark:text-blue-200", background: "bg-blue-100/50 dark:bg-blue-900/50", }; case "Action": return { text: "text-purple-700 dark:text-purple-200", background: "bg-purple-100/50 dark:bg-purple-900/50", }; case "HttpAction": return { text: "text-green-700 dark:text-green-200", background: "bg-green-100/50 dark:bg-green-900/50", }; default: return { text: "text-content-primary", background: "bg-background-tertiary", }; } };

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