@primer/mcp 0.3.2 → 0.3.3-rc.5b1595e6f

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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { s as server } from './server-DRag4xtw.js';
1
+ export { s as server } from './server-B7Ip8Z4Y.js';
2
2
  import '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import 'cheerio';
4
4
  import 'zod';
@@ -420,7 +420,7 @@ function getDesignTokenSpecsText(groups) {
420
420
  * **Shorthand**: MUST use \`font: var(...)\`. NEVER split size/weight.
421
421
  * **Shorthand Fallback**: If no shorthand exists (e.g. Monospace), use individual tokens for font-size, family, and line-height. NEVER raw 1.5.
422
422
  * **States**: Define 5: Rest, Hover, Focus-visible, Active, Disabled.
423
- * **Focus**: \`:focus-visible\` MUST use \`outline: var(--focus-outline)\` AND \`outline-offset: var(--outline-focus-offset)\`.
423
+ * **Focus**: \`:focus-visible\` MUST use \`outline: var(--focus-outline)\` AND \`outline-offset: var(--focus-outline-offset, var(--outline-focus-offset))\`.
424
424
  * **Validation**: CALL \`lint_css\` after any CSS change. Task is incomplete without a success message.
425
425
  * **Self-Correction**: Adopt autofixes immediately. Report unfixable errors to the user.
426
426
 
@@ -491,7 +491,7 @@ function getTokenUsagePatternsText() {
491
491
 
492
492
  .btn-primary:focus-visible {
493
493
  outline: var(--focus-outline);
494
- outline-offset: var(--outline-focus-offset);
494
+ outline-offset: var(--focus-outline-offset, var(--outline-focus-offset));
495
495
  }
496
496
 
497
497
  .btn-primary:active {
@@ -736,7 +736,7 @@ function runStylelint(css) {
736
736
  });
737
737
  }
738
738
 
739
- var version = "0.3.2";
739
+ var version = "0.3.3";
740
740
  var packageJson = {
741
741
  version: version};
742
742
 
@@ -753,7 +753,10 @@ const allTokensWithGuidelines = loadAllTokensWithGuidelines();
753
753
  // Project setup
754
754
  // -----------------------------------------------------------------------------
755
755
  server.registerTool('init', {
756
- description: 'Setup or create a project that includes Primer React'
756
+ description: 'Setup or create a project that includes Primer React',
757
+ annotations: {
758
+ readOnlyHint: true
759
+ }
757
760
  }, async () => {
758
761
  const url = new URL(`/product/getting-started/react`, 'https://primer.style');
759
762
  const response = await fetch(url);
@@ -798,7 +801,10 @@ ${text}
798
801
  // Components
799
802
  // -----------------------------------------------------------------------------
800
803
  server.registerTool('list_components', {
801
- description: 'List all of the components available from Primer React'
804
+ description: 'List all of the components available from Primer React',
805
+ annotations: {
806
+ readOnlyHint: true
807
+ }
802
808
  }, async () => {
803
809
  const components = listComponents().map(component => {
804
810
  return `- ${component.name}`;
@@ -818,6 +824,9 @@ server.registerTool('get_component', {
818
824
  description: 'Retrieve documentation and usage details for a specific React component from the @primer/react package by its name. This tool provides the official Primer documentation for any listed component, making it easy to inspect, reuse, or integrate components in your project.',
819
825
  inputSchema: {
820
826
  name: z.string().describe('The name of the component to retrieve')
827
+ },
828
+ annotations: {
829
+ readOnlyHint: true
821
830
  }
822
831
  }, async ({
823
832
  name
@@ -858,6 +867,9 @@ server.registerTool('get_component_examples', {
858
867
  description: 'Get examples for how to use a component from Primer React',
859
868
  inputSchema: {
860
869
  name: z.string().describe('The name of the component to retrieve')
870
+ },
871
+ annotations: {
872
+ readOnlyHint: true
861
873
  }
862
874
  }, async ({
863
875
  name
@@ -906,6 +918,9 @@ server.registerTool('get_component_usage_guidelines', {
906
918
  description: 'Get usage information for how to use a component from Primer',
907
919
  inputSchema: {
908
920
  name: z.string().describe('The name of the component to retrieve')
921
+ },
922
+ annotations: {
923
+ readOnlyHint: true
909
924
  }
910
925
  }, async ({
911
926
  name
@@ -962,6 +977,9 @@ server.registerTool('get_component_accessibility_guidelines', {
962
977
  description: 'Retrieve accessibility guidelines and best practices for a specific component from the @primer/react package by its name. Use this tool to get official accessibility recommendations, usage tips, and requirements to ensure your UI components are inclusive and meet accessibility standards.',
963
978
  inputSchema: {
964
979
  name: z.string().describe('The name of the component to retrieve')
980
+ },
981
+ annotations: {
982
+ readOnlyHint: true
965
983
  }
966
984
  }, async ({
967
985
  name
@@ -1019,7 +1037,10 @@ ${text}`
1019
1037
  // Patterns
1020
1038
  // -----------------------------------------------------------------------------
1021
1039
  server.registerTool('list_patterns', {
1022
- description: 'List all of the patterns available from Primer React'
1040
+ description: 'List all of the patterns available from Primer React',
1041
+ annotations: {
1042
+ readOnlyHint: true
1043
+ }
1023
1044
  }, async () => {
1024
1045
  const patterns = listPatterns().map(pattern => {
1025
1046
  return `- ${pattern.name}`;
@@ -1037,6 +1058,9 @@ server.registerTool('get_pattern', {
1037
1058
  description: 'Get a specific pattern by name',
1038
1059
  inputSchema: {
1039
1060
  name: z.string().describe('The name of the pattern to retrieve')
1061
+ },
1062
+ annotations: {
1063
+ readOnlyHint: true
1040
1064
  }
1041
1065
  }, async ({
1042
1066
  name
@@ -1091,6 +1115,9 @@ server.registerTool('find_tokens', {
1091
1115
  query: z.string().optional().default('').describe('Search keywords (e.g., "danger border", "success background")'),
1092
1116
  group: z.string().optional().describe('Filter by group (e.g., "fgColor", "border")'),
1093
1117
  limit: z.number().int().min(1).max(100).optional().default(15).describe('Maximum results to return to stay within context limits')
1118
+ },
1119
+ annotations: {
1120
+ readOnlyHint: true
1094
1121
  }
1095
1122
  }, async ({
1096
1123
  query,
@@ -1172,6 +1199,9 @@ server.registerTool('get_token_group_bundle', {
1172
1199
  description: "PREFERRED FOR COMPONENTS. Fetch all tokens for complex UI (e.g., Dialogs, Cards) in one call by providing an array of groups like ['overlay', 'shadow']. Use this instead of multiple find_tokens calls to save context.",
1173
1200
  inputSchema: {
1174
1201
  groups: z.array(z.string()).describe('Array of group names (e.g., ["overlay", "shadow", "focus"])')
1202
+ },
1203
+ annotations: {
1204
+ readOnlyHint: true
1175
1205
  }
1176
1206
  }, async ({
1177
1207
  groups
@@ -1206,7 +1236,10 @@ server.registerTool('get_token_group_bundle', {
1206
1236
  };
1207
1237
  });
1208
1238
  server.registerTool('get_design_token_specs', {
1209
- description: 'CRITICAL: CALL THIS FIRST. Provides the logic matrix and the list of valid group names. You cannot search accurately without this map.'
1239
+ description: 'CRITICAL: CALL THIS FIRST. Provides the logic matrix and the list of valid group names. You cannot search accurately without this map.',
1240
+ annotations: {
1241
+ readOnlyHint: true
1242
+ }
1210
1243
  }, async () => {
1211
1244
  const groups = listTokenGroups();
1212
1245
  const customRules = getDesignTokenSpecsText(groups);
@@ -1225,7 +1258,10 @@ server.registerTool('get_design_token_specs', {
1225
1258
  };
1226
1259
  });
1227
1260
  server.registerTool('get_token_usage_patterns', {
1228
- description: 'Provides "Golden Example" CSS for core patterns: Button (Interactions) and Stack (Layout). Use this to understand how to apply the Logic Matrix, Motion, and Spacing scales.'
1261
+ description: 'Provides "Golden Example" CSS for core patterns: Button (Interactions) and Stack (Layout). Use this to understand how to apply the Logic Matrix, Motion, and Spacing scales.',
1262
+ annotations: {
1263
+ readOnlyHint: true
1264
+ }
1229
1265
  }, async () => {
1230
1266
  const customPatterns = getTokenUsagePatternsText();
1231
1267
  let text;
@@ -1251,6 +1287,9 @@ server.registerTool('lint_css', {
1251
1287
  description: 'REQUIRED FINAL STEP. Use this to validate your CSS. You cannot complete a task involving CSS without a successful run of this tool.',
1252
1288
  inputSchema: {
1253
1289
  css: z.string()
1290
+ },
1291
+ annotations: {
1292
+ readOnlyHint: true
1254
1293
  }
1255
1294
  }, async ({
1256
1295
  css
@@ -1282,7 +1321,10 @@ server.registerTool('lint_css', {
1282
1321
  // Foundations
1283
1322
  // -----------------------------------------------------------------------------
1284
1323
  server.registerTool('get_color_usage', {
1285
- description: 'Get the guidelines for how to apply color to a user interface'
1324
+ description: 'Get the guidelines for how to apply color to a user interface',
1325
+ annotations: {
1326
+ readOnlyHint: true
1327
+ }
1286
1328
  }, async () => {
1287
1329
  const url = new URL(`/product/getting-started/foundations/color-usage`, 'https://primer.style');
1288
1330
  const response = await fetch(url);
@@ -1311,7 +1353,10 @@ server.registerTool('get_color_usage', {
1311
1353
  };
1312
1354
  });
1313
1355
  server.registerTool('get_typography_usage', {
1314
- description: 'Get the guidelines for how to apply typography to a user interface'
1356
+ description: 'Get the guidelines for how to apply typography to a user interface',
1357
+ annotations: {
1358
+ readOnlyHint: true
1359
+ }
1315
1360
  }, async () => {
1316
1361
  const url = new URL(`/product/getting-started/foundations/typography`, 'https://primer.style');
1317
1362
  const response = await fetch(url);
@@ -1344,7 +1389,10 @@ server.registerTool('get_typography_usage', {
1344
1389
  // Icons
1345
1390
  // -----------------------------------------------------------------------------
1346
1391
  server.registerTool('list_icons', {
1347
- description: 'List all of the icons (octicons) available from Primer Octicons React'
1392
+ description: 'List all of the icons (octicons) available from Primer Octicons React',
1393
+ annotations: {
1394
+ readOnlyHint: true
1395
+ }
1348
1396
  }, async () => {
1349
1397
  const icons = listIcons().map(icon => {
1350
1398
  const keywords = icon.keywords.map(keyword => {
@@ -1371,6 +1419,9 @@ server.registerTool('get_icon', {
1371
1419
  inputSchema: {
1372
1420
  name: z.string().describe('The name of the icon to retrieve'),
1373
1421
  size: z.string().optional().describe('The size of the icon to retrieve, e.g. "16"').default('16')
1422
+ },
1423
+ annotations: {
1424
+ readOnlyHint: true
1374
1425
  }
1375
1426
  }, async ({
1376
1427
  name,
@@ -1420,7 +1471,10 @@ ${text}`
1420
1471
  // Coding guidelines
1421
1472
  // -----------------------------------------------------------------------------
1422
1473
  server.registerTool('primer_coding_guidelines', {
1423
- description: 'Get the guidelines when writing code that uses Primer or for UI code that you are creating'
1474
+ description: 'Get the guidelines when writing code that uses Primer or for UI code that you are creating',
1475
+ annotations: {
1476
+ readOnlyHint: true
1477
+ }
1424
1478
  }, async () => {
1425
1479
  return {
1426
1480
  content: [{
@@ -1471,6 +1525,9 @@ server.registerTool('review_alt_text', {
1471
1525
  surroundingText: z.string().describe('Text surrounding the image, relevant to the image.'),
1472
1526
  alt: z.string().describe('The alt text of the image being evaluated'),
1473
1527
  image: z.string().describe('The image URL or file path being evaluated')
1528
+ },
1529
+ annotations: {
1530
+ readOnlyHint: true
1474
1531
  }
1475
1532
  }, async ({
1476
1533
  surroundingText,
package/dist/stdio.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
2
- import { s as server } from './server-DRag4xtw.js';
2
+ import { s as server } from './server-B7Ip8Z4Y.js';
3
3
  import '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import 'cheerio';
5
5
  import 'zod';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@primer/mcp",
3
3
  "description": "An MCP server that connects AI tools to the Primer Design System",
4
- "version": "0.3.2",
4
+ "version": "0.3.3-rc.5b1595e6f",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "mcp": "./bin/mcp.js"
@@ -37,7 +37,7 @@
37
37
  "@modelcontextprotocol/sdk": "^1.24.0",
38
38
  "@primer/octicons": "^19.15.5",
39
39
  "@primer/primitives": "10.x || 11.x",
40
- "@primer/react": "^38.20.0",
40
+ "@primer/react": "^38.28.0",
41
41
  "cheerio": "^1.0.0",
42
42
  "turndown": "^7.2.0",
43
43
  "zod": "^4.3.5"
@@ -56,6 +56,6 @@
56
56
  "rimraf": "^6.0.1",
57
57
  "rollup": "^4.59.0",
58
58
  "rollup-plugin-typescript2": "^0.36.0",
59
- "typescript": "^5.9.2"
59
+ "typescript": "^6.0.3"
60
60
  }
61
61
  }
package/src/primitives.ts CHANGED
@@ -437,7 +437,7 @@ function getDesignTokenSpecsText(groups: TokenGroups): string {
437
437
  * **Shorthand**: MUST use \`font: var(...)\`. NEVER split size/weight.
438
438
  * **Shorthand Fallback**: If no shorthand exists (e.g. Monospace), use individual tokens for font-size, family, and line-height. NEVER raw 1.5.
439
439
  * **States**: Define 5: Rest, Hover, Focus-visible, Active, Disabled.
440
- * **Focus**: \`:focus-visible\` MUST use \`outline: var(--focus-outline)\` AND \`outline-offset: var(--outline-focus-offset)\`.
440
+ * **Focus**: \`:focus-visible\` MUST use \`outline: var(--focus-outline)\` AND \`outline-offset: var(--focus-outline-offset, var(--outline-focus-offset))\`.
441
441
  * **Validation**: CALL \`lint_css\` after any CSS change. Task is incomplete without a success message.
442
442
  * **Self-Correction**: Adopt autofixes immediately. Report unfixable errors to the user.
443
443
 
@@ -508,7 +508,7 @@ function getTokenUsagePatternsText(): string {
508
508
 
509
509
  .btn-primary:focus-visible {
510
510
  outline: var(--focus-outline);
511
- outline-offset: var(--outline-focus-offset);
511
+ outline-offset: var(--focus-outline-offset, var(--outline-focus-offset));
512
512
  }
513
513
 
514
514
  .btn-primary:active {
package/src/server.ts CHANGED
@@ -39,6 +39,7 @@ server.registerTool(
39
39
  'init',
40
40
  {
41
41
  description: 'Setup or create a project that includes Primer React',
42
+ annotations: {readOnlyHint: true},
42
43
  },
43
44
  async () => {
44
45
  const url = new URL(`/product/getting-started/react`, 'https://primer.style')
@@ -92,7 +93,7 @@ ${text}
92
93
  // -----------------------------------------------------------------------------
93
94
  server.registerTool(
94
95
  'list_components',
95
- {description: 'List all of the components available from Primer React'},
96
+ {description: 'List all of the components available from Primer React', annotations: {readOnlyHint: true}},
96
97
  async () => {
97
98
  const components = listComponents().map(component => {
98
99
  return `- ${component.name}`
@@ -120,6 +121,7 @@ server.registerTool(
120
121
  inputSchema: {
121
122
  name: z.string().describe('The name of the component to retrieve'),
122
123
  },
124
+ annotations: {readOnlyHint: true},
123
125
  },
124
126
  async ({name}) => {
125
127
  const components = listComponents()
@@ -166,6 +168,7 @@ server.registerTool(
166
168
  inputSchema: {
167
169
  name: z.string().describe('The name of the component to retrieve'),
168
170
  },
171
+ annotations: {readOnlyHint: true},
169
172
  },
170
173
  async ({name}) => {
171
174
  const components = listComponents()
@@ -226,6 +229,7 @@ server.registerTool(
226
229
  inputSchema: {
227
230
  name: z.string().describe('The name of the component to retrieve'),
228
231
  },
232
+ annotations: {readOnlyHint: true},
229
233
  },
230
234
  async ({name}) => {
231
235
  const components = listComponents()
@@ -298,6 +302,7 @@ server.registerTool(
298
302
  inputSchema: {
299
303
  name: z.string().describe('The name of the component to retrieve'),
300
304
  },
305
+ annotations: {readOnlyHint: true},
301
306
  },
302
307
  async ({name}) => {
303
308
  const components = listComponents()
@@ -367,7 +372,7 @@ ${text}`,
367
372
  // -----------------------------------------------------------------------------
368
373
  server.registerTool(
369
374
  'list_patterns',
370
- {description: 'List all of the patterns available from Primer React'},
375
+ {description: 'List all of the patterns available from Primer React', annotations: {readOnlyHint: true}},
371
376
  async () => {
372
377
  const patterns = listPatterns().map(pattern => {
373
378
  return `- ${pattern.name}`
@@ -392,6 +397,7 @@ server.registerTool(
392
397
  inputSchema: {
393
398
  name: z.string().describe('The name of the pattern to retrieve'),
394
399
  },
400
+ annotations: {readOnlyHint: true},
395
401
  },
396
402
  async ({name}) => {
397
403
  const patterns = listPatterns()
@@ -469,6 +475,7 @@ server.registerTool(
469
475
  .default(15)
470
476
  .describe('Maximum results to return to stay within context limits'),
471
477
  },
478
+ annotations: {readOnlyHint: true},
472
479
  },
473
480
  async ({query, group, limit}) => {
474
481
  // Resolve group via aliases
@@ -566,6 +573,7 @@ server.registerTool(
566
573
  inputSchema: {
567
574
  groups: z.array(z.string()).describe('Array of group names (e.g., ["overlay", "shadow", "focus"])'),
568
575
  },
576
+ annotations: {readOnlyHint: true},
569
577
  },
570
578
  async ({groups}) => {
571
579
  // Normalize and resolve aliases
@@ -608,6 +616,7 @@ server.registerTool(
608
616
  {
609
617
  description:
610
618
  'CRITICAL: CALL THIS FIRST. Provides the logic matrix and the list of valid group names. You cannot search accurately without this map.',
619
+ annotations: {readOnlyHint: true},
611
620
  },
612
621
  async () => {
613
622
  const groups = listTokenGroups()
@@ -631,6 +640,7 @@ server.registerTool(
631
640
  {
632
641
  description:
633
642
  'Provides "Golden Example" CSS for core patterns: Button (Interactions) and Stack (Layout). Use this to understand how to apply the Logic Matrix, Motion, and Spacing scales.',
643
+ annotations: {readOnlyHint: true},
634
644
  },
635
645
  async () => {
636
646
  const customPatterns = getTokenUsagePatternsText()
@@ -659,6 +669,7 @@ server.registerTool(
659
669
  description:
660
670
  'REQUIRED FINAL STEP. Use this to validate your CSS. You cannot complete a task involving CSS without a successful run of this tool.',
661
671
  inputSchema: {css: z.string()},
672
+ annotations: {readOnlyHint: true},
662
673
  },
663
674
  async ({css}) => {
664
675
  try {
@@ -694,7 +705,7 @@ server.registerTool(
694
705
  // -----------------------------------------------------------------------------
695
706
  server.registerTool(
696
707
  'get_color_usage',
697
- {description: 'Get the guidelines for how to apply color to a user interface'},
708
+ {description: 'Get the guidelines for how to apply color to a user interface', annotations: {readOnlyHint: true}},
698
709
  async () => {
699
710
  const url = new URL(`/product/getting-started/foundations/color-usage`, 'https://primer.style')
700
711
  const response = await fetch(url)
@@ -732,7 +743,10 @@ server.registerTool(
732
743
 
733
744
  server.registerTool(
734
745
  'get_typography_usage',
735
- {description: 'Get the guidelines for how to apply typography to a user interface'},
746
+ {
747
+ description: 'Get the guidelines for how to apply typography to a user interface',
748
+ annotations: {readOnlyHint: true},
749
+ },
736
750
  async () => {
737
751
  const url = new URL(`/product/getting-started/foundations/typography`, 'https://primer.style')
738
752
  const response = await fetch(url)
@@ -773,7 +787,10 @@ server.registerTool(
773
787
  // -----------------------------------------------------------------------------
774
788
  server.registerTool(
775
789
  'list_icons',
776
- {description: 'List all of the icons (octicons) available from Primer Octicons React'},
790
+ {
791
+ description: 'List all of the icons (octicons) available from Primer Octicons React',
792
+ annotations: {readOnlyHint: true},
793
+ },
777
794
  async () => {
778
795
  const icons = listIcons().map(icon => {
779
796
  const keywords = icon.keywords.map(keyword => {
@@ -808,6 +825,7 @@ server.registerTool(
808
825
  name: z.string().describe('The name of the icon to retrieve'),
809
826
  size: z.string().optional().describe('The size of the icon to retrieve, e.g. "16"').default('16'),
810
827
  },
828
+ annotations: {readOnlyHint: true},
811
829
  },
812
830
  async ({name, size}) => {
813
831
  const icons = listIcons()
@@ -865,7 +883,10 @@ ${text}`,
865
883
  // -----------------------------------------------------------------------------
866
884
  server.registerTool(
867
885
  'primer_coding_guidelines',
868
- {description: 'Get the guidelines when writing code that uses Primer or for UI code that you are creating'},
886
+ {
887
+ description: 'Get the guidelines when writing code that uses Primer or for UI code that you are creating',
888
+ annotations: {readOnlyHint: true},
889
+ },
869
890
  async () => {
870
891
  return {
871
892
  content: [
@@ -922,6 +943,7 @@ server.registerTool(
922
943
  alt: z.string().describe('The alt text of the image being evaluated'),
923
944
  image: z.string().describe('The image URL or file path being evaluated'),
924
945
  },
946
+ annotations: {readOnlyHint: true},
925
947
  },
926
948
  async ({surroundingText, alt, image}) => {
927
949
  // Call the LLM through MCP sampling