Skip to content

Commit 59a2b92

Browse files
authored
docs: add MCP server docs (#9020)
* add MCP server docs * fix md output * add SVG to card
1 parent 3edd16b commit 59a2b92

File tree

8 files changed

+330
-8
lines changed

8 files changed

+330
-8
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {Layout} from '../../src/Layout';
2+
import {StaticTable} from '../../src/StaticTable';
3+
import {Command} from '../../src/Command';
4+
import {Link} from '@react-spectrum/s2';
5+
export default Layout;
6+
7+
export const section = 'Guides';
8+
export const description = 'MCP Server for React Aria';
9+
export const tags = ['mcp', 'ai', 'documentation', 'tools'];
10+
11+
# MCP Server
12+
13+
The `@react-spectrum/mcp` package allows you to run [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) servers for React Aria locally. It exposes a set of tools that MCP clients can discover and call to browse the docs.
14+
15+
## Using with an MCP client
16+
17+
Add one or both servers to your MCP client configuration (the exact file and schema may depend on your client).
18+
19+
```js
20+
{
21+
"mcpServers": {
22+
"React Aria": {
23+
"command": "npx",
24+
"args": ["@react-spectrum/mcp", "react-aria"]
25+
}
26+
}
27+
}
28+
```
29+
30+
### Cursor
31+
32+
<Link href="cursor://anysphere.cursor-deeplink/mcp/install?name=React%20Aria&config=eyJjb21tYW5kIjoibnB4IEByZWFjdC1zcGVjdHJ1bS9tY3AgcmVhY3QtYXJpYSJ9" aria-label="Add to Cursor">
33+
<picture>
34+
<source srcSet="https://cursor.com/deeplink/mcp-install-dark.svg" media="(prefers-color-scheme: light)" />
35+
<source srcSet="https://cursor.com/deeplink/mcp-install-light.svg" media="(prefers-color-scheme: dark)" />
36+
<img src="https://cursor.com/deeplink/mcp-install-light.svg" alt="Add to Cursor" />
37+
</picture>
38+
</Link>
39+
40+
41+
Or follow Cursor's MCP install [guide](https://docs.cursor.com/en/context/mcp#installing-mcp-servers) and use the standard config above.
42+
43+
### VS Code
44+
45+
<Link href="vscode:mcp/install?%7B%22name%22%3A%22React%20Aria%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40react-spectrum%2Fmcp%22%2C%22react-aria%22%5D%7D" aria-label="Add to Visual Studio Code">
46+
<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in Visual Studio Code" />
47+
</Link>
48+
49+
Or follow VS Code's MCP install [guide](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server) and use the standard config above. You can also add servers using the VS Code CLI:
50+
51+
<Command command='code --add-mcp &#39;{"name":"React Aria","command":"npx","args":["@react-spectrum/mcp","react-aria"]}&#39;' />
52+
53+
### Claude Code
54+
55+
Use the Claude Code CLI to add the servers:
56+
57+
<Command command="claude mcp add react-aria npx @react-spectrum/mcp react-aria" />
58+
59+
For more information, see the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp).
60+
61+
### Codex
62+
63+
Create or edit the configuration file `~/.codex/config.toml` and add:
64+
65+
```js
66+
[mcp_servers.react-aria]
67+
command = "npx"
68+
args = ["@react-spectrum/mcp", "react-aria"]
69+
```
70+
71+
For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/docs/config.md#mcp_servers).
72+
73+
### Gemini CLI
74+
75+
Use the Gemini CLI to add the servers:
76+
77+
<Command command="gemini mcp add react-aria npx @react-spectrum/mcp react-aria" />
78+
79+
For more information, see the [Gemini CLI MCP documentation](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md#how-to-set-up-your-mcp-server).
80+
81+
### Windsurf
82+
83+
Follow the Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp) and use the standard config above.

packages/dev/s2-docs/pages/s2/Icons.mdx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Layout} from '../../src/Layout';
22
import {InstallCommand} from '../../src/InstallCommand';
3+
import {Command} from '../../src/Command';
34
import {IconCards} from '../../src/IconCards';
45
import {IconColors} from '../../src/IconColors';
56
import {IconSizes} from '../../src/IconSizes';
@@ -116,7 +117,7 @@ Now you can import icon SVGs using the `icon:` [pipeline](https://parceljs.org/f
116117

117118
The `@react-spectrum/s2-icon-builder` CLI tool can be used to pre-process a folder of SVG icons into TSX files.
118119

119-
`npx @react-spectrum/s2-icon-builder -i 'path/to/icons/*.svg' -o 'path/to/destination'`
120+
<Command command="npx @react-spectrum/s2-icon-builder -i 'path/to/icons/*.svg' -o 'path/to/destination'" />
120121

121122
This outputs a folder of TSX files with names corresponding to the input SVG files. You may rename them as you wish. To use them in your application, import them like normal components.
122123
`import Icon from './path/to/destination/Icon';`
@@ -126,7 +127,7 @@ This outputs a folder of TSX files with names corresponding to the input SVG fil
126127
You can also build the icons as a separate library for distribution so that multiple projects can share the same icons. Or possibly you simply do not want to output tsx files.
127128
To do this, use the `--isLibrary` flag.
128129

129-
`npx @react-spectrum/s2-icon-builder -i 'path/to/icons/*.svg' -o 'path/to/destination' --isLibrary`
130+
<Command command="npx @react-spectrum/s2-icon-builder -i 'path/to/icons/*.svg' -o 'path/to/destination' --isLibrary" />
130131

131132
This outputs a folder of ES modules and commonjs modules with names corresponding to the input SVG files. You may rename them as you wish. To use them in your application, import them like normal components.
132133
`import Icon from 'library-name/path/to/destination/Icon';`

packages/dev/s2-docs/pages/s2/Illustrations.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Layout} from '../../src/Layout';
22
import {InstallCommand} from '../../src/InstallCommand';
3+
import {Command} from '../../src/Command';
34
import {InlineAlert, Heading, Content} from '@react-spectrum/s2';
45
import {IllustrationCards} from '../../src/IllustrationCards';
56
export default Layout;
@@ -54,7 +55,7 @@ Note that you must use the name `illustration` for the pipeline.
5455

5556
The `@react-spectrum/s2-icon-builder` CLI tool can be used to pre-process a folder of SVG illustrations into TSX files.
5657

57-
`npx @react-spectrum/s2-icon-builder -i 'path/to/illustrations/*.svg' --type illustration -o 'path/to/destination'`
58+
<Command command="npx @react-spectrum/s2-icon-builder -i 'path/to/illustrations/*.svg' --type illustration -o 'path/to/destination'" />
5859

5960
This outputs a folder of TSX files with names corresponding to the input SVG files. You may rename them as you wish. To use them in your application, import them like normal components.
6061
`import Illustration from './path/to/destination/Illustration';`
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import {Layout} from '../../src/Layout';
2+
import {StaticTable} from '../../src/StaticTable';
3+
import {Command} from '../../src/Command';
4+
import {Link} from '@react-spectrum/s2';
5+
export default Layout;
6+
7+
export const section = 'Guides';
8+
export const description = 'MCP Server for React Spectrum';
9+
export const tags = ['mcp', 'ai', 'documentation', 'tools'];
10+
11+
# MCP Server
12+
13+
The `@react-spectrum/mcp` package allows you to run [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) servers for React Spectrum (S2) and React Aria locally. It exposes a set of tools that MCP clients can discover and call to browse the docs.
14+
15+
## Using with an MCP client
16+
17+
Add one or both servers to your MCP client configuration (the exact file and schema may depend on your client).
18+
19+
```js
20+
{
21+
"mcpServers": {
22+
"React Spectrum (S2)": {
23+
"command": "npx",
24+
"args": ["@react-spectrum/mcp", "s2"]
25+
},
26+
"React Aria": {
27+
"command": "npx",
28+
"args": ["@react-spectrum/mcp", "react-aria"]
29+
}
30+
}
31+
}
32+
```
33+
34+
### Cursor
35+
36+
React Spectrum (S2):
37+
38+
<Link href="cursor://anysphere.cursor-deeplink/mcp/install?name=React%20Spectrum%20(S2)&config=eyJjb21tYW5kIjoibnB4IEByZWFjdC1zcGVjdHJ1bS9tY3AgczIifQ%3D%3D" aria-label="Add to Cursor">
39+
<picture>
40+
<source srcSet="https://cursor.com/deeplink/mcp-install-dark.svg" media="(prefers-color-scheme: light)" />
41+
<source srcSet="https://cursor.com/deeplink/mcp-install-light.svg" media="(prefers-color-scheme: dark)" />
42+
<img src="https://cursor.com/deeplink/mcp-install-light.svg" alt="Add to Cursor" />
43+
</picture>
44+
</Link>
45+
46+
React Aria:
47+
48+
<Link href="cursor://anysphere.cursor-deeplink/mcp/install?name=React%20Aria&config=eyJjb21tYW5kIjoibnB4IEByZWFjdC1zcGVjdHJ1bS9tY3AgcmVhY3QtYXJpYSJ9" aria-label="Add to Cursor">
49+
<picture>
50+
<source srcSet="https://cursor.com/deeplink/mcp-install-dark.svg" media="(prefers-color-scheme: light)" />
51+
<source srcSet="https://cursor.com/deeplink/mcp-install-light.svg" media="(prefers-color-scheme: dark)" />
52+
<img src="https://cursor.com/deeplink/mcp-install-light.svg" alt="Add to Cursor" />
53+
</picture>
54+
</Link>
55+
56+
57+
Or follow Cursor's MCP install [guide](https://docs.cursor.com/en/context/mcp#installing-mcp-servers) and use the standard config above.
58+
59+
### VS Code
60+
61+
React Spectrum (S2):
62+
63+
<Link href="vscode:mcp/install?%7B%22name%22%3A%22React%20Spectrum%20(S2)%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40react-spectrum%2Fmcp%22%2C%22s2%22%5D%7D" aria-label="Add to Visual Studio Code">
64+
<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in Visual Studio Code" />
65+
</Link>
66+
67+
React Aria:
68+
69+
<Link href="vscode:mcp/install?%7B%22name%22%3A%22React%20Aria%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40react-spectrum%2Fmcp%22%2C%22react-aria%22%5D%7D" aria-label="Add to Visual Studio Code">
70+
<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in Visual Studio Code" />
71+
</Link>
72+
73+
Or follow VS Code's MCP install [guide](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server) and use the standard config above. You can also add servers using the VS Code CLI:
74+
75+
<Command command='code --add-mcp &#39;{"name":"React Spectrum (S2)","command":"npx","args":["@react-spectrum/mcp","s2"]}&#39;' />
76+
77+
<Command command='code --add-mcp &#39;{"name":"React Aria","command":"npx","args":["@react-spectrum/mcp","react-aria"]}&#39;' />
78+
79+
### Claude Code
80+
81+
Use the Claude Code CLI to add the servers:
82+
83+
<Command command="claude mcp add react-spectrum-s2 npx @react-spectrum/mcp s2" />
84+
85+
<Command command="claude mcp add react-aria npx @react-spectrum/mcp react-aria" />
86+
87+
For more information, see the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp).
88+
89+
### Codex
90+
91+
Create or edit the configuration file `~/.codex/config.toml` and add:
92+
93+
```js
94+
[mcp_servers.react-spectrum-s2]
95+
command = "npx"
96+
args = ["@react-spectrum/mcp", "s2"]
97+
98+
[mcp_servers.react-aria]
99+
command = "npx"
100+
args = ["@react-spectrum/mcp", "react-aria"]
101+
```
102+
103+
For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/docs/config.md#mcp_servers).
104+
105+
### Gemini CLI
106+
107+
Use the Gemini CLI to add the servers:
108+
109+
<Command command="gemini mcp add react-spectrum-s2 npx @react-spectrum/mcp s2" />
110+
111+
<Command command="gemini mcp add react-aria npx @react-spectrum/mcp react-aria" />
112+
113+
For more information, see the [Gemini CLI MCP documentation](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md#how-to-set-up-your-mcp-server).
114+
115+
### Windsurf
116+
117+
Follow the Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp) and use the standard config above.

packages/dev/s2-docs/scripts/generateMarkdownDocs.mjs

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,37 @@ function remarkDocsComponentsToMarkdown() {
695695
return index;
696696
}
697697

698+
// Render a simple command snippet.
699+
if (name === 'Command') {
700+
const commandAttr = node.attributes?.find(a => a.name === 'command');
701+
if (!commandAttr) {
702+
parent.children.splice(index, 1);
703+
return index;
704+
}
705+
706+
let command = '';
707+
if (commandAttr.value?.type === 'mdxJsxAttributeValueExpression') {
708+
command = commandAttr.value.value.replace(/['"`]/g, '').trim();
709+
} else if (typeof commandAttr.value === 'string') {
710+
command = commandAttr.value.trim();
711+
}
712+
713+
if (!command) {
714+
parent.children.splice(index, 1);
715+
return index;
716+
}
717+
718+
const codeNode = {
719+
type: 'code',
720+
lang: 'bash',
721+
meta: '',
722+
value: command
723+
};
724+
725+
parent.children.splice(index, 1, codeNode);
726+
return index;
727+
}
728+
698729
// Render an unordered list of icon names.
699730
if (name === 'IconCards') {
700731
const iconList = getIconNames();
@@ -1082,6 +1113,18 @@ function remarkDocsComponentsToMarkdown() {
10821113
}
10831114
}
10841115

1116+
// Check for aria-label attribute first
1117+
const ariaLabelAttr = node.attributes?.find(a => a.name === 'aria-label');
1118+
let ariaLabel = '';
1119+
1120+
if (ariaLabelAttr) {
1121+
if (ariaLabelAttr.value?.type === 'mdxJsxAttributeValueExpression') {
1122+
ariaLabel = ariaLabelAttr.value.value.replace(/['"`]/g, '').trim();
1123+
} else if (typeof ariaLabelAttr.value === 'string') {
1124+
ariaLabel = ariaLabelAttr.value.trim();
1125+
}
1126+
}
1127+
10851128
// Extract text content from children
10861129
const extractText = (children) => {
10871130
if (!children) {return '';}
@@ -1098,18 +1141,35 @@ function remarkDocsComponentsToMarkdown() {
10981141
.join('');
10991142
};
11001143

1101-
const linkText = extractText(node.children) || href;
1144+
const childrenText = extractText(node.children);
1145+
const linkText = ariaLabel || childrenText || href;
11021146

11031147
if (href) {
11041148
const linkNode = {
11051149
type: 'link',
11061150
url: href,
11071151
children: [{type: 'text', value: linkText}]
11081152
};
1109-
parent.children[index] = linkNode;
1153+
1154+
// If this is a flow element (block-level), wrap in paragraph to preserve spacing
1155+
if (node.type === 'mdxJsxFlowElement') {
1156+
parent.children[index] = {
1157+
type: 'paragraph',
1158+
children: [linkNode]
1159+
};
1160+
} else {
1161+
parent.children[index] = linkNode;
1162+
}
11101163
} else {
11111164
// No href, just convert to plain text
1112-
parent.children[index] = {type: 'text', value: linkText};
1165+
if (node.type === 'mdxJsxFlowElement') {
1166+
parent.children[index] = {
1167+
type: 'paragraph',
1168+
children: [{type: 'text', value: linkText}]
1169+
};
1170+
} else {
1171+
parent.children[index] = {type: 'text', value: linkText};
1172+
}
11131173
}
11141174
return;
11151175
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use client';
2+
3+
import {CopyButton} from './CopyButton';
4+
import React from 'react';
5+
import {style} from '@react-spectrum/s2/style' with {type: 'macro'};
6+
7+
const container = style({
8+
backgroundColor: 'layer-1',
9+
marginY: 20,
10+
borderRadius: 'xl',
11+
display: 'flex',
12+
flexDirection: 'column'
13+
});
14+
15+
const codeWrap = style({
16+
padding: 16
17+
});
18+
19+
const codeContainer = style({
20+
display: 'flex',
21+
alignItems: 'center',
22+
gap: 12,
23+
padding: 4
24+
});
25+
26+
const preStyle = style({
27+
font: {default: 'code-xs', lg: 'code-sm'},
28+
overflowX: 'auto',
29+
paddingY: 8,
30+
paddingX: 0,
31+
margin: 0,
32+
whiteSpace: 'pre',
33+
flex: 1,
34+
minWidth: 0
35+
});
36+
37+
export interface CommandProps {
38+
/** The command to display. */
39+
command: string,
40+
/** Optional label preceding the code block. */
41+
label?: string
42+
}
43+
44+
export function Command({command, label}: CommandProps) {
45+
return (
46+
<div className={container} data-example-switcher>
47+
<div className={codeWrap}>
48+
{label && <div className={style({font: 'body-sm', marginBottom: 8, color: 'body'})}>{label}</div>}
49+
<div className={codeContainer}>
50+
<pre className={preStyle}>{command}</pre>
51+
<CopyButton ariaLabel="Copy command" tooltip="Copy command" text={command} />
52+
</div>
53+
</div>
54+
</div>
55+
);
56+
}
57+
58+
export default Command;

0 commit comments

Comments
 (0)