docusaurus-plugin-mcp-server 0.5.0 → 0.6.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.
@@ -9,7 +9,7 @@ interface McpInstallButtonProps {
9
9
  serverUrl?: string;
10
10
  /** Server name. If not provided, uses plugin configuration. */
11
11
  serverName?: string;
12
- /** Button label (default: "Install MCP") */
12
+ /** Button label (default: "Install docs MCP") */
13
13
  label?: string;
14
14
  /** Optional className for styling */
15
15
  className?: string;
@@ -18,6 +18,7 @@ interface McpInstallButtonProps {
18
18
  }
19
19
  /**
20
20
  * A dropdown button component for installing MCP servers in various AI tools.
21
+ * Uses Docusaurus/Infima CSS classes for consistent theming.
21
22
  *
22
23
  * @example
23
24
  * ```tsx
@@ -9,7 +9,7 @@ interface McpInstallButtonProps {
9
9
  serverUrl?: string;
10
10
  /** Server name. If not provided, uses plugin configuration. */
11
11
  serverName?: string;
12
- /** Button label (default: "Install MCP") */
12
+ /** Button label (default: "Install docs MCP") */
13
13
  label?: string;
14
14
  /** Optional className for styling */
15
15
  className?: string;
@@ -18,6 +18,7 @@ interface McpInstallButtonProps {
18
18
  }
19
19
  /**
20
20
  * A dropdown button component for installing MCP servers in various AI tools.
21
+ * Uses Docusaurus/Infima CSS classes for consistent theming.
21
22
  *
22
23
  * @example
23
24
  * ```tsx
@@ -4,9 +4,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var react = require('react');
6
6
  var browser = require('@gleanwork/mcp-config-schema/browser');
7
+ var IconCopy = require('@theme/Icon/Copy');
8
+ var IconSuccess = require('@theme/Icon/Success');
7
9
  var useGlobalData = require('@docusaurus/useGlobalData');
8
10
  var jsxRuntime = require('react/jsx-runtime');
9
11
 
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var IconCopy__default = /*#__PURE__*/_interopDefault(IconCopy);
15
+ var IconSuccess__default = /*#__PURE__*/_interopDefault(IconSuccess);
16
+
10
17
  // src/theme/McpInstallButton.tsx
11
18
  function createDocsRegistryOptions(config) {
12
19
  return {
@@ -40,10 +47,107 @@ function useMcpRegistry() {
40
47
  }, [pluginData?.serverUrl, pluginData?.serverName]);
41
48
  return result;
42
49
  }
50
+ function IconMcp({ size = 16 }) {
51
+ return /* @__PURE__ */ jsxRuntime.jsxs(
52
+ "svg",
53
+ {
54
+ viewBox: "0 0 170 195",
55
+ width: size,
56
+ height: size,
57
+ fill: "none",
58
+ xmlns: "http://www.w3.org/2000/svg",
59
+ style: { display: "block" },
60
+ children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx(
62
+ "path",
63
+ {
64
+ d: "M25 97.8528L92.8823 29.9706C102.255 20.598 117.451 20.598 126.823 29.9706C136.196 39.3431 136.196 54.5391 126.823 63.9117L75.5581 115.177",
65
+ stroke: "currentColor",
66
+ strokeWidth: "12",
67
+ strokeLinecap: "round"
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsxRuntime.jsx(
71
+ "path",
72
+ {
73
+ d: "M76.2653 114.47L126.823 63.9117C136.196 54.5391 151.392 54.5391 160.765 63.9117L161.118 64.2652C170.491 73.6378 170.491 88.8338 161.118 98.2063L99.7248 159.6C96.6006 162.724 96.6006 167.789 99.7248 170.913L112.331 183.52",
74
+ stroke: "currentColor",
75
+ strokeWidth: "12",
76
+ strokeLinecap: "round"
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsxRuntime.jsx(
80
+ "path",
81
+ {
82
+ d: "M109.853 46.9411L59.6482 97.1457C50.2757 106.518 50.2757 121.714 59.6482 131.087C69.0208 140.459 84.2168 140.459 93.5894 131.087L143.794 80.8822",
83
+ stroke: "currentColor",
84
+ strokeWidth: "12",
85
+ strokeLinecap: "round"
86
+ }
87
+ )
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ function IconChevron({ isOpen }) {
93
+ return /* @__PURE__ */ jsxRuntime.jsx(
94
+ "svg",
95
+ {
96
+ width: "12",
97
+ height: "12",
98
+ viewBox: "0 0 12 12",
99
+ style: {
100
+ display: "block",
101
+ transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
102
+ transition: "transform var(--ifm-transition-fast)"
103
+ },
104
+ children: /* @__PURE__ */ jsxRuntime.jsx(
105
+ "path",
106
+ {
107
+ d: "M2.5 4.5L6 8L9.5 4.5",
108
+ stroke: "currentColor",
109
+ strokeWidth: "1.5",
110
+ strokeLinecap: "round",
111
+ strokeLinejoin: "round",
112
+ fill: "none"
113
+ }
114
+ )
115
+ }
116
+ );
117
+ }
118
+ function IconExternalLink() {
119
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", style: { display: "block", marginLeft: "4px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
120
+ "path",
121
+ {
122
+ fill: "currentColor",
123
+ d: "M3.5 3C3.22386 3 3 3.22386 3 3.5C3 3.77614 3.22386 4 3.5 4H7.29289L3.14645 8.14645C2.95118 8.34171 2.95118 8.65829 3.14645 8.85355C3.34171 9.04882 3.65829 9.04882 3.85355 8.85355L8 4.70711V8.5C8 8.77614 8.22386 9 8.5 9C8.77614 9 9 8.77614 9 8.5V3.5C9 3.22386 8.77614 3 8.5 3H3.5Z"
124
+ }
125
+ ) });
126
+ }
127
+ function CodeBlock({
128
+ code,
129
+ isMultiline = false,
130
+ isCopied,
131
+ onCopy
132
+ }) {
133
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mcp-code-block", children: [
134
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mcp-code-block__content", children: isMultiline ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mcp-code-block__pre", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) }) : /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) }),
135
+ /* @__PURE__ */ jsxRuntime.jsx(
136
+ "button",
137
+ {
138
+ className: "mcp-code-block__copy",
139
+ onClick: onCopy,
140
+ title: isCopied ? "Copied!" : "Copy to clipboard",
141
+ "aria-label": isCopied ? "Copied" : "Copy to clipboard",
142
+ children: isCopied ? /* @__PURE__ */ jsxRuntime.jsx(IconSuccess__default.default, { className: "mcp-code-block__icon mcp-code-block__icon--success" }) : /* @__PURE__ */ jsxRuntime.jsx(IconCopy__default.default, { className: "mcp-code-block__icon" })
143
+ }
144
+ )
145
+ ] });
146
+ }
43
147
  function McpInstallButton({
44
148
  serverUrl: serverUrlProp,
45
149
  serverName: serverNameProp,
46
- label = "Install MCP",
150
+ label = "Install docs MCP",
47
151
  className = "",
48
152
  clients: clientsProp
49
153
  }) {
@@ -82,10 +186,13 @@ function McpInstallButton({
82
186
  return null;
83
187
  }
84
188
  const clientConfigs = react.useMemo(() => {
189
+ let clients;
85
190
  if (clientsProp) {
86
- return clientsProp.map((id) => registry.getConfig(id)).filter((c) => c !== void 0);
191
+ clients = clientsProp.map((id) => registry.getConfig(id)).filter((c) => c !== void 0);
192
+ } else {
193
+ clients = registry.getNativeHttpClients();
87
194
  }
88
- return registry.getNativeHttpClients();
195
+ return clients.sort((a, b) => a.displayName.localeCompare(b.displayName));
89
196
  }, [registry, clientsProp]);
90
197
  const copyToClipboard = react.useCallback(async (text, clientId) => {
91
198
  try {
@@ -98,196 +205,244 @@ function McpInstallButton({
98
205
  }, []);
99
206
  const getConfigForClient = react.useCallback(
100
207
  (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);
208
+ try {
209
+ const builder = registry.createBuilder(clientId);
210
+ const clientConfig = builder.buildConfiguration({
211
+ transport: "http",
212
+ serverUrl: config.serverUrl,
213
+ serverName: config.serverName
214
+ });
215
+ return JSON.stringify(clientConfig, null, 2);
216
+ } catch {
217
+ return null;
218
+ }
108
219
  },
109
220
  [registry, config.serverUrl, config.serverName]
110
221
  );
111
222
  const getCommandForClient = react.useCallback(
112
223
  (clientId) => {
113
- const builder = registry.createBuilder(clientId);
114
- const cliStatus = builder.supportsCliInstallation();
115
- if (!cliStatus.supported) {
224
+ try {
225
+ const builder = registry.createBuilder(clientId);
226
+ const cliStatus = builder.supportsCliInstallation();
227
+ if (!cliStatus.supported) {
228
+ return null;
229
+ }
230
+ return builder.buildCommand({
231
+ transport: "http",
232
+ serverUrl: config.serverUrl,
233
+ serverName: config.serverName
234
+ });
235
+ } catch {
116
236
  return null;
117
237
  }
118
- return builder.buildCommand({
119
- transport: "http",
120
- serverUrl: config.serverUrl,
121
- serverName: config.serverName
122
- });
123
238
  },
124
239
  [registry, config.serverUrl, config.serverName]
125
240
  );
126
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: `mcp-install-button ${className}`, style: styles.container, children: [
241
+ const dropdownClasses = [
242
+ "dropdown",
243
+ "dropdown--right",
244
+ isOpen ? "dropdown--show" : "",
245
+ "mcp-install-dropdown",
246
+ className
247
+ ].filter(Boolean).join(" ");
248
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: dropdownClasses, children: [
127
249
  /* @__PURE__ */ jsxRuntime.jsxs(
128
250
  "button",
129
251
  {
252
+ className: "button button--primary mcp-install-dropdown__button",
130
253
  onClick: () => setIsOpen(!isOpen),
131
- style: styles.button,
132
254
  "aria-expanded": isOpen,
133
255
  "aria-haspopup": "true",
134
256
  children: [
135
- label,
136
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.caret, children: isOpen ? "\u25B2" : "\u25BC" })
257
+ /* @__PURE__ */ jsxRuntime.jsx(IconMcp, { size: 16 }),
258
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
259
+ /* @__PURE__ */ jsxRuntime.jsx(IconChevron, { isOpen })
137
260
  ]
138
261
  }
139
262
  ),
140
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.dropdown, children: [
141
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.dropdownHeader, children: "Choose your AI tool:" }),
263
+ /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "dropdown__menu mcp-install-dropdown__menu", children: [
264
+ /* @__PURE__ */ jsxRuntime.jsx("li", { className: "mcp-install-dropdown__header", children: "Choose your AI tool:" }),
142
265
  clientConfigs.map((client) => {
143
266
  const command = getCommandForClient(client.id);
144
- const config2 = getConfigForClient(client.id);
267
+ const clientConfig = getConfigForClient(client.id);
145
268
  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
- )
269
+ if (!command && !clientConfig) {
270
+ return null;
271
+ }
272
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "mcp-install-dropdown__item", children: [
273
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mcp-install-dropdown__client-header", children: [
274
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mcp-install-dropdown__client-name", children: client.displayName }),
275
+ command && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "badge badge--success", children: "CLI" })
170
276
  ] }),
171
- client.localConfigNotes && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.notes, children: client.localConfigNotes })
277
+ command ? /* @__PURE__ */ jsxRuntime.jsx(
278
+ CodeBlock,
279
+ {
280
+ code: command,
281
+ isCopied,
282
+ onCopy: () => copyToClipboard(command, client.id)
283
+ }
284
+ ) : clientConfig ? /* @__PURE__ */ jsxRuntime.jsx(
285
+ CodeBlock,
286
+ {
287
+ code: clientConfig,
288
+ isMultiline: true,
289
+ isCopied,
290
+ onCopy: () => copyToClipboard(clientConfig, client.id)
291
+ }
292
+ ) : null,
293
+ client.localConfigNotes && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mcp-install-dropdown__notes", children: client.localConfigNotes })
172
294
  ] }, client.id);
173
295
  }),
174
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.footer, children: /* @__PURE__ */ jsxRuntime.jsx(
296
+ /* @__PURE__ */ jsxRuntime.jsx("li", { className: "mcp-install-dropdown__footer", children: /* @__PURE__ */ jsxRuntime.jsxs(
175
297
  "a",
176
298
  {
177
299
  href: "https://modelcontextprotocol.io/",
178
300
  target: "_blank",
179
301
  rel: "noopener noreferrer",
180
- style: styles.learnMore,
181
- children: "Learn more about MCP \u2192"
302
+ className: "mcp-install-dropdown__learn-more",
303
+ children: [
304
+ "Learn more about MCP",
305
+ /* @__PURE__ */ jsxRuntime.jsx(IconExternalLink, {})
306
+ ]
182
307
  }
183
308
  ) })
184
- ] })
309
+ ] }),
310
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
311
+ .mcp-install-dropdown {
312
+ --mcp-dropdown-width: 520px;
313
+ /* Always use dark code blocks for consistency across themes */
314
+ --mcp-code-bg: #1e1e1e;
315
+ --mcp-code-color: #e5e7eb;
316
+ }
317
+
318
+ .mcp-install-dropdown__button {
319
+ display: inline-flex;
320
+ align-items: center;
321
+ gap: 0.5rem;
322
+ }
323
+
324
+ .mcp-install-dropdown__menu {
325
+ width: var(--mcp-dropdown-width);
326
+ padding: 0;
327
+ top: calc(100% + 0.25rem);
328
+ }
329
+
330
+ .mcp-install-dropdown__header {
331
+ padding: 0.75rem 1rem;
332
+ font-size: var(--ifm-font-size-small);
333
+ font-weight: var(--ifm-font-weight-semibold);
334
+ color: var(--ifm-color-secondary-darkest);
335
+ background-color: var(--ifm-background-color);
336
+ border-bottom: 1px solid var(--ifm-toc-border-color);
337
+ }
338
+
339
+ .mcp-install-dropdown__item {
340
+ padding: 0.875rem 1rem;
341
+ border-bottom: 1px solid var(--ifm-toc-border-color);
342
+ }
343
+
344
+ .mcp-install-dropdown__client-header {
345
+ display: flex;
346
+ align-items: center;
347
+ gap: 0.5rem;
348
+ margin-bottom: 0.625rem;
349
+ }
350
+
351
+ .mcp-install-dropdown__client-name {
352
+ font-weight: var(--ifm-font-weight-semibold);
353
+ color: var(--ifm-font-color-base);
354
+ }
355
+
356
+ .mcp-install-dropdown__notes {
357
+ margin: 0.5rem 0 0;
358
+ font-size: var(--ifm-font-size-small);
359
+ color: var(--ifm-color-secondary-darkest);
360
+ line-height: 1.4;
361
+ }
362
+
363
+ .mcp-install-dropdown__footer {
364
+ padding: 0.75rem 1rem;
365
+ text-align: center;
366
+ background-color: var(--ifm-background-color);
367
+ }
368
+
369
+ .mcp-install-dropdown__learn-more {
370
+ display: inline-flex;
371
+ align-items: center;
372
+ font-size: var(--ifm-font-size-small);
373
+ font-weight: var(--ifm-font-weight-semibold);
374
+ color: var(--ifm-color-primary);
375
+ text-decoration: none;
376
+ }
377
+
378
+ .mcp-install-dropdown__learn-more:hover {
379
+ color: var(--ifm-color-primary-dark);
380
+ text-decoration: none;
381
+ }
382
+
383
+ /* Code block styles */
384
+ .mcp-code-block {
385
+ display: flex;
386
+ border-radius: var(--ifm-code-border-radius, 0.25rem);
387
+ overflow: hidden;
388
+ }
389
+
390
+ .mcp-code-block__content {
391
+ flex: 1;
392
+ background-color: var(--mcp-code-bg);
393
+ padding: 0.75rem 1rem;
394
+ overflow-x: auto;
395
+ }
396
+
397
+ .mcp-code-block__content code {
398
+ font-family: var(--ifm-font-family-monospace);
399
+ font-size: var(--ifm-code-font-size);
400
+ color: var(--mcp-code-color);
401
+ background: none;
402
+ padding: 0;
403
+ border: none;
404
+ white-space: nowrap;
405
+ }
406
+
407
+ .mcp-code-block__pre {
408
+ margin: 0;
409
+ background: none;
410
+ max-height: 120px;
411
+ overflow-y: auto;
412
+ }
413
+
414
+ .mcp-code-block__pre code {
415
+ white-space: pre;
416
+ }
417
+
418
+ .mcp-code-block__copy {
419
+ display: flex;
420
+ align-items: center;
421
+ justify-content: center;
422
+ width: 2.75rem;
423
+ background-color: var(--ifm-color-gray-800, #374151);
424
+ border: none;
425
+ cursor: pointer;
426
+ color: var(--ifm-color-gray-400, #9ca3af);
427
+ transition: background-color var(--ifm-transition-fast);
428
+ }
429
+
430
+ .mcp-code-block__copy:hover {
431
+ background-color: var(--ifm-color-gray-700, #4b5563);
432
+ }
433
+
434
+ .mcp-code-block__icon {
435
+ width: 16px;
436
+ height: 16px;
437
+ display: block;
438
+ }
439
+
440
+ .mcp-code-block__icon--success {
441
+ color: var(--ifm-color-success, #22c55e);
442
+ }
443
+ ` })
185
444
  ] });
186
445
  }
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
446
  var McpInstallButton_default = McpInstallButton;
292
447
 
293
448
  exports.McpInstallButton = McpInstallButton;