Skip to main content
Glama

Karakeep MCP server

by karakeep-app
RuleEngineRuleList.tsx5.29 kB
import { ActionButton } from "@/components/ui/action-button"; import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Switch } from "@/components/ui/switch"; import { toast } from "@/components/ui/use-toast"; import { useClientConfig } from "@/lib/clientConfig"; import { Edit, Trash2 } from "lucide-react"; import { useTranslation } from "react-i18next"; import type { RuleEngineRule } from "@karakeep/shared/types/rules"; import { useDeleteRule, useUpdateRule, } from "@karakeep/shared-react/hooks/rules"; export default function RuleList({ rules, onEditRule, onDeleteRule, }: { rules: RuleEngineRule[]; onEditRule: (rule: RuleEngineRule) => void; onDeleteRule?: (ruleId: string) => void; }) { const { t } = useTranslation(); const { demoMode } = useClientConfig(); const { mutate: updateRule, isPending: isUpdating } = useUpdateRule({ onSuccess: () => { toast({ description: t("settings.rules.rule_has_been_updated"), }); }, onError: (e) => { toast({ description: e.message, variant: "destructive", }); }, }); const { mutate: deleteRule, isPending: isDeleting } = useDeleteRule({ onSuccess: (_ret, req) => { toast({ description: t("settings.rules.rule_has_been_deleted"), }); onDeleteRule?.(req.id); }, onError: (e) => { toast({ description: e.message, variant: "destructive", }); }, }); if (rules.length === 0) { return ( <div className="rounded-lg border border-dashed p-8 text-center"> <h3 className="text-lg font-medium"> {t("settings.rules.no_rules_created_yet")} </h3> <p className="mt-2 text-sm text-muted-foreground"> {t("settings.rules.create_your_first_rule")} </p> </div> ); } return ( <div className="space-y-4"> {rules.map((rule) => ( <Card key={rule.id} className={rule.enabled ? "" : "opacity-70"}> <CardContent className="p-4"> <div className="flex items-center justify-between"> <div className="mr-4 flex-1"> <h3 className="font-medium">{rule.name}</h3> <p className="line-clamp-2 text-sm text-muted-foreground"> {rule.description} </p> <div className="mt-2 flex items-center text-xs text-muted-foreground"> <span className="flex items-center"> <span className="mr-1">Trigger:</span> <span className="font-medium"> {formatEventType(rule.event.type)} </span> </span> <span className="mx-2">•</span> <span> {rule.actions.length} action {rule.actions.length !== 1 ? "s" : ""} </span> </div> </div> <div className="flex items-center space-x-2"> <Switch disabled={!!demoMode || isUpdating} checked={rule.enabled} onCheckedChange={(checked) => updateRule({ ...rule, enabled: checked, }) } /> <Button variant="ghost" size="icon" onClick={() => onEditRule(rule)} > <Edit className="h-4 w-4" /> </Button> <ActionConfirmingDialog title={t("settings.rules.delete_rule")} description={t("settings.rules.delete_rule_confirmation")} actionButton={(setDialogOpen) => ( <ActionButton loading={isDeleting} variant="destructive" onClick={() => { deleteRule({ id: rule.id }); setDialogOpen(true); }} > <Trash2 className="mr-2 h-4 w-4" /> {t("actions.delete")} </ActionButton> )} > <Button variant="ghost" size="icon" className="text-red-500 hover:text-red-600" > <Trash2 className="h-4 w-4" /> </Button> </ActionConfirmingDialog> </div> </div> </CardContent> </Card> ))} </div> ); } function formatEventType(type: string): string { switch (type) { case "bookmarkAdded": return "Bookmark Added"; case "tagAdded": return "Tag Added"; case "tagRemoved": return "Tag Removed"; case "addedToList": return "Added to List"; case "removedFromList": return "Removed from List"; case "favourited": return "Favourited"; case "archived": return "Archived"; default: return type; } }

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/karakeep-app/karakeep'

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