Skip to content

Commit 1cc639d

Browse files
scalvertclaude
andauthored
feat(McpInstallButton): add icon-only mode, configurable header, and Docusaurus styling (#7)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7f5a9d6 commit 1cc639d

4 files changed

Lines changed: 37 additions & 26 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ The button shows a dropdown with copy-to-clipboard configurations for all suppor
178178
|------|------|---------|-------------|
179179
| `serverUrl` | `string` | required | Your MCP server endpoint URL |
180180
| `serverName` | `string` | required | Name for the MCP server |
181-
| `label` | `string` | `"Install MCP"` | Button label |
181+
| `label` | `string` | (none) | Button label. If omitted, shows only the MCP icon |
182+
| `headerText` | `string` | `"Choose your AI tool:"` | Text shown at the top of the dropdown |
182183
| `className` | `string` | `""` | Optional CSS class |
183184
| `clients` | `ClientId[]` | All HTTP-capable | Which clients to show |
184185

examples/basic-docs/src/theme/NavbarItem/McpInstallNavbarItem.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,12 @@ import React from 'react';
22
import { McpInstallButton } from 'docusaurus-plugin-mcp-server/theme';
33

44
export default function McpInstallNavbarItem() {
5-
return <McpInstallButton serverUrl="https://example.com/mcp" serverName="example-docs" />;
5+
// Icon-only mode (no label) with custom header text
6+
return (
7+
<McpInstallButton
8+
serverUrl="https://example.com/mcp"
9+
serverName="example-docs"
10+
headerText="Install in your AI tool:"
11+
/>
12+
);
613
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { default } from './plugin/docusaurus-plugin.js';
12
export { default as mcpServerPlugin } from './plugin/docusaurus-plugin.js';
23
export { McpDocsServer } from './mcp/server.js';
34

src/theme/McpInstallButton.tsx

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ export interface McpInstallButtonProps {
133133
serverUrl?: string;
134134
/** Server name. If not provided, uses plugin configuration. */
135135
serverName?: string;
136-
/** Button label (default: "Install docs MCP") */
136+
/** Button label. If not provided, shows only the MCP icon. */
137137
label?: string;
138138
/** Optional className for styling */
139139
className?: string;
140140
/** Clients to show. Defaults to all HTTP-capable clients from registry. */
141141
clients?: ClientId[];
142+
/** Header text shown at top of dropdown (default: "Choose your AI tool:") */
143+
headerText?: string;
142144
}
143145

144146
/**
@@ -156,9 +158,10 @@ export interface McpInstallButtonProps {
156158
export function McpInstallButton({
157159
serverUrl: serverUrlProp,
158160
serverName: serverNameProp,
159-
label = 'Install docs MCP',
161+
label,
160162
className = '',
161163
clients: clientsProp,
164+
headerText = 'Choose your AI tool:',
162165
}: McpInstallButtonProps) {
163166
const [isOpen, setIsOpen] = useState(false);
164167
const [copiedClient, setCopiedClient] = useState<string | null>(null);
@@ -281,19 +284,20 @@ export function McpInstallButton({
281284
<div ref={dropdownRef} className={dropdownClasses}>
282285
{/* Infima button classes */}
283286
<button
284-
className="button button--primary mcp-install-dropdown__button"
287+
className={`button button--primary mcp-install-dropdown__button${label ? '' : ' mcp-install-dropdown__button--icon-only'}`}
285288
onClick={() => setIsOpen(!isOpen)}
286289
aria-expanded={isOpen}
287290
aria-haspopup="true"
291+
aria-label={label || 'Install MCP'}
288292
>
289293
<IconMcp size={16} />
290-
<span>{label}</span>
294+
{label && <span>{label}</span>}
291295
<IconChevron isOpen={isOpen} />
292296
</button>
293297

294298
{/* Dropdown menu using Infima classes */}
295299
<ul className="dropdown__menu mcp-install-dropdown__menu">
296-
<li className="mcp-install-dropdown__header">Choose your AI tool:</li>
300+
<li className="mcp-install-dropdown__header">{headerText}</li>
297301

298302
{clientConfigs.map((client) => {
299303
const command = getCommandForClient(client.id);
@@ -346,23 +350,21 @@ export function McpInstallButton({
346350
</li>
347351
</ul>
348352

349-
{/* Scoped styles using CSS variables for customization */}
353+
{/* Scoped styles using Docusaurus/Infima CSS variables */}
350354
<style>{`
351-
.mcp-install-dropdown {
352-
--mcp-dropdown-width: 520px;
353-
/* Always use dark code blocks for consistency across themes */
354-
--mcp-code-bg: #1e1e1e;
355-
--mcp-code-color: #e5e7eb;
356-
}
357-
358355
.mcp-install-dropdown__button {
359356
display: inline-flex;
360357
align-items: center;
361358
gap: 0.5rem;
362359
}
363360
361+
.mcp-install-dropdown__button--icon-only {
362+
padding: 0.5rem 0.75rem;
363+
gap: 0.25rem;
364+
}
365+
364366
.mcp-install-dropdown__menu {
365-
width: var(--mcp-dropdown-width);
367+
width: 520px;
366368
padding: 0;
367369
top: calc(100% + 0.25rem);
368370
}
@@ -371,7 +373,7 @@ export function McpInstallButton({
371373
padding: 0.75rem 1rem;
372374
font-size: var(--ifm-font-size-small);
373375
font-weight: var(--ifm-font-weight-semibold);
374-
color: var(--ifm-color-secondary-darkest);
376+
color: var(--ifm-color-emphasis-700);
375377
background-color: var(--ifm-background-color);
376378
border-bottom: 1px solid var(--ifm-toc-border-color);
377379
}
@@ -396,7 +398,7 @@ export function McpInstallButton({
396398
.mcp-install-dropdown__notes {
397399
margin: 0.5rem 0 0;
398400
font-size: var(--ifm-font-size-small);
399-
color: var(--ifm-color-secondary-darkest);
401+
color: var(--ifm-color-emphasis-700);
400402
line-height: 1.4;
401403
}
402404
@@ -420,24 +422,24 @@ export function McpInstallButton({
420422
text-decoration: none;
421423
}
422424
423-
/* Code block styles */
425+
/* Code block styles - uses Docusaurus pre/code variables */
424426
.mcp-code-block {
425427
display: flex;
426-
border-radius: var(--ifm-code-border-radius, 0.25rem);
428+
border-radius: var(--ifm-code-border-radius);
427429
overflow: hidden;
428430
}
429431
430432
.mcp-code-block__content {
431433
flex: 1;
432-
background-color: var(--mcp-code-bg);
434+
background-color: var(--ifm-pre-background);
433435
padding: 0.75rem 1rem;
434436
overflow-x: auto;
435437
}
436438
437439
.mcp-code-block__content code {
438440
font-family: var(--ifm-font-family-monospace);
439441
font-size: var(--ifm-code-font-size);
440-
color: var(--mcp-code-color);
442+
color: var(--ifm-pre-color);
441443
background: none;
442444
padding: 0;
443445
border: none;
@@ -460,15 +462,15 @@ export function McpInstallButton({
460462
align-items: center;
461463
justify-content: center;
462464
width: 2.75rem;
463-
background-color: var(--ifm-color-gray-800, #374151);
465+
background-color: var(--ifm-color-emphasis-200);
464466
border: none;
465467
cursor: pointer;
466-
color: var(--ifm-color-gray-400, #9ca3af);
468+
color: var(--ifm-color-emphasis-700);
467469
transition: background-color var(--ifm-transition-fast);
468470
}
469471
470472
.mcp-code-block__copy:hover {
471-
background-color: var(--ifm-color-gray-700, #4b5563);
473+
background-color: var(--ifm-color-emphasis-300);
472474
}
473475
474476
.mcp-code-block__icon {
@@ -478,7 +480,7 @@ export function McpInstallButton({
478480
}
479481
480482
.mcp-code-block__icon--success {
481-
color: var(--ifm-color-success, #22c55e);
483+
color: var(--ifm-color-success);
482484
}
483485
`}</style>
484486
</div>

0 commit comments

Comments
 (0)