Skip to content

Commit 82ab383

Browse files
joshblackCopilot
andauthored
feat: add mcp package (#6222)
Co-authored-by: Copilot <[email protected]>
1 parent 97d13fa commit 82ab383

File tree

10 files changed

+8750
-3372
lines changed

10 files changed

+8750
-3372
lines changed

package-lock.json

Lines changed: 7639 additions & 3372 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"private": true,
44
"workspaces": [
55
"packages/rollup-plugin-import-css",
6+
"packages/react",
7+
"packages/mcp",
68
"packages/*",
79
"examples/*"
810
],

packages/mcp/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# @primer/mcp
2+
3+
> The Primer MCP server connects AI tools to Primer's design system. It provides
4+
> tools for AI agents to connect with design tokens, components, patterns, and
5+
> more.
6+
7+
## Getting started
8+
9+
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=Primer+MCP&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40primer%2Fmcp%40latest%22%5D%7D) [![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=Primer+MCP&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22%40primer%2Fmcp%40latest%22%5D%7D&quality=insiders)
10+
11+
The `@primer/mcp` package provides a server that can be run in your local
12+
development environment or can be setup in tools like GitHub Actions to be used
13+
by AI agents.
14+
15+
### VS Code
16+
17+
To use `@primer/mcp` in VS Code, you can use the button in the section above or
18+
follow these steps:
19+
20+
1. Open the Command Palette (Cmd/Ctrl + Shift + P)
21+
2. Type `MCP: Install Server` and select it
22+
3. Select the `stdio` type
23+
4. Enter in the following command: `npx @primer/mcp@latest`
24+
5. Enter the name `Primer MCP` for the server
25+
26+
Your MCP servers configuration should look like:
27+
28+
```json
29+
{
30+
"servers": {
31+
"Primer MCP": {
32+
"type": "stdio",
33+
"command": "npx",
34+
"args": ["@primer/mcp@latest"]
35+
}
36+
},
37+
"inputs": []
38+
}
39+
```
40+
41+
## 🙌 Contributing
42+
43+
We love collaborating with folks inside and outside of GitHub and welcome contributions! If you're interested, check out our [contributing docs](contributor-docs/CONTRIBUTING.md) for more info on how to get started.

packages/mcp/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "@primer/mcp",
3+
"version": "0.0.0",
4+
"private": true,
5+
"type": "module",
6+
"bin": "./dist/stdio.js",
7+
"exports": {
8+
"./transports/stdio": {
9+
"types": "./dist/transports/stdio.d.ts",
10+
"default": "./dist/stdio.js"
11+
}
12+
},
13+
"files": [
14+
"dist",
15+
"src",
16+
"README.md"
17+
],
18+
"scripts": {
19+
"clean": "rimraf dist",
20+
"build": "rollup -c",
21+
"type-check": "tsc --noEmit",
22+
"watch": "rollup -c -w"
23+
},
24+
"dependencies": {
25+
"@babel/runtime": "^7.27.0",
26+
"@modelcontextprotocol/sdk": "^1.12.0",
27+
"@primer/primitives": "10.x || 11.x",
28+
"@primer/react": "^37.24.0",
29+
"cheerio": "^1.0.0",
30+
"turndown": "^7.2.0",
31+
"zod": "^3.23.8"
32+
},
33+
"devDependencies": {
34+
"@babel/core": "^7.27.1",
35+
"@babel/plugin-transform-runtime": "^7.27.1",
36+
"@babel/preset-env": "^7.27.2",
37+
"@babel/preset-typescript": "^7.27.1",
38+
"@modelcontextprotocol/inspector": "^0.13.0",
39+
"@rollup/plugin-babel": "^6.0.4",
40+
"@rollup/plugin-commonjs": "^25.0.8",
41+
"@rollup/plugin-json": "^6.1.0",
42+
"@rollup/plugin-node-resolve": "^15.2.3",
43+
"@types/turndown": "^5.0.5",
44+
"rimraf": "^6.0.1",
45+
"rollup": "^4.30.1",
46+
"rollup-plugin-typescript2": "^0.36.0",
47+
"typescript": "^5.8.3"
48+
}
49+
}

packages/mcp/rollup.config.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {defineConfig} from 'rollup'
2+
import babel from '@rollup/plugin-babel'
3+
import json from '@rollup/plugin-json'
4+
import nodeResolve from '@rollup/plugin-node-resolve'
5+
import commonjs from '@rollup/plugin-commonjs'
6+
import typescript from 'rollup-plugin-typescript2'
7+
import packageJson from './package.json' with {type: 'json'}
8+
9+
const external = [
10+
...Object.keys(packageJson.peerDependencies ?? {}),
11+
...Object.keys(packageJson.dependencies ?? {}),
12+
...Object.keys(packageJson.devDependencies ?? {}),
13+
].map(name => {
14+
return new RegExp(`^${name}(/.*)?`)
15+
})
16+
17+
const config = defineConfig({
18+
input: ['./src/transports/stdio.ts'],
19+
external,
20+
plugins: [
21+
nodeResolve(),
22+
commonjs(),
23+
typescript({
24+
tsconfig: './tsconfig.build.json',
25+
}),
26+
babel({
27+
extensions: ['.js', '.cjs', '.mjs', '.ts', '.tsx'],
28+
presets: [
29+
[
30+
'@babel/preset-env',
31+
{
32+
targets: {
33+
node: 'current',
34+
},
35+
},
36+
],
37+
'@babel/preset-typescript',
38+
],
39+
plugins: ['@babel/plugin-transform-runtime'],
40+
babelHelpers: 'runtime',
41+
}),
42+
json(),
43+
],
44+
output: {
45+
dir: 'dist',
46+
format: 'esm',
47+
importAttributesKey: 'with',
48+
},
49+
})
50+
51+
export default config

packages/mcp/src/primer.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import componentsMetadata from '@primer/react/generated/components.json' with {type: 'json'}
2+
3+
type Component = {
4+
id: string
5+
name: string
6+
importPath: string
7+
}
8+
9+
const components: Array<Component> = Object.entries(componentsMetadata.components).map(([id, component]) => {
10+
return {
11+
id,
12+
name: component.name,
13+
importPath: component.importPath,
14+
}
15+
})
16+
17+
function listComponents(): Array<Component> {
18+
return components
19+
}
20+
21+
type Pattern = {
22+
id: string
23+
name: string
24+
}
25+
26+
const patterns: Array<Pattern> = [
27+
{
28+
id: 'data-visualization',
29+
name: 'Data Visualization',
30+
},
31+
{
32+
id: 'degraded-experiences',
33+
name: 'Degraded Experiences',
34+
},
35+
{
36+
id: 'empty-states',
37+
name: 'Empty States',
38+
},
39+
{
40+
id: 'feature-onboarding',
41+
name: 'Feature Onboarding',
42+
},
43+
{
44+
id: 'forms',
45+
name: 'Forms',
46+
},
47+
{
48+
id: 'loading',
49+
name: 'Loading',
50+
},
51+
{
52+
id: 'navigation',
53+
name: 'Navigation',
54+
},
55+
{
56+
id: 'notification-messaging',
57+
name: 'Notification message',
58+
},
59+
{
60+
id: 'progressive-disclosure',
61+
name: 'Progressive disclosure',
62+
},
63+
{
64+
id: 'saving',
65+
name: 'Saving',
66+
},
67+
]
68+
69+
function listPatterns(): Array<Pattern> {
70+
return patterns
71+
}
72+
73+
export {listComponents, listPatterns}

0 commit comments

Comments
 (0)