docusaurus-plugin-mcp-server 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,299 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var react = require('react');
6
+ var browser = require('@gleanwork/mcp-config-schema/browser');
7
+ var useGlobalData = require('@docusaurus/useGlobalData');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ // src/theme/McpInstallButton.tsx
11
+ function createDocsRegistryOptions(config) {
12
+ return {
13
+ // Use the serverName from config for naming
14
+ serverNameBuilder: () => config.serverName
15
+ };
16
+ }
17
+ function createDocsRegistry(config) {
18
+ const options = createDocsRegistryOptions(config);
19
+ return {
20
+ registry: new browser.MCPConfigRegistry(options),
21
+ config
22
+ };
23
+ }
24
+ function useMcpRegistry() {
25
+ let pluginData;
26
+ try {
27
+ pluginData = useGlobalData.usePluginData("docusaurus-plugin-mcp-server");
28
+ } catch {
29
+ return void 0;
30
+ }
31
+ const result = react.useMemo(() => {
32
+ if (!pluginData?.serverUrl || !pluginData?.serverName) {
33
+ return void 0;
34
+ }
35
+ const config = {
36
+ serverUrl: pluginData.serverUrl,
37
+ serverName: pluginData.serverName
38
+ };
39
+ return createDocsRegistry(config);
40
+ }, [pluginData?.serverUrl, pluginData?.serverName]);
41
+ return result;
42
+ }
43
+ function McpInstallButton({
44
+ serverUrl: serverUrlProp,
45
+ serverName: serverNameProp,
46
+ label = "Install MCP",
47
+ className = "",
48
+ clients: clientsProp
49
+ }) {
50
+ const [isOpen, setIsOpen] = react.useState(false);
51
+ const [copiedClient, setCopiedClient] = react.useState(null);
52
+ const dropdownRef = react.useRef(null);
53
+ const pluginMcp = useMcpRegistry();
54
+ const { registry, config } = react.useMemo(() => {
55
+ if (serverUrlProp && serverNameProp) {
56
+ return createDocsRegistry({
57
+ serverUrl: serverUrlProp,
58
+ serverName: serverNameProp
59
+ });
60
+ }
61
+ if (pluginMcp) {
62
+ return pluginMcp;
63
+ }
64
+ return {
65
+ registry: new browser.MCPConfigRegistry(),
66
+ config: { serverUrl: "", serverName: "" }
67
+ };
68
+ }, [serverUrlProp, serverNameProp, pluginMcp]);
69
+ react.useEffect(() => {
70
+ function handleClickOutside(event) {
71
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
72
+ setIsOpen(false);
73
+ }
74
+ }
75
+ document.addEventListener("mousedown", handleClickOutside);
76
+ return () => document.removeEventListener("mousedown", handleClickOutside);
77
+ }, []);
78
+ if (!config.serverUrl || !config.serverName) {
79
+ console.error(
80
+ "[McpInstallButton] Missing serverUrl or serverName. Either pass them as props or configure the docusaurus-plugin-mcp-server plugin."
81
+ );
82
+ return null;
83
+ }
84
+ const clientConfigs = react.useMemo(() => {
85
+ if (clientsProp) {
86
+ return clientsProp.map((id) => registry.getConfig(id)).filter((c) => c !== void 0);
87
+ }
88
+ return registry.getNativeHttpClients();
89
+ }, [registry, clientsProp]);
90
+ const copyToClipboard = react.useCallback(async (text, clientId) => {
91
+ try {
92
+ await navigator.clipboard.writeText(text);
93
+ setCopiedClient(clientId);
94
+ setTimeout(() => setCopiedClient(null), 2e3);
95
+ } catch (err) {
96
+ console.error("Failed to copy:", err);
97
+ }
98
+ }, []);
99
+ const getConfigForClient = react.useCallback(
100
+ (clientId) => {
101
+ const builder = registry.createBuilder(clientId);
102
+ const clientConfig = builder.buildConfiguration({
103
+ transport: "http",
104
+ serverUrl: config.serverUrl,
105
+ serverName: config.serverName
106
+ });
107
+ return JSON.stringify(clientConfig, null, 2);
108
+ },
109
+ [registry, config.serverUrl, config.serverName]
110
+ );
111
+ const getCommandForClient = react.useCallback(
112
+ (clientId) => {
113
+ const builder = registry.createBuilder(clientId);
114
+ const cliStatus = builder.supportsCliInstallation();
115
+ if (!cliStatus.supported) {
116
+ return null;
117
+ }
118
+ return builder.buildCommand({
119
+ transport: "http",
120
+ serverUrl: config.serverUrl,
121
+ serverName: config.serverName
122
+ });
123
+ },
124
+ [registry, config.serverUrl, config.serverName]
125
+ );
126
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: `mcp-install-button ${className}`, style: styles.container, children: [
127
+ /* @__PURE__ */ jsxRuntime.jsxs(
128
+ "button",
129
+ {
130
+ onClick: () => setIsOpen(!isOpen),
131
+ style: styles.button,
132
+ "aria-expanded": isOpen,
133
+ "aria-haspopup": "true",
134
+ children: [
135
+ label,
136
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.caret, children: isOpen ? "\u25B2" : "\u25BC" })
137
+ ]
138
+ }
139
+ ),
140
+ isOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.dropdown, children: [
141
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.dropdownHeader, children: "Choose your AI tool:" }),
142
+ clientConfigs.map((client) => {
143
+ const command = getCommandForClient(client.id);
144
+ const config2 = getConfigForClient(client.id);
145
+ const isCopied = copiedClient === client.id;
146
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.clientSection, children: [
147
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.clientHeader, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.clientName, children: client.displayName }) }),
148
+ command ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.codeBlock, children: [
149
+ /* @__PURE__ */ jsxRuntime.jsx("code", { style: styles.code, children: command }),
150
+ /* @__PURE__ */ jsxRuntime.jsx(
151
+ "button",
152
+ {
153
+ onClick: () => copyToClipboard(command, client.id),
154
+ style: styles.copyButton,
155
+ title: "Copy to clipboard",
156
+ children: isCopied ? "\u2713" : "\u{1F4CB}"
157
+ }
158
+ )
159
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.codeBlock, children: [
160
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { style: styles.pre, children: /* @__PURE__ */ jsxRuntime.jsx("code", { style: styles.code, children: config2 }) }),
161
+ /* @__PURE__ */ jsxRuntime.jsx(
162
+ "button",
163
+ {
164
+ onClick: () => copyToClipboard(config2, client.id),
165
+ style: styles.copyButton,
166
+ title: "Copy to clipboard",
167
+ children: isCopied ? "\u2713" : "\u{1F4CB}"
168
+ }
169
+ )
170
+ ] }),
171
+ client.localConfigNotes && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.notes, children: client.localConfigNotes })
172
+ ] }, client.id);
173
+ }),
174
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.footer, children: /* @__PURE__ */ jsxRuntime.jsx(
175
+ "a",
176
+ {
177
+ href: "https://modelcontextprotocol.io/",
178
+ target: "_blank",
179
+ rel: "noopener noreferrer",
180
+ style: styles.learnMore,
181
+ children: "Learn more about MCP \u2192"
182
+ }
183
+ ) })
184
+ ] })
185
+ ] });
186
+ }
187
+ var styles = {
188
+ container: {
189
+ position: "relative",
190
+ display: "inline-block"
191
+ },
192
+ button: {
193
+ display: "inline-flex",
194
+ alignItems: "center",
195
+ gap: "6px",
196
+ padding: "8px 16px",
197
+ fontSize: "14px",
198
+ fontWeight: 500,
199
+ color: "#fff",
200
+ backgroundColor: "#5B4DC7",
201
+ border: "none",
202
+ borderRadius: "6px",
203
+ cursor: "pointer",
204
+ transition: "background-color 0.2s"
205
+ },
206
+ caret: {
207
+ fontSize: "10px"
208
+ },
209
+ dropdown: {
210
+ position: "absolute",
211
+ top: "100%",
212
+ right: 0,
213
+ marginTop: "8px",
214
+ width: "380px",
215
+ maxHeight: "70vh",
216
+ overflowY: "auto",
217
+ backgroundColor: "#fff",
218
+ borderRadius: "8px",
219
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.15)",
220
+ zIndex: 1e3
221
+ },
222
+ dropdownHeader: {
223
+ padding: "12px 16px",
224
+ fontSize: "13px",
225
+ fontWeight: 600,
226
+ color: "#666",
227
+ borderBottom: "1px solid #eee"
228
+ },
229
+ clientSection: {
230
+ padding: "12px 16px",
231
+ borderBottom: "1px solid #eee"
232
+ },
233
+ clientHeader: {
234
+ display: "flex",
235
+ alignItems: "center",
236
+ marginBottom: "8px"
237
+ },
238
+ clientName: {
239
+ fontSize: "14px",
240
+ fontWeight: 600,
241
+ color: "#333"
242
+ },
243
+ codeBlock: {
244
+ position: "relative",
245
+ backgroundColor: "#f6f8fa",
246
+ borderRadius: "6px",
247
+ padding: "10px 40px 10px 12px"
248
+ },
249
+ pre: {
250
+ margin: 0,
251
+ fontSize: "12px",
252
+ lineHeight: 1.4,
253
+ overflow: "auto",
254
+ maxHeight: "120px"
255
+ },
256
+ code: {
257
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
258
+ fontSize: "12px",
259
+ color: "#24292f",
260
+ whiteSpace: "pre-wrap",
261
+ wordBreak: "break-all"
262
+ },
263
+ copyButton: {
264
+ position: "absolute",
265
+ top: "8px",
266
+ right: "8px",
267
+ padding: "4px 8px",
268
+ fontSize: "14px",
269
+ backgroundColor: "transparent",
270
+ border: "none",
271
+ cursor: "pointer",
272
+ opacity: 0.6,
273
+ transition: "opacity 0.2s"
274
+ },
275
+ notes: {
276
+ marginTop: "8px",
277
+ fontSize: "11px",
278
+ color: "#666",
279
+ fontStyle: "italic"
280
+ },
281
+ footer: {
282
+ padding: "12px 16px",
283
+ textAlign: "center"
284
+ },
285
+ learnMore: {
286
+ fontSize: "12px",
287
+ color: "#5B4DC7",
288
+ textDecoration: "none"
289
+ }
290
+ };
291
+ var McpInstallButton_default = McpInstallButton;
292
+
293
+ exports.McpInstallButton = McpInstallButton;
294
+ exports.createDocsRegistry = createDocsRegistry;
295
+ exports.createDocsRegistryOptions = createDocsRegistryOptions;
296
+ exports.default = McpInstallButton_default;
297
+ exports.useMcpRegistry = useMcpRegistry;
298
+ //# sourceMappingURL=index.js.map
299
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/theme/McpRegistryContext.tsx","../../src/theme/McpInstallButton.tsx"],"names":["MCPConfigRegistry","usePluginData","useMemo","useState","useRef","useEffect","useCallback","jsxs","jsx","config"],"mappings":"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","file":"index.js","sourcesContent":["import { useMemo } from 'react';\nimport { usePluginData } from '@docusaurus/useGlobalData';\nimport { MCPConfigRegistry, type RegistryOptions } from '@gleanwork/mcp-config-schema/browser';\n\n/**\n * Configuration from the plugin\n */\nexport interface McpConfig {\n /** Full URL to the MCP server endpoint */\n serverUrl: string;\n /** Name of the MCP server for configuration */\n serverName: string;\n}\n\n/**\n * Plugin global data shape\n */\ninterface McpPluginGlobalData {\n serverUrl: string;\n serverName: string;\n}\n\n/**\n * Registry options for the docs MCP server.\n * Similar to GLEAN_REGISTRY_OPTIONS in @gleanwork/mcp-config-glean\n */\nexport function createDocsRegistryOptions(config: McpConfig): RegistryOptions {\n return {\n // Use the serverName from config for naming\n serverNameBuilder: () => config.serverName,\n };\n}\n\n/**\n * Creates an MCPConfigRegistry pre-configured with the docs server settings.\n *\n * Similar to createGleanRegistry() from @gleanwork/mcp-config-glean\n *\n * @param config - The server configuration from plugin\n * @returns Object with registry instance and bound config\n */\nexport function createDocsRegistry(config: McpConfig): {\n registry: MCPConfigRegistry;\n config: McpConfig;\n} {\n const options = createDocsRegistryOptions(config);\n return {\n registry: new MCPConfigRegistry(options),\n config,\n };\n}\n\n/**\n * Hook to access the pre-configured MCP registry and config.\n *\n * Reads configuration from plugin globalData and creates a registry\n * with the serverUrl and serverName pre-bound in the config object.\n *\n * @returns { registry, config } or undefined if plugin not configured\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const mcp = useMcpRegistry();\n * if (!mcp) return null;\n *\n * const { registry, config } = mcp;\n * const builder = registry.createBuilder('claude-code');\n * const json = builder.buildConfiguration({\n * transport: 'http',\n * serverUrl: config.serverUrl,\n * serverName: config.serverName,\n * });\n * }\n * ```\n */\nexport function useMcpRegistry(): { registry: MCPConfigRegistry; config: McpConfig } | undefined {\n // Read plugin globalData\n let pluginData: McpPluginGlobalData | undefined;\n try {\n pluginData = usePluginData('docusaurus-plugin-mcp-server') as McpPluginGlobalData | undefined;\n } catch {\n // Plugin not installed\n return undefined;\n }\n\n // Memoize registry creation\n const result = useMemo(() => {\n if (!pluginData?.serverUrl || !pluginData?.serverName) {\n return undefined;\n }\n const config: McpConfig = {\n serverUrl: pluginData.serverUrl,\n serverName: pluginData.serverName,\n };\n return createDocsRegistry(config);\n }, [pluginData?.serverUrl, pluginData?.serverName]);\n\n return result;\n}\n\nexport default useMcpRegistry;\n","import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';\nimport {\n MCPConfigRegistry,\n type ClientId,\n type MCPClientConfig,\n} from '@gleanwork/mcp-config-schema/browser';\nimport { useMcpRegistry, createDocsRegistry, type McpConfig } from './McpRegistryContext.js';\n\n/**\n * Props for the McpInstallButton component\n */\nexport interface McpInstallButtonProps {\n /** Server URL. If not provided, uses plugin configuration. */\n serverUrl?: string;\n /** Server name. If not provided, uses plugin configuration. */\n serverName?: string;\n /** Button label (default: \"Install MCP\") */\n label?: string;\n /** Optional className for styling */\n className?: string;\n /** Clients to show. Defaults to all HTTP-capable clients from registry. */\n clients?: ClientId[];\n}\n\n/**\n * A dropdown button component for installing MCP servers in various AI tools.\n *\n * @example\n * ```tsx\n * <McpInstallButton\n * serverUrl=\"https://docs.example.com/mcp\"\n * serverName=\"my-docs\"\n * />\n * ```\n */\nexport function McpInstallButton({\n serverUrl: serverUrlProp,\n serverName: serverNameProp,\n label = 'Install MCP',\n className = '',\n clients: clientsProp,\n}: McpInstallButtonProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [copiedClient, setCopiedClient] = useState<string | null>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // Get pre-configured registry from plugin\n const pluginMcp = useMcpRegistry();\n\n // Use props if provided, otherwise fall back to plugin config\n const { registry, config } = useMemo(() => {\n // If explicit props provided, create a new registry with those values\n if (serverUrlProp && serverNameProp) {\n return createDocsRegistry({\n serverUrl: serverUrlProp,\n serverName: serverNameProp,\n });\n }\n // Otherwise use plugin-provided registry\n if (pluginMcp) {\n return pluginMcp;\n }\n // Fallback: create registry without bound config (will fail validation below)\n return {\n registry: new MCPConfigRegistry(),\n config: { serverUrl: '', serverName: '' } as McpConfig,\n };\n }, [serverUrlProp, serverNameProp, pluginMcp]);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Validate configuration\n if (!config.serverUrl || !config.serverName) {\n console.error(\n '[McpInstallButton] Missing serverUrl or serverName. ' +\n 'Either pass them as props or configure the docusaurus-plugin-mcp-server plugin.'\n );\n return null;\n }\n\n // Get clients to display - dynamic from registry\n const clientConfigs = useMemo(() => {\n if (clientsProp) {\n return clientsProp\n .map((id) => registry.getConfig(id))\n .filter((c): c is MCPClientConfig => c !== undefined);\n }\n // Get all HTTP-capable clients dynamically\n return registry.getNativeHttpClients();\n }, [registry, clientsProp]);\n\n const copyToClipboard = useCallback(async (text: string, clientId: string) => {\n try {\n await navigator.clipboard.writeText(text);\n setCopiedClient(clientId);\n setTimeout(() => setCopiedClient(null), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }, []);\n\n const getConfigForClient = useCallback(\n (clientId: ClientId): string => {\n const builder = registry.createBuilder(clientId);\n const clientConfig = builder.buildConfiguration({\n transport: 'http',\n serverUrl: config.serverUrl,\n serverName: config.serverName,\n });\n return JSON.stringify(clientConfig, null, 2);\n },\n [registry, config.serverUrl, config.serverName]\n );\n\n const getCommandForClient = useCallback(\n (clientId: ClientId): string | null => {\n const builder = registry.createBuilder(clientId);\n const cliStatus = builder.supportsCliInstallation();\n if (!cliStatus.supported) {\n return null;\n }\n return builder.buildCommand({\n transport: 'http',\n serverUrl: config.serverUrl,\n serverName: config.serverName,\n });\n },\n [registry, config.serverUrl, config.serverName]\n );\n\n return (\n <div ref={dropdownRef} className={`mcp-install-button ${className}`} style={styles.container}>\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={styles.button}\n aria-expanded={isOpen}\n aria-haspopup=\"true\"\n >\n {label}\n <span style={styles.caret}>{isOpen ? '▲' : '▼'}</span>\n </button>\n\n {isOpen && (\n <div style={styles.dropdown}>\n <div style={styles.dropdownHeader}>Choose your AI tool:</div>\n\n {clientConfigs.map((client) => {\n const command = getCommandForClient(client.id);\n const config = getConfigForClient(client.id);\n const isCopied = copiedClient === client.id;\n\n return (\n <div key={client.id} style={styles.clientSection}>\n <div style={styles.clientHeader}>\n <span style={styles.clientName}>{client.displayName}</span>\n </div>\n\n {command ? (\n <div style={styles.codeBlock}>\n <code style={styles.code}>{command}</code>\n <button\n onClick={() => copyToClipboard(command, client.id)}\n style={styles.copyButton}\n title=\"Copy to clipboard\"\n >\n {isCopied ? '✓' : '📋'}\n </button>\n </div>\n ) : (\n <div style={styles.codeBlock}>\n <pre style={styles.pre}>\n <code style={styles.code}>{config}</code>\n </pre>\n <button\n onClick={() => copyToClipboard(config, client.id)}\n style={styles.copyButton}\n title=\"Copy to clipboard\"\n >\n {isCopied ? '✓' : '📋'}\n </button>\n </div>\n )}\n\n {client.localConfigNotes && (\n <div style={styles.notes}>{client.localConfigNotes}</div>\n )}\n </div>\n );\n })}\n\n <div style={styles.footer}>\n <a\n href=\"https://modelcontextprotocol.io/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={styles.learnMore}\n >\n Learn more about MCP →\n </a>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n position: 'relative',\n display: 'inline-block',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '6px',\n padding: '8px 16px',\n fontSize: '14px',\n fontWeight: 500,\n color: '#fff',\n backgroundColor: '#5B4DC7',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'background-color 0.2s',\n },\n caret: {\n fontSize: '10px',\n },\n dropdown: {\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: '8px',\n width: '380px',\n maxHeight: '70vh',\n overflowY: 'auto',\n backgroundColor: '#fff',\n borderRadius: '8px',\n boxShadow: '0 4px 20px rgba(0, 0, 0, 0.15)',\n zIndex: 1000,\n },\n dropdownHeader: {\n padding: '12px 16px',\n fontSize: '13px',\n fontWeight: 600,\n color: '#666',\n borderBottom: '1px solid #eee',\n },\n clientSection: {\n padding: '12px 16px',\n borderBottom: '1px solid #eee',\n },\n clientHeader: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: '8px',\n },\n clientName: {\n fontSize: '14px',\n fontWeight: 600,\n color: '#333',\n },\n codeBlock: {\n position: 'relative',\n backgroundColor: '#f6f8fa',\n borderRadius: '6px',\n padding: '10px 40px 10px 12px',\n },\n pre: {\n margin: 0,\n fontSize: '12px',\n lineHeight: 1.4,\n overflow: 'auto',\n maxHeight: '120px',\n },\n code: {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n fontSize: '12px',\n color: '#24292f',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n },\n copyButton: {\n position: 'absolute',\n top: '8px',\n right: '8px',\n padding: '4px 8px',\n fontSize: '14px',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n opacity: 0.6,\n transition: 'opacity 0.2s',\n },\n notes: {\n marginTop: '8px',\n fontSize: '11px',\n color: '#666',\n fontStyle: 'italic',\n },\n footer: {\n padding: '12px 16px',\n textAlign: 'center',\n },\n learnMore: {\n fontSize: '12px',\n color: '#5B4DC7',\n textDecoration: 'none',\n },\n};\n\nexport default McpInstallButton;\n"]}
@@ -0,0 +1,291 @@
1
+ import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
+ import { MCPConfigRegistry } from '@gleanwork/mcp-config-schema/browser';
3
+ import { usePluginData } from '@docusaurus/useGlobalData';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/theme/McpInstallButton.tsx
7
+ function createDocsRegistryOptions(config) {
8
+ return {
9
+ // Use the serverName from config for naming
10
+ serverNameBuilder: () => config.serverName
11
+ };
12
+ }
13
+ function createDocsRegistry(config) {
14
+ const options = createDocsRegistryOptions(config);
15
+ return {
16
+ registry: new MCPConfigRegistry(options),
17
+ config
18
+ };
19
+ }
20
+ function useMcpRegistry() {
21
+ let pluginData;
22
+ try {
23
+ pluginData = usePluginData("docusaurus-plugin-mcp-server");
24
+ } catch {
25
+ return void 0;
26
+ }
27
+ const result = useMemo(() => {
28
+ if (!pluginData?.serverUrl || !pluginData?.serverName) {
29
+ return void 0;
30
+ }
31
+ const config = {
32
+ serverUrl: pluginData.serverUrl,
33
+ serverName: pluginData.serverName
34
+ };
35
+ return createDocsRegistry(config);
36
+ }, [pluginData?.serverUrl, pluginData?.serverName]);
37
+ return result;
38
+ }
39
+ function McpInstallButton({
40
+ serverUrl: serverUrlProp,
41
+ serverName: serverNameProp,
42
+ label = "Install MCP",
43
+ className = "",
44
+ clients: clientsProp
45
+ }) {
46
+ const [isOpen, setIsOpen] = useState(false);
47
+ const [copiedClient, setCopiedClient] = useState(null);
48
+ const dropdownRef = useRef(null);
49
+ const pluginMcp = useMcpRegistry();
50
+ const { registry, config } = useMemo(() => {
51
+ if (serverUrlProp && serverNameProp) {
52
+ return createDocsRegistry({
53
+ serverUrl: serverUrlProp,
54
+ serverName: serverNameProp
55
+ });
56
+ }
57
+ if (pluginMcp) {
58
+ return pluginMcp;
59
+ }
60
+ return {
61
+ registry: new MCPConfigRegistry(),
62
+ config: { serverUrl: "", serverName: "" }
63
+ };
64
+ }, [serverUrlProp, serverNameProp, pluginMcp]);
65
+ useEffect(() => {
66
+ function handleClickOutside(event) {
67
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
68
+ setIsOpen(false);
69
+ }
70
+ }
71
+ document.addEventListener("mousedown", handleClickOutside);
72
+ return () => document.removeEventListener("mousedown", handleClickOutside);
73
+ }, []);
74
+ if (!config.serverUrl || !config.serverName) {
75
+ console.error(
76
+ "[McpInstallButton] Missing serverUrl or serverName. Either pass them as props or configure the docusaurus-plugin-mcp-server plugin."
77
+ );
78
+ return null;
79
+ }
80
+ const clientConfigs = useMemo(() => {
81
+ if (clientsProp) {
82
+ return clientsProp.map((id) => registry.getConfig(id)).filter((c) => c !== void 0);
83
+ }
84
+ return registry.getNativeHttpClients();
85
+ }, [registry, clientsProp]);
86
+ const copyToClipboard = useCallback(async (text, clientId) => {
87
+ try {
88
+ await navigator.clipboard.writeText(text);
89
+ setCopiedClient(clientId);
90
+ setTimeout(() => setCopiedClient(null), 2e3);
91
+ } catch (err) {
92
+ console.error("Failed to copy:", err);
93
+ }
94
+ }, []);
95
+ const getConfigForClient = useCallback(
96
+ (clientId) => {
97
+ const builder = registry.createBuilder(clientId);
98
+ const clientConfig = builder.buildConfiguration({
99
+ transport: "http",
100
+ serverUrl: config.serverUrl,
101
+ serverName: config.serverName
102
+ });
103
+ return JSON.stringify(clientConfig, null, 2);
104
+ },
105
+ [registry, config.serverUrl, config.serverName]
106
+ );
107
+ const getCommandForClient = useCallback(
108
+ (clientId) => {
109
+ const builder = registry.createBuilder(clientId);
110
+ const cliStatus = builder.supportsCliInstallation();
111
+ if (!cliStatus.supported) {
112
+ return null;
113
+ }
114
+ return builder.buildCommand({
115
+ transport: "http",
116
+ serverUrl: config.serverUrl,
117
+ serverName: config.serverName
118
+ });
119
+ },
120
+ [registry, config.serverUrl, config.serverName]
121
+ );
122
+ return /* @__PURE__ */ jsxs("div", { ref: dropdownRef, className: `mcp-install-button ${className}`, style: styles.container, children: [
123
+ /* @__PURE__ */ jsxs(
124
+ "button",
125
+ {
126
+ onClick: () => setIsOpen(!isOpen),
127
+ style: styles.button,
128
+ "aria-expanded": isOpen,
129
+ "aria-haspopup": "true",
130
+ children: [
131
+ label,
132
+ /* @__PURE__ */ jsx("span", { style: styles.caret, children: isOpen ? "\u25B2" : "\u25BC" })
133
+ ]
134
+ }
135
+ ),
136
+ isOpen && /* @__PURE__ */ jsxs("div", { style: styles.dropdown, children: [
137
+ /* @__PURE__ */ jsx("div", { style: styles.dropdownHeader, children: "Choose your AI tool:" }),
138
+ clientConfigs.map((client) => {
139
+ const command = getCommandForClient(client.id);
140
+ const config2 = getConfigForClient(client.id);
141
+ const isCopied = copiedClient === client.id;
142
+ return /* @__PURE__ */ jsxs("div", { style: styles.clientSection, children: [
143
+ /* @__PURE__ */ jsx("div", { style: styles.clientHeader, children: /* @__PURE__ */ jsx("span", { style: styles.clientName, children: client.displayName }) }),
144
+ command ? /* @__PURE__ */ jsxs("div", { style: styles.codeBlock, children: [
145
+ /* @__PURE__ */ jsx("code", { style: styles.code, children: command }),
146
+ /* @__PURE__ */ jsx(
147
+ "button",
148
+ {
149
+ onClick: () => copyToClipboard(command, client.id),
150
+ style: styles.copyButton,
151
+ title: "Copy to clipboard",
152
+ children: isCopied ? "\u2713" : "\u{1F4CB}"
153
+ }
154
+ )
155
+ ] }) : /* @__PURE__ */ jsxs("div", { style: styles.codeBlock, children: [
156
+ /* @__PURE__ */ jsx("pre", { style: styles.pre, children: /* @__PURE__ */ jsx("code", { style: styles.code, children: config2 }) }),
157
+ /* @__PURE__ */ jsx(
158
+ "button",
159
+ {
160
+ onClick: () => copyToClipboard(config2, client.id),
161
+ style: styles.copyButton,
162
+ title: "Copy to clipboard",
163
+ children: isCopied ? "\u2713" : "\u{1F4CB}"
164
+ }
165
+ )
166
+ ] }),
167
+ client.localConfigNotes && /* @__PURE__ */ jsx("div", { style: styles.notes, children: client.localConfigNotes })
168
+ ] }, client.id);
169
+ }),
170
+ /* @__PURE__ */ jsx("div", { style: styles.footer, children: /* @__PURE__ */ jsx(
171
+ "a",
172
+ {
173
+ href: "https://modelcontextprotocol.io/",
174
+ target: "_blank",
175
+ rel: "noopener noreferrer",
176
+ style: styles.learnMore,
177
+ children: "Learn more about MCP \u2192"
178
+ }
179
+ ) })
180
+ ] })
181
+ ] });
182
+ }
183
+ var styles = {
184
+ container: {
185
+ position: "relative",
186
+ display: "inline-block"
187
+ },
188
+ button: {
189
+ display: "inline-flex",
190
+ alignItems: "center",
191
+ gap: "6px",
192
+ padding: "8px 16px",
193
+ fontSize: "14px",
194
+ fontWeight: 500,
195
+ color: "#fff",
196
+ backgroundColor: "#5B4DC7",
197
+ border: "none",
198
+ borderRadius: "6px",
199
+ cursor: "pointer",
200
+ transition: "background-color 0.2s"
201
+ },
202
+ caret: {
203
+ fontSize: "10px"
204
+ },
205
+ dropdown: {
206
+ position: "absolute",
207
+ top: "100%",
208
+ right: 0,
209
+ marginTop: "8px",
210
+ width: "380px",
211
+ maxHeight: "70vh",
212
+ overflowY: "auto",
213
+ backgroundColor: "#fff",
214
+ borderRadius: "8px",
215
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.15)",
216
+ zIndex: 1e3
217
+ },
218
+ dropdownHeader: {
219
+ padding: "12px 16px",
220
+ fontSize: "13px",
221
+ fontWeight: 600,
222
+ color: "#666",
223
+ borderBottom: "1px solid #eee"
224
+ },
225
+ clientSection: {
226
+ padding: "12px 16px",
227
+ borderBottom: "1px solid #eee"
228
+ },
229
+ clientHeader: {
230
+ display: "flex",
231
+ alignItems: "center",
232
+ marginBottom: "8px"
233
+ },
234
+ clientName: {
235
+ fontSize: "14px",
236
+ fontWeight: 600,
237
+ color: "#333"
238
+ },
239
+ codeBlock: {
240
+ position: "relative",
241
+ backgroundColor: "#f6f8fa",
242
+ borderRadius: "6px",
243
+ padding: "10px 40px 10px 12px"
244
+ },
245
+ pre: {
246
+ margin: 0,
247
+ fontSize: "12px",
248
+ lineHeight: 1.4,
249
+ overflow: "auto",
250
+ maxHeight: "120px"
251
+ },
252
+ code: {
253
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
254
+ fontSize: "12px",
255
+ color: "#24292f",
256
+ whiteSpace: "pre-wrap",
257
+ wordBreak: "break-all"
258
+ },
259
+ copyButton: {
260
+ position: "absolute",
261
+ top: "8px",
262
+ right: "8px",
263
+ padding: "4px 8px",
264
+ fontSize: "14px",
265
+ backgroundColor: "transparent",
266
+ border: "none",
267
+ cursor: "pointer",
268
+ opacity: 0.6,
269
+ transition: "opacity 0.2s"
270
+ },
271
+ notes: {
272
+ marginTop: "8px",
273
+ fontSize: "11px",
274
+ color: "#666",
275
+ fontStyle: "italic"
276
+ },
277
+ footer: {
278
+ padding: "12px 16px",
279
+ textAlign: "center"
280
+ },
281
+ learnMore: {
282
+ fontSize: "12px",
283
+ color: "#5B4DC7",
284
+ textDecoration: "none"
285
+ }
286
+ };
287
+ var McpInstallButton_default = McpInstallButton;
288
+
289
+ export { McpInstallButton, createDocsRegistry, createDocsRegistryOptions, McpInstallButton_default as default, useMcpRegistry };
290
+ //# sourceMappingURL=index.mjs.map
291
+ //# sourceMappingURL=index.mjs.map