Skip to main content
Glama

Karakeep MCP server

by karakeep-app
markdown-editor.tsx4.22 kB
import { memo, useMemo, useState } from "react"; import ToolbarPlugin from "@/components/ui/markdown/plugins/toolbar-plugin"; import { MarkdownEditorTheme } from "@/components/ui/markdown/theme"; import { CodeHighlightNode, CodeNode, registerCodeHighlighting, } from "@lexical/code"; import { LinkNode } from "@lexical/link"; import { ListItemNode, ListNode } from "@lexical/list"; import { $convertFromMarkdownString, $convertToMarkdownString, TRANSFORMERS, } from "@lexical/markdown"; import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin"; import { InitialConfigType, LexicalComposer, } from "@lexical/react/LexicalComposer"; import { ContentEditable } from "@lexical/react/LexicalContentEditable"; import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary"; import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin"; import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode"; import { ListPlugin } from "@lexical/react/LexicalListPlugin"; import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin"; import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin"; import { PlainTextPlugin } from "@lexical/react/LexicalPlainTextPlugin"; import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"; import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin"; import { HeadingNode, QuoteNode } from "@lexical/rich-text"; import { $getRoot, EditorState, LexicalEditor } from "lexical"; function onError(error: Error) { console.error(error); } const EDITOR_NODES = [ HeadingNode, ListNode, ListItemNode, QuoteNode, LinkNode, CodeNode, HorizontalRuleNode, CodeHighlightNode, ]; interface MarkdownEditorProps { children: string; onSave?: (markdown: string) => void; isSaving?: boolean; } const MarkdownEditor = memo( ({ children: initialMarkdown, onSave, isSaving }: MarkdownEditorProps) => { const [isRawMarkdownMode, setIsRawMarkdownMode] = useState(false); const [rawMarkdown, setRawMarkdown] = useState(initialMarkdown); const initialConfig: InitialConfigType = useMemo( () => ({ namespace: "editor", onError, theme: MarkdownEditorTheme, nodes: EDITOR_NODES, editorState: (editor: LexicalEditor) => { registerCodeHighlighting(editor); $convertFromMarkdownString(initialMarkdown, TRANSFORMERS); }, }), [initialMarkdown], ); const handleOnChange = (editorState: EditorState) => { editorState.read(() => { let markdownString; if (isRawMarkdownMode) { markdownString = $getRoot()?.getFirstChild()?.getTextContent() ?? ""; } else { markdownString = $convertToMarkdownString(TRANSFORMERS); } setRawMarkdown(markdownString); }); }; return ( <LexicalComposer initialConfig={initialConfig}> <div className="flex h-full flex-col justify-stretch"> <ToolbarPlugin isRawMarkdownMode={isRawMarkdownMode} setIsRawMarkdownMode={setIsRawMarkdownMode} onSave={onSave && (() => onSave(rawMarkdown))} isSaving={!!isSaving} /> {isRawMarkdownMode ? ( <PlainTextPlugin contentEditable={ <ContentEditable className="h-full w-full min-w-full overflow-auto p-2" /> } ErrorBoundary={LexicalErrorBoundary} /> ) : ( <RichTextPlugin contentEditable={ <ContentEditable className="prose h-full w-full min-w-full overflow-auto p-2 dark:prose-invert prose-p:m-0" /> } ErrorBoundary={LexicalErrorBoundary} /> )} </div> <HistoryPlugin /> <AutoFocusPlugin /> <TabIndentationPlugin /> <MarkdownShortcutPlugin transformers={TRANSFORMERS} /> <OnChangePlugin onChange={handleOnChange} /> <ListPlugin /> </LexicalComposer> ); }, ); // needed for linter because of memo MarkdownEditor.displayName = "MarkdownEditor"; export default MarkdownEditor;

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