Skip to main content
Glama

Karakeep MCP server

by karakeep-app
QueryExplainerTooltip.tsx6.87 kB
import InfoTooltip from "@/components/ui/info-tooltip"; import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table"; import { useTranslation } from "@/lib/i18n/client"; import { match } from "@/lib/utils"; import { TextAndMatcher } from "@karakeep/shared/searchQueryParser"; import { Matcher } from "@karakeep/shared/types/search"; export default function QueryExplainerTooltip({ parsedSearchQuery, header, className, }: { header?: React.ReactNode; parsedSearchQuery: TextAndMatcher & { result: string }; className?: string; }) { const { t } = useTranslation(); if (parsedSearchQuery.result == "invalid") { return null; } const MatcherComp = ({ matcher }: { matcher: Matcher }) => { switch (matcher.type) { case "tagName": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.does_not_have_tag") : t("search.has_tag")} </TableCell> <TableCell>{matcher.tagName}</TableCell> </TableRow> ); case "listName": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.is_not_in_list") : t("search.is_in_list")} </TableCell> <TableCell>{matcher.listName}</TableCell> </TableRow> ); case "dateAfter": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.not_created_on_or_after") : t("search.created_on_or_after")} </TableCell> <TableCell>{matcher.dateAfter.toDateString()}</TableCell> </TableRow> ); case "dateBefore": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.not_created_on_or_before") : t("search.created_on_or_before")} </TableCell> <TableCell>{matcher.dateBefore.toDateString()}</TableCell> </TableRow> ); case "age": return ( <TableRow> <TableCell> {matcher.relativeDate.direction === "newer" ? t("search.created_within") : t("search.created_earlier_than")} </TableCell> <TableCell> {matcher.relativeDate.amount.toString() + (matcher.relativeDate.direction === "newer" ? { day: t("search.day_s"), week: t("search.week_s"), month: t("search.month_s"), year: t("search.year_s"), }[matcher.relativeDate.unit] : { day: t("search.day_s_ago"), week: t("search.week_s_ago"), month: t("search.month_s_ago"), year: t("search.year_s_ago"), }[matcher.relativeDate.unit])} </TableCell> </TableRow> ); case "favourited": return ( <TableRow> <TableCell colSpan={2} className="text-center"> {matcher.favourited ? t("search.is_favorited") : t("search.is_not_favorited")} </TableCell> </TableRow> ); case "archived": return ( <TableRow> <TableCell colSpan={2} className="text-center"> {matcher.archived ? t("search.is_archived") : t("search.is_not_archived")} </TableCell> </TableRow> ); case "tagged": return ( <TableRow> <TableCell colSpan={2} className="text-center"> {matcher.tagged ? t("search.has_any_tag") : t("search.has_no_tags")} </TableCell> </TableRow> ); case "inlist": return ( <TableRow> <TableCell colSpan={2} className="text-center"> {matcher.inList ? t("search.is_in_any_list") : t("search.is_not_in_any_list")} </TableCell> </TableRow> ); case "and": case "or": return ( <TableRow> <TableCell> {matcher.type === "and" ? t("search.and") : t("search.or")} </TableCell> <TableCell> <Table> <TableBody> {matcher.matchers.map((m, i) => ( <MatcherComp key={i} matcher={m} /> ))} </TableBody> </Table> </TableCell> </TableRow> ); case "url": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.url_does_not_contain") : t("search.url_contains")} </TableCell> <TableCell>{matcher.url}</TableCell> </TableRow> ); case "title": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.title_does_not_contain") : t("search.title_contains")} </TableCell> <TableCell>{matcher.title}</TableCell> </TableRow> ); case "rssFeedName": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.is_not_from_feed") : t("search.is_from_feed")} </TableCell> <TableCell>{matcher.feedName}</TableCell> </TableRow> ); case "type": return ( <TableRow> <TableCell> {matcher.inverse ? t("search.type_is_not") : t("search.type_is")} </TableCell> <TableCell> {match(matcher.typeName, { link: t("common.bookmark_types.link"), text: t("common.bookmark_types.text"), asset: t("common.bookmark_types.media"), })} </TableCell> </TableRow> ); default: { const _exhaustiveCheck: never = matcher; return null; } } }; return ( <InfoTooltip className={className}> {header} <Table> <TableBody> {parsedSearchQuery.text && ( <TableRow> <TableCell>{t("search.full_text_search")}</TableCell> <TableCell>{parsedSearchQuery.text}</TableCell> </TableRow> )} {parsedSearchQuery.matcher && ( <MatcherComp matcher={parsedSearchQuery.matcher} /> )} </TableBody> </Table> </InfoTooltip> ); }

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