Skip to main content
Glama

Karakeep MCP server

by karakeep-app
background.ts3.52 kB
import { BookmarkTypes, ZNewBookmarkRequest, } from "@karakeep/shared/types/bookmarks.ts"; import { getPluginSettings, Settings, subscribeToSettingsChanges, } from "../utils/settings.ts"; import { NEW_BOOKMARK_REQUEST_KEY_NAME } from "./protocol.ts"; const OPEN_KARAKEEP_ID = "open-karakeep"; const ADD_LINK_TO_KARAKEEP_ID = "add-link"; function checkSettingsState(settings: Settings) { if (settings?.address) { registerContextMenus(); } else { removeContextMenus(); } } function removeContextMenus() { chrome.contextMenus.remove(OPEN_KARAKEEP_ID); chrome.contextMenus.remove(ADD_LINK_TO_KARAKEEP_ID); } /** * Registers * * a context menu button to open a tab with the currently configured karakeep instance * * a context menu button to add a link to karakeep without loading the page */ function registerContextMenus() { chrome.contextMenus.create({ id: OPEN_KARAKEEP_ID, title: "Open Karakeep", contexts: ["action"], }); chrome.contextMenus.create({ id: ADD_LINK_TO_KARAKEEP_ID, title: "Add to Karakeep", contexts: ["link", "page", "selection", "image"], }); } /** * Reads the current settings and opens a new tab with karakeep * @param info the information about the click in the context menu */ async function handleContextMenuClick(info: chrome.contextMenus.OnClickData) { const { menuItemId, selectionText, srcUrl, linkUrl, pageUrl } = info; if (menuItemId === OPEN_KARAKEEP_ID) { getPluginSettings().then((settings: Settings) => { chrome.tabs.create({ url: settings.address, active: true }); }); } else if (menuItemId === ADD_LINK_TO_KARAKEEP_ID) { addLinkToKarakeep({ selectionText, srcUrl, linkUrl, pageUrl }); // NOTE: Firefox only allows opening context menus if it's triggered by a user action. // awaiting on any promise before calling this function will lose the "user action" context. await chrome.action.openPopup(); } } function addLinkToKarakeep({ selectionText, srcUrl, linkUrl, pageUrl, }: { selectionText?: string; srcUrl?: string; linkUrl?: string; pageUrl?: string; }) { let newBookmark: ZNewBookmarkRequest | null = null; if (selectionText) { newBookmark = { type: BookmarkTypes.TEXT, text: selectionText, sourceUrl: pageUrl, }; } else if (srcUrl ?? linkUrl ?? pageUrl) { newBookmark = { type: BookmarkTypes.LINK, url: srcUrl ?? linkUrl ?? pageUrl ?? "", }; } if (newBookmark) { chrome.storage.session.set({ [NEW_BOOKMARK_REQUEST_KEY_NAME]: newBookmark, }); } } getPluginSettings().then((settings: Settings) => { checkSettingsState(settings); }); subscribeToSettingsChanges((settings) => { checkSettingsState(settings); }); // eslint-disable-next-line @typescript-eslint/no-misused-promises -- Manifest V3 allows async functions for all callbacks chrome.contextMenus.onClicked.addListener(handleContextMenuClick); function handleCommand(command: string, tab: chrome.tabs.Tab) { if (command === ADD_LINK_TO_KARAKEEP_ID) { addLinkToKarakeep({ selectionText: undefined, srcUrl: undefined, linkUrl: undefined, pageUrl: tab?.url, }); // now try to open the popup chrome.action.openPopup(); } else { console.warn(`Received unknown command: ${command}`); } } chrome.commands.onCommand.addListener(handleCommand);

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