@primer/mcp 0.0.3 → 0.0.4

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,7 +1,16 @@
1
- export { s as server } from './server-BdIvJFTO.js';
1
+ export { s as server } from './server-DHzOLtG9.js';
2
2
  import '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import 'cheerio';
4
4
  import 'zod';
5
5
  import 'turndown';
6
6
  import '@primer/react/generated/components.json' with { type: 'json' };
7
7
  import '@primer/octicons/build/data.json' with { type: 'json' };
8
+ import '@primer/primitives/dist/docs/base/motion/motion.json' with { type: 'json' };
9
+ import '@primer/primitives/dist/docs/base/size/size.json' with { type: 'json' };
10
+ import '@primer/primitives/dist/docs/base/typography/typography.json' with { type: 'json' };
11
+ import '@primer/primitives/dist/docs/functional/size/border.json' with { type: 'json' };
12
+ import '@primer/primitives/dist/docs/functional/size/size-coarse.json' with { type: 'json' };
13
+ import '@primer/primitives/dist/docs/functional/size/size-fine.json' with { type: 'json' };
14
+ import '@primer/primitives/dist/docs/functional/size/size.json' with { type: 'json' };
15
+ import '@primer/primitives/dist/docs/functional/themes/light.json' with { type: 'json' };
16
+ import '@primer/primitives/dist/docs/functional/typography/typography.json' with { type: 'json' };
@@ -1 +1 @@
1
- {"version":3,"file":"primer.d.ts","sourceRoot":"","sources":["../src/primer.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAWD,iBAAS,cAAc,IAAI,KAAK,CAAC,SAAS,CAAC,CAE1C;AAED,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AA6CD,iBAAS,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,CAEtC;AAED,KAAK,IAAI,GAAG;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACvB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CACvB,CAAA;AAUD,iBAAS,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,CAEhC;AAED,OAAO,EAAC,cAAc,EAAE,YAAY,EAAE,SAAS,EAAC,CAAA"}
1
+ {"version":3,"file":"primer.d.ts","sourceRoot":"","sources":["../src/primer.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AA+BD,iBAAS,cAAc,IAAI,KAAK,CAAC,SAAS,CAAC,CAE1C;AAED,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AA6CD,iBAAS,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,CAEtC;AAED,KAAK,IAAI,GAAG;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACvB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CACvB,CAAA;AAUD,iBAAS,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,CAEhC;AAED,OAAO,EAAC,cAAc,EAAE,YAAY,EAAE,SAAS,EAAC,CAAA"}
@@ -0,0 +1,65 @@
1
+ declare const categories: {
2
+ readonly base: {
3
+ readonly motion: {
4
+ name: string;
5
+ type: string;
6
+ value: string | number[];
7
+ }[];
8
+ readonly size: {
9
+ name: string;
10
+ type: string;
11
+ value: string;
12
+ }[];
13
+ readonly typography: {
14
+ name: string;
15
+ type: string;
16
+ value: number;
17
+ }[];
18
+ };
19
+ readonly functional: {
20
+ readonly border: {
21
+ name: string;
22
+ type: string;
23
+ value: string;
24
+ }[];
25
+ readonly sizeCoarse: {
26
+ name: string;
27
+ type: string;
28
+ value: string;
29
+ }[];
30
+ readonly sizeFine: {
31
+ name: string;
32
+ type: string;
33
+ value: string;
34
+ }[];
35
+ readonly size: {
36
+ name: string;
37
+ type: string;
38
+ value: string;
39
+ }[];
40
+ readonly themes: {
41
+ readonly light: {
42
+ name: string;
43
+ type: string;
44
+ value: string;
45
+ }[];
46
+ };
47
+ readonly typography: {
48
+ name: string;
49
+ type: string;
50
+ value: string | number;
51
+ }[];
52
+ };
53
+ };
54
+ declare const tokens: ({
55
+ name: string;
56
+ type: string;
57
+ value: string | number[];
58
+ } | {
59
+ name: string;
60
+ type: string;
61
+ value: string | number;
62
+ })[];
63
+ declare function serialize(value: typeof tokens): string;
64
+ export { categories, tokens, serialize };
65
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEN,CAAA;AAEV,QAAA,MAAM,MAAM;;;;;;;;IAUX,CAAA;AAED,iBAAS,SAAS,CAAC,KAAK,EAAE,OAAO,MAAM,GAAG,MAAM,CAM/C;AAED,OAAO,EAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAC,CAAA"}
@@ -4,13 +4,37 @@ import { z } from 'zod';
4
4
  import TurndownService from 'turndown';
5
5
  import componentsMetadata from '@primer/react/generated/components.json' with { type: 'json' };
6
6
  import octicons from '@primer/octicons/build/data.json' with { type: 'json' };
7
+ import baseMotion from '@primer/primitives/dist/docs/base/motion/motion.json' with { type: 'json' };
8
+ import baseSize from '@primer/primitives/dist/docs/base/size/size.json' with { type: 'json' };
9
+ import baseTypography from '@primer/primitives/dist/docs/base/typography/typography.json' with { type: 'json' };
10
+ import functionalSizeBorder from '@primer/primitives/dist/docs/functional/size/border.json' with { type: 'json' };
11
+ import functionalSizeCoarse from '@primer/primitives/dist/docs/functional/size/size-coarse.json' with { type: 'json' };
12
+ import functionalSizeFine from '@primer/primitives/dist/docs/functional/size/size-fine.json' with { type: 'json' };
13
+ import functionalSize from '@primer/primitives/dist/docs/functional/size/size.json' with { type: 'json' };
14
+ import light from '@primer/primitives/dist/docs/functional/themes/light.json' with { type: 'json' };
15
+ import functionalTypography from '@primer/primitives/dist/docs/functional/typography/typography.json' with { type: 'json' };
7
16
 
17
+ function idToSlug(id) {
18
+ if (id === 'actionbar') {
19
+ return 'action-bar';
20
+ }
21
+ if (id === 'tooltip-v2') {
22
+ return 'tooltip';
23
+ }
24
+ if (id === 'dialog_v2') {
25
+ return 'dialog';
26
+ }
27
+ if (id.startsWith('skeleton')) {
28
+ return 'skeleton-loaders';
29
+ }
30
+ return id.replaceAll('_', '-');
31
+ }
8
32
  const components = Object.entries(componentsMetadata.components).map(([id, component]) => {
9
33
  return {
10
34
  id,
11
35
  name: component.name,
12
36
  importPath: component.importPath,
13
- slug: id.replaceAll('_', '-')
37
+ slug: idToSlug(id)
14
38
  };
15
39
  });
16
40
  function listComponents() {
@@ -61,7 +85,85 @@ function listIcons() {
61
85
  return icons;
62
86
  }
63
87
 
64
- var version = "0.0.3";
88
+ const categories = {
89
+ base: {
90
+ motion: Object.values(baseMotion).map(token => {
91
+ return {
92
+ name: token.name,
93
+ type: token.type,
94
+ value: token.value
95
+ };
96
+ }),
97
+ size: Object.values(baseSize).map(token => {
98
+ return {
99
+ name: token.name,
100
+ type: token.type,
101
+ value: token.value
102
+ };
103
+ }),
104
+ typography: Object.values(baseTypography).map(token => {
105
+ return {
106
+ name: token.name,
107
+ type: token.type,
108
+ value: token.value
109
+ };
110
+ })
111
+ },
112
+ functional: {
113
+ border: Object.values(functionalSizeBorder).map(token => {
114
+ return {
115
+ name: token.name,
116
+ type: token.type,
117
+ value: token.value
118
+ };
119
+ }),
120
+ sizeCoarse: Object.values(functionalSizeCoarse).map(token => {
121
+ return {
122
+ name: token.name,
123
+ type: token.type,
124
+ value: token.value
125
+ };
126
+ }),
127
+ sizeFine: Object.values(functionalSizeFine).map(token => {
128
+ return {
129
+ name: token.name,
130
+ type: token.type,
131
+ value: token.value
132
+ };
133
+ }),
134
+ size: Object.values(functionalSize).map(token => {
135
+ return {
136
+ name: token.name,
137
+ type: token.type,
138
+ value: token.value
139
+ };
140
+ }),
141
+ themes: {
142
+ light: Object.values(light).map(token => {
143
+ return {
144
+ name: token.name,
145
+ type: token.type,
146
+ value: token.value
147
+ };
148
+ })
149
+ },
150
+ typography: Object.values(functionalTypography).map(token => {
151
+ return {
152
+ name: token.name,
153
+ type: token.type,
154
+ value: token.value
155
+ };
156
+ })
157
+ }
158
+ };
159
+ const tokens = [...categories.base.motion, ...categories.base.size, ...categories.base.typography, ...categories.functional.border, ...categories.functional.sizeCoarse, ...categories.functional.sizeFine, ...categories.functional.size, ...categories.functional.themes.light, ...categories.functional.typography];
160
+ function serialize(value) {
161
+ return value.map(token => {
162
+ return `<token name="${token.name}" value="${token.value}" type="${token.type}"></token>`;
163
+ }).join('\n');
164
+ }
165
+
166
+ var version = "0.0.4-rc.0";
65
167
  var packageJson = {
66
168
  version: version};
67
169
 
@@ -389,122 +491,13 @@ ${text}`
389
491
  }]
390
492
  };
391
493
  });
392
- const tokens = [{
393
- category: 'color',
394
- tokens: [{
395
- category: 'foreground',
396
- tokens: ['--fgColor-accent', '--fgColor-attention', '--fgColor-black', '--fgColor-closed', '--fgColor-danger', '--fgColor-default', '--fgColor-disabled', '--fgColor-done', '--fgColor-link', '--fgColor-muted', '--fgColor-neutral', '--fgColor-onEmphasis', '--fgColor-onInverse', '--fgColor-open', '--fgColor-severe', '--fgColor-sponsors', '--fgColor-success', '--fgColor-upsell', '--fgColor-white']
397
- }, {
398
- category: 'background',
399
- tokens: ['--bgColor-accent-emphasis', '--bgColor-accent-muted', '--bgColor-attention-emphasis', '--bgColor-attention-muted', '--bgColor-black', '--bgColor-closed-emphasis', '--bgColor-closed-muted', '--bgColor-danger-emphasis', '--bgColor-danger-muted', '--bgColor-default', '--bgColor-disabled', '--bgColor-done-emphasis', '--bgColor-done-muted', '--bgColor-emphasis', '--bgColor-inset', '--bgColor-inverse', '--bgColor-muted', '--bgColor-neutral-emphasis', '--bgColor-neutral-muted', '--bgColor-open-emphasis', '--bgColor-open-muted', '--bgColor-severe-emphasis', '--bgColor-severe-muted', '--bgColor-sponsors-emphasis', '--bgColor-sponsors-muted', '--bgColor-success-emphasis', '--bgColor-success-muted', '--bgColor-transparent', '--bgColor-upsell-emphasis', '--bgColor-upsell-muted', '--bgColor-white']
400
- }, {
401
- category: 'border',
402
- tokens: ['--borderColor-accent-emphasis', '--borderColor-accent-muted', '--borderColor-attention-emphasis', '--borderColor-attention-muted', '--borderColor-closed-emphasis', '--borderColor-closed-muted', '--borderColor-danger-emphasis', '--borderColor-danger-muted', '--borderColor-default', '--borderColor-disabled', '--borderColor-done-emphasis', '--borderColor-done-muted', '--borderColor-emphasis', '--borderColor-muted', '--borderColor-neutral-emphasis', '--borderColor-neutral-muted', '--borderColor-open-emphasis', '--borderColor-open-muted', '--borderColor-severe-emphasis', '--borderColor-severe-muted', '--borderColor-sponsors-emphasis', '--borderColor-sponsors-muted', '--borderColor-success-emphasis', '--borderColor-success-muted', '--borderColor-translucent', '--borderColor-transparent', '--borderColor-upsell-emphasis', '--borderColor-upsell-muted']
403
- }, {
404
- category: 'shadow',
405
- tokens: ['--shadow-floating-large', '--shadow-floating-legacy', '--shadow-floating-medium', '--shadow-floating-small', '--shadow-floating-xlarge', '--shadow-inset', '--shadow-resting-medium', '--shadow-resting-small', '--shadow-resting-xsmall']
406
- }, {
407
- category: 'control',
408
- tokens: ['--control-bgColor-active', '--control-bgColor-disabled', '--control-bgColor-hover', '--control-bgColor-rest', '--control-bgColor-selected', '--control-borderColor-danger', '--control-borderColor-disabled', '--control-borderColor-emphasis', '--control-borderColor-rest', '--control-borderColor-selected', '--control-borderColor-success', '--control-borderColor-warning', '--control-checked-bgColor-active', '--control-checked-bgColor-disabled', '--control-checked-bgColor-hover', '--control-checked-bgColor-rest', '--control-checked-borderColor-active', '--control-checked-borderColor-disabled', '--control-checked-borderColor-hover', '--control-checked-borderColor-rest', '--control-checked-fgColor-disabled', '--control-checked-fgColor-rest', '--control-danger-bgColor-active', '--control-danger-bgColor-hover', '--control-danger-fgColor-hover', '--control-danger-fgColor-rest', '--control-fgColor-disabled', '--control-fgColor-placeholder', '--control-fgColor-rest', '--control-iconColor-rest', '--control-transparent-bgColor-active', '--control-transparent-bgColor-disabled', '--control-transparent-bgColor-hover', '--control-transparent-bgColor-rest', '--control-transparent-bgColor-selected', '--control-transparent-borderColor-active', '--control-transparent-borderColor-hover', '--control-transparent-borderColor-rest']
409
- }, {
410
- category: 'focus',
411
- tokens: ['--focus-outlineColor']
412
- }, {
413
- category: 'overlay',
414
- tokens: ['--overlay-background-bgColor', '--overlay-bgColor', '--overlay-borderColor']
415
- }]
416
- }, {
417
- category: 'size',
418
- tokens: [{
419
- category: 'base',
420
- tokens: ['--base-size-2', '--base-size-4', '--base-size-6', '--base-size-8', '--base-size-12', '--base-size-16', '--base-size-20', '--base-size-24', '--base-size-28', '--base-size-32', '--base-size-36', '--base-size-40', '--base-size-44', '--base-size-48', '--base-size-64', '--base-size-80', '--base-size-96', '--base-size-112', '--base-size-128']
421
- }, {
422
- category: 'border',
423
- tokens: [{
424
- category: 'border-size',
425
- tokens: ['--boxShadow-thick', '--boxShadow-thicker', '--boxShadow-thin', '--borderWidth-default', '--borderWidth-thick', '--borderWidth-thicker', '--borderWidth-thin']
426
- }, {
427
- category: 'border-radius',
428
- tokens: ['--borderRadius-default', '--borderRadius-full', '--borderRadius-large', '--borderRadius-medium', '--borderRadius-small']
429
- }, {
430
- category: 'outline',
431
- tokens: ['--outline-focus-offset', '--outline-focus-width']
432
- }]
433
- }, {
434
- category: 'layout',
435
- tokens: [{
436
- category: 'stack',
437
- tokens: ['--stack-gap-condensed', '--stack-gap-normal', '--stack-gap-spacious', '--stack-padding-condensed', '--stack-padding-normal', '--stack-padding-spacious']
438
- }, {
439
- category: 'controls',
440
- tokens: ['--controlStack-large-gap-auto', '--controlStack-large-gap-condensed', '--controlStack-large-gap-spacious', '--controlStack-medium-gap-condensed', '--controlStack-medium-gap-spacious', '--controlStack-small-gap-condensed', '--controlStack-small-gap-spacious', '--controlStack-medium-gap-auto', '--controlStack-small-gap-auto', '--control-xsmall-gap', '--control-small-gap', '--control-medium-gap', '--control-large-gap', '--control-xlarge-gap', '--control-xsmall-lineBoxHeight', '--control-small-lineBoxHeight', '--control-medium-lineBoxHeight', '--control-large-lineBoxHeight', '--control-xlarge-lineBoxHeight', '--control-xsmall-paddingBlock', '--control-small-paddingBlock', '--control-medium-paddingBlock', '--control-large-paddingBlock', '--control-xlarge-paddingBlock', '--control-xsmall-paddingInline-condensed', '--control-small-paddingInline-condensed', '--control-medium-paddingInline-condensed', '--control-large-paddingInline-condensed', '--control-xlarge-paddingInline-condensed', '--control-xsmall-paddingInline-normal', '--control-small-paddingInline-normal', '--control-medium-paddingInline-normal', '--control-large-paddingInline-normal', '--control-xlarge-paddingInline-normal', '--control-xsmall-paddingInline-spacious', '--control-small-paddingInline-spacious', '--control-medium-paddingInline-spacious', '--control-large-paddingInline-spacious', '--control-xlarge-paddingInline-spacious', '--control-xsmall-size', '--control-small-size', '--control-medium-size', '--control-large-size', '--control-xlarge-size']
441
- }, {
442
- category: 'overlay',
443
- tokens: ['--overlay-borderRadius', '--overlay-height-large', '--overlay-height-medium', '--overlay-height-small', '--overlay-height-xlarge', '--overlay-offset', '--overlay-padding-condensed', '--overlay-padding-normal', '--overlay-paddingBlock-condensed', '--overlay-paddingBlock-normal', '--overlay-width-large', '--overlay-width-medium', '--overlay-width-small', '--overlay-width-xlarge', '--overlay-width-xsmall']
444
- }]
445
- }]
446
- }, {
447
- category: 'typography',
448
- tokens: [{
449
- category: 'weight',
450
- tokens: ['--base-text-weight-light', '--base-text-weight-normal', '--base-text-weight-medium', '--base-text-weight-semibold']
451
- }, {
452
- category: 'font-family',
453
- tokens: ['--fontStack-monospace', '--fontStack-sansSerif', '--fontStack-sansSerifDisplay', '--fontStack-system']
454
- }, {
455
- category: 'font-shorthand',
456
- tokens: ['--text-body-shorthand-large', '--text-body-shorthand-medium', '--text-body-shorthand-small', '--text-caption-shorthand', '--text-codeBlock-shorthand', '--text-codeInline-shorthand', '--text-display-shorthand', '--text-subtitle-shorthand', '--text-title-shorthand-large', '--text-title-shorthand-medium', '--text-title-shorthand-small']
457
- }, {
458
- category: 'display',
459
- tokens: ['--text-display-lineBoxHeight', '--text-display-lineHeight', '--text-display-size', '--text-display-weight']
460
- }, {
461
- category: 'title-large',
462
- tokens: ['--text-title-lineHeight-large', '--text-title-size-large', '--text-title-weight-large']
463
- }, {
464
- category: 'title-medium',
465
- tokens: ['--text-title-lineHeight-medium', '--text-title-size-medium', '--text-title-weight-medium']
466
- }, {
467
- category: 'title-small',
468
- tokens: ['--text-title-lineHeight-small', '--text-title-size-small', '--text-title-weight-small']
469
- }, {
470
- category: 'subtitle',
471
- tokens: ['--text-subtitle-lineHeight', '--text-subtitle-size', '--text-subtitle-weight']
472
- }, {
473
- category: 'body-large',
474
- tokens: ['--text-body-lineHeight-large', '--text-body-size-large']
475
- }, {
476
- category: 'body-medium',
477
- tokens: ['--text-body-lineHeight-medium', '--text-body-size-medium']
478
- }, {
479
- category: 'body-small',
480
- tokens: ['--text-body-lineHeight-small', '--text-body-size-small']
481
- }, {
482
- category: 'caption',
483
- tokens: ['--text-caption-lineHeight', '--text-caption-size', '--text-caption-weight']
484
- }, {
485
- category: 'code-block',
486
- tokens: ['--text-codeBlock-lineHeight', '--text-codeBlock-size', '--text-codeBlock-weight']
487
- }, {
488
- category: 'inline-code-block',
489
- tokens: ['--text-codeInline-size', '--text-codeInline-weight']
490
- }]
491
- }];
492
- function serialize(token) {
493
- if (typeof token === 'string') {
494
- return `<token name="${token}"></token>`;
495
- }
496
- return `<token-category name="${token.category}">\n${token.tokens.map(serialize).join('\n')}\n</token-category>`;
497
- }
498
494
 
499
495
  // -----------------------------------------------------------------------------
500
496
  // Design Tokens
501
497
  // -----------------------------------------------------------------------------
502
498
  server.tool('list_tokens', 'List all of the design tokens available from Primer', async () => {
503
- let text = 'Below is a list of all designs tokens available from Primer. They are organized by category. Tokens are used in CSS and CSS Modules. They can also be referred to in JavaScript files using the style attribute or prop in React components. To refer to the CSS Custom Property for a design token, wrap it in var(name-of-token). To learn how to use a specific token, use a corresponding usage tool for the category of the token. For example, if a token is a color token look for the get_color_usage tool. \n\n';
504
- for (const token of tokens) {
505
- text += serialize(token);
506
- text += '\n';
507
- }
499
+ let text = 'Below is a list of all design tokens available from Primer. Tokens are used in CSS and CSS Modules. To refer to the CSS Custom Property for a design token, wrap it in var(--{name-of-token}). To learn how to use a specific token, use a corresponding usage tool for the category of the token. For example, if a token is a color token look for the get_color_usage tool. \n\n';
500
+ text += serialize(tokens);
508
501
  return {
509
502
  content: [{
510
503
  type: 'text',
@@ -642,4 +635,84 @@ ${text}`
642
635
  };
643
636
  });
644
637
 
638
+ // -----------------------------------------------------------------------------
639
+ // Coding guidelines
640
+ // -----------------------------------------------------------------------------
641
+ server.tool('primer_coding_guidelines', 'Get the guidelines when writing code that uses Primer or for UI code that you are creating', async () => {
642
+ return {
643
+ content: [{
644
+ type: 'text',
645
+ text: `When writing code that uses Primer, follow these guidelines:
646
+
647
+ ## Design Tokens
648
+
649
+ - Prefer design tokens over hard-coded values. For example, use \`var(--fgColor-default)\` instead of \`#24292f\`. Use the \`list_tokens\` tool to find the design token you need.
650
+ - Prefer recommending design tokens in the same group for related CSS properties. For example, when styling background and border color, use tokens from the same group/category
651
+
652
+ ## Authoring & Using Components
653
+
654
+ - Prefer re-using a component from Primer when possible over writing a new component.
655
+ - Prefer using existing props for a component for styling instead of adding styling to a component
656
+ - Prefer using icons from Primer instead of creating new icons. Use the \`list_icons\` tool to find the icon you need.
657
+ - Follow patterns from Primer when creating new components. Use the \`list_patterns\` tool to find the pattern you need, if one exists
658
+ - When using a component from Primer, make sure to follow the component's usage and accessibility guidelines
659
+
660
+ ## Coding guidelines
661
+
662
+ The following list of coding guidelines must be followed:
663
+
664
+ - Do not use the sx prop for styling components. Instead, use CSS Modules.
665
+ - Do not use the Box component for styling components. Instead, use CSS Modules.
666
+ `
667
+ }]
668
+ };
669
+ });
670
+
671
+ // -----------------------------------------------------------------------------
672
+ // Accessibility
673
+ // -----------------------------------------------------------------------------
674
+
675
+ /**
676
+ * The `review_alt_text` tool is experimental and may be removed in future versions.
677
+ *
678
+ * The intent of this tool is to assist products like Copilot Code Review and Copilot Coding Agent
679
+ * in reviewing both user- and AI-generated alt text for images, ensuring compliance with accessibility guidelines.
680
+ * This tool is not intended to replace human-generated alt text; rather, it supports the review process
681
+ * by providing suggestions for improvement. It should be used alongside human review, not as a substitute.
682
+ *
683
+ *
684
+ **/
685
+ server.tool('review_alt_text', 'Evaluates image alt text against accessibility best practices and context relevance.', {
686
+ surroundingText: z.string().describe('Text surrounding the image, relevant to the image.'),
687
+ alt: z.string().describe('The alt text of the image being evaluated'),
688
+ image: z.union([z.instanceof(File).describe('The image src file being evaluated'), z.string().url().describe('The URL of the image src being evaluated'), z.string().describe('The file path of the image src being evaluated')]).describe('The image file, file path, or URL being evaluated')
689
+ }, async ({
690
+ surroundingText,
691
+ alt,
692
+ image
693
+ }) => {
694
+ // Call the LLM through MCP sampling
695
+ const response = await server.server.createMessage({
696
+ messages: [{
697
+ role: 'user',
698
+ content: {
699
+ type: 'text',
700
+ text: `Does this alt text: '${alt}' meet accessibility guidelines and describe the image: ${image} accurately in context of this surrounding text: '${surroundingText}'?\n\n`
701
+ }
702
+ }],
703
+ sampling: {
704
+ temperature: 0.4
705
+ },
706
+ maxTokens: 500
707
+ });
708
+ return {
709
+ content: [{
710
+ type: 'text',
711
+ text: response.content.type === 'text' ? response.content.text : 'Unable to generate summary'
712
+ }],
713
+ altTextEvaluation: response.content.type === 'text' ? response.content.text : 'Unable to generate summary',
714
+ nextSteps: `If the evaluation indicates issues with the alt text, provide more meaningful alt text based on the feedback. DO NOT run this tool repeatedly on the same image - evaluations may vary slightly with each run.`
715
+ };
716
+ });
717
+
645
718
  export { server as s };