diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c816185 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.claude \ No newline at end of file diff --git a/package.json b/package.json index df6a558..9720505 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docusaurus-plugin-copy-page-button", - "version": "0.4.2", + "version": "0.5.0", "description": "Docusaurus plugin that adds a copy page button to extract documentation content as markdown for AI tools like ChatGPT, Claude, and Gemini", "main": "src/index.js", "keywords": [ diff --git a/src/CopyPageButton.js b/src/CopyPageButton.js index 3b1ac05..3498c78 100644 --- a/src/CopyPageButton.js +++ b/src/CopyPageButton.js @@ -49,7 +49,8 @@ const separatePositioningStyles = (styleObject = {}) => { export default function CopyPageButton({ customStyles = {}, - enabledActions = ['copy', 'view', 'chatgpt', 'claude', 'gemini'] + enabledActions = ['copy', 'view', 'chatgpt', 'claude', 'perplexity', 'gemini', 'mcp-copy', 'mcp-cursor', 'mcp-vscode'], + mcpServer = null }) { const [isOpen, setIsOpen] = useState(false); const [pageContent, setPageContent] = useState(""); @@ -423,6 +424,34 @@ Please provide a clear summary and help me understand the key concepts covered i } }; + const buildCursorMcpUrl = () => { + if (!mcpServer) return null; + const config = JSON.stringify({ name: mcpServer.name, url: mcpServer.url }); + const encodedConfig = btoa(config); + return `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(mcpServer.name)}&config=${encodeURIComponent(encodedConfig)}`; + }; + + const buildVscodeMcpUrl = () => { + if (!mcpServer) return null; + const config = JSON.stringify({ name: mcpServer.name, url: mcpServer.url }); + return `vscode:mcp/install?${encodeURIComponent(config)}`; + }; + + const copyMcpConfig = async () => { + if (!mcpServer) return; + await copyToClipboard(mcpServer.url); + }; + + const openInCursor = () => { + const url = buildCursorMcpUrl(); + if (url) window.open(url, "_self"); + }; + + const openInVscode = () => { + const url = buildVscodeMcpUrl(); + if (url) window.open(url, "_self"); + }; + const allDropdownItems = [ { id: "copy", @@ -503,6 +532,23 @@ Please provide a clear summary and help me understand the key concepts covered i ), action: () => openInAI("https://claude.ai/new"), }, + { + id: "perplexity", + title: "Open in Perplexity", + description: "Ask questions about this page", + icon: ( + + + + ), + action: () => openInAI("https://www.perplexity.ai/search", "q"), + }, { id: "gemini", title: "Open in Gemini", @@ -523,6 +569,67 @@ Please provide a clear summary and help me understand the key concepts covered i ), action: () => openInAI("https://gemini.google.com/guided-learning", "query"), }, + ...(mcpServer ? [ + { + id: "mcp-copy", + title: "Copy MCP Server", + description: "Copy MCP Server URL to clipboard", + icon: ( + + + + ), + action: copyMcpConfig, + }, + { + id: "mcp-cursor", + title: "Connect to Cursor", + description: "Install MCP Server on Cursor", + icon: ( + + + + + + ), + action: openInCursor, + }, + { + id: "mcp-vscode", + title: "Connect to VS Code", + description: "Install MCP Server on VS Code", + icon: ( + + + + ), + action: openInVscode, + }, + ] : []), ]; // Filter dropdown items based on enabled actions diff --git a/src/client.js b/src/client.js index ae51add..506a343 100644 --- a/src/client.js +++ b/src/client.js @@ -80,7 +80,8 @@ if (ExecutionEnvironment.canUseDOM) { const renderOptions = getPluginOptions(); root.render(React.createElement(CopyPageButton, { customStyles: renderOptions.customStyles, - enabledActions: renderOptions.enabledActions + enabledActions: renderOptions.enabledActions, + mcpServer: renderOptions.mcpServer })); }; @@ -141,7 +142,8 @@ if (ExecutionEnvironment.canUseDOM) { const renderOptions = getPluginOptions(); root.render(React.createElement(CopyPageButton, { customStyles: renderOptions.customStyles, - enabledActions: renderOptions.enabledActions + enabledActions: renderOptions.enabledActions, + mcpServer: renderOptions.mcpServer })); }; @@ -218,7 +220,8 @@ if (ExecutionEnvironment.canUseDOM) { const renderOptions = getPluginOptions(); root.render(React.createElement(CopyPageButton, { customStyles: renderOptions.customStyles, - enabledActions: renderOptions.enabledActions + enabledActions: renderOptions.enabledActions, + mcpServer: renderOptions.mcpServer })); // Reset injection attempts on successful injection diff --git a/src/index.js b/src/index.js index 0a03904..fc01b57 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,8 @@ const path = require("path"); module.exports = function copyPageButtonPlugin(context, options = {}) { const { customStyles = {}, - enabledActions = ['copy', 'view', 'chatgpt', 'claude', 'gemini'], + enabledActions = ['copy', 'view', 'chatgpt', 'claude', 'perplexity', 'gemini', 'mcp-copy', 'mcp-cursor', 'mcp-vscode'], + mcpServer = null, ...otherOptions } = options; @@ -23,6 +24,7 @@ module.exports = function copyPageButtonPlugin(context, options = {}) { window.__COPY_PAGE_BUTTON_OPTIONS__ = ${JSON.stringify({ customStyles, enabledActions, + mcpServer, ...otherOptions })}; `