@atlaskit/ads-mcp 0.4.0 → 0.5.0

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +33 -4
  3. package/dist/cjs/helpers/index.js +9 -0
  4. package/dist/cjs/index.js +3 -3
  5. package/dist/cjs/instructions.js +1 -1
  6. package/dist/cjs/tools/get-components/index.js +1 -1
  7. package/dist/cjs/tools/search-components/index.js +146 -0
  8. package/dist/cjs/tools/search-icons/index.js +33 -9
  9. package/dist/cjs/tools/search-tokens/index.js +2 -4
  10. package/dist/es2019/helpers/index.js +1 -0
  11. package/dist/es2019/index.js +3 -3
  12. package/dist/es2019/instructions.js +0 -9
  13. package/dist/es2019/tools/get-components/index.js +1 -1
  14. package/dist/es2019/tools/search-components/index.js +128 -0
  15. package/dist/es2019/tools/search-icons/index.js +20 -2
  16. package/dist/es2019/tools/search-tokens/index.js +1 -1
  17. package/dist/esm/helpers/index.js +3 -0
  18. package/dist/esm/index.js +3 -3
  19. package/dist/esm/instructions.js +1 -1
  20. package/dist/esm/tools/get-components/index.js +1 -1
  21. package/dist/esm/tools/search-components/index.js +139 -0
  22. package/dist/esm/tools/search-icons/index.js +32 -8
  23. package/dist/esm/tools/search-tokens/index.js +1 -3
  24. package/dist/types/helpers/index.d.ts +1 -0
  25. package/dist/types/instructions.d.ts +1 -1
  26. package/dist/{types-ts4.5/tools/get-component-details → types/tools/search-components}/index.d.ts +11 -5
  27. package/dist/types/tools/search-icons/index.d.ts +7 -0
  28. package/dist/types-ts4.5/helpers/index.d.ts +1 -0
  29. package/dist/types-ts4.5/instructions.d.ts +1 -1
  30. package/dist/{types/tools/get-component-details → types-ts4.5/tools/search-components}/index.d.ts +11 -5
  31. package/dist/types-ts4.5/tools/search-icons/index.d.ts +7 -0
  32. package/package.json +2 -2
  33. package/dist/cjs/tools/get-component-details/index.js +0 -88
  34. package/dist/es2019/tools/get-component-details/index.js +0 -51
  35. package/dist/esm/tools/get-component-details/index.js +0 -81
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/ads-mcp
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`0276dc4a39d9d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0276dc4a39d9d) -
8
+ Renamed `get_component_details` to `search_components` tool and adjusted related references in the
9
+ codebase and improved querying of components.
10
+
11
+ ## 0.4.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [`217beed112e9f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/217beed112e9f) -
16
+ fix broken import
17
+
3
18
  ## 0.4.0
4
19
 
5
20
  ### Minor Changes
package/README.md CHANGED
@@ -12,10 +12,39 @@ to help ensure your interfaces are accessible to all users.
12
12
 
13
13
  ### Design System Tools
14
14
 
15
- - `get_tokens` - Get design tokens for colors, spacing, typography, etc.
16
- - `get_components` - Get a list of available components
17
- - `get_component_details` - Get detailed information about a specific component
18
- - `get_icons` - Get a list of available icons
15
+ - `get_all_tokens` - Get all available design tokens for colors, spacing, typography, etc.
16
+ - `search_tokens` - Search for specific design tokens by name, description, or example values
17
+ - `get_components` - Get a list of all available components with basic information
18
+ - `search_components` - Search for components by name, description, category, or package name
19
+ - `get_all_icons` - Get all available icons from the design system
20
+ - `search_icons` - Search for specific icons by name, keywords, or categorization
21
+
22
+ #### Design System Tools Usage
23
+
24
+ ```typescript
25
+ // Search for components (recommended approach)
26
+ const buttonComponents = await search_components({
27
+ terms: ['button', 'click'],
28
+ limit: 3
29
+ });
30
+
31
+ // Search for specific tokens
32
+ const colorTokens = await search_tokens({
33
+ terms: ['color.text', 'primary'],
34
+ limit: 5
35
+ });
36
+
37
+ // Search for icons
38
+ const addIcons = await search_icons({
39
+ terms: ['add', 'plus', 'create'],
40
+ limit: 2
41
+ });
42
+
43
+ // Get all available items (fallback when search doesn't find what you need)
44
+ const allComponents = await get_components();
45
+ const allTokens = await get_all_tokens();
46
+ const allIcons = await get_all_icons();
47
+ ```
19
48
 
20
49
  ### Accessibility Tools
21
50
 
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cleanQuery = void 0;
7
+ var cleanQuery = exports.cleanQuery = function cleanQuery(query) {
8
+ return query.trim().toLowerCase().replace(/\s+/g, '');
9
+ };
package/dist/cjs/index.js CHANGED
@@ -11,8 +11,8 @@ var _analyzeAccessibility = require("./tools/analyze-accessibility");
11
11
  var _getAccessibilityGuidelines = require("./tools/get-accessibility-guidelines");
12
12
  var _getAllIcons = require("./tools/get-all-icons");
13
13
  var _getAllTokens = require("./tools/get-all-tokens");
14
- var _getComponentDetails = require("./tools/get-component-details");
15
14
  var _getComponents = require("./tools/get-components");
15
+ var _searchComponents = require("./tools/search-components");
16
16
  var _searchIcons = require("./tools/search-icons");
17
17
  var _searchTokens = require("./tools/search-tokens");
18
18
  var _suggestAccessibilityFixes = require("./tools/suggest-accessibility-fixes");
@@ -35,7 +35,7 @@ server.setRequestHandler(_types.ListToolsRequestSchema, /*#__PURE__*/(0, _asyncT
35
35
  while (1) switch (_context.prev = _context.next) {
36
36
  case 0:
37
37
  return _context.abrupt("return", {
38
- tools: [_getAllTokens.listGetAllTokensTool, _getComponents.listGetComponentsTool, _getComponentDetails.listGetComponentDetailsTool, _getAllIcons.listGetAllIconsTool, _searchIcons.listSearchIconsTool, _searchTokens.listSearchTokensTool, _analyzeAccessibility.listAnalyzeAccessibilityTool, _analyzeAccessibility.listAnalyzeLocalhostAccessibilityTool, _getAccessibilityGuidelines.listGetAccessibilityGuidelinesTool, _suggestAccessibilityFixes.listSuggestAccessibilityFixesTool]
38
+ tools: [_getAllTokens.listGetAllTokensTool, _getComponents.listGetComponentsTool, _searchComponents.listSearchComponentsTool, _getAllIcons.listGetAllIconsTool, _searchIcons.listSearchIconsTool, _searchTokens.listSearchTokensTool, _analyzeAccessibility.listAnalyzeAccessibilityTool, _analyzeAccessibility.listAnalyzeLocalhostAccessibilityTool, _getAccessibilityGuidelines.listGetAccessibilityGuidelinesTool, _suggestAccessibilityFixes.listSuggestAccessibilityFixesTool]
39
39
  });
40
40
  case 1:
41
41
  case "end":
@@ -47,7 +47,7 @@ var callTools = {
47
47
  get_all_tokens: _getAllTokens.getAllTokensTool,
48
48
  search_tokens: _searchTokens.searchTokensTool,
49
49
  get_components: _getComponents.getComponentsTool,
50
- get_component_details: _getComponentDetails.getComponentDetailsTool,
50
+ search_components: _searchComponents.searchComponentsTool,
51
51
  get_all_icons: _getAllIcons.getAllIconsTool,
52
52
  search_icons: _searchIcons.searchIconsTool,
53
53
  analyze_accessibility: _analyzeAccessibility.analyzeAccessibilityTool,
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.instructions = void 0;
7
- var instructions = exports.instructions = "\nYou are an expert in the Atlassian Design System (aka ADS). You are able to answer questions about the design system and provide guidance on what offerings to use when building user interfaces.\n\nYou have special expertise in accessibility and can help ensure that interfaces built with ADS components are accessible to all users. You can analyze code for accessibility violations, provide specific fix suggestions, and offer guidance on accessibility best practices.\n\nYou are able to use the provided tools to help answer your questions, but may also access https://atlassian.design/llms.txt, https://atlassian.design/llms-a11y.txt, or https://atlassian.design/ directly for deeper research and information.\n\nAccessibility Tools Available:\n- analyze_accessibility: Analyze React component code for accessibility violations\n- get_accessibility_guidelines: Get specific accessibility guidelines and best practices\n- suggest_accessibility_fixes: Get specific fix suggestions for accessibility violations\n- get_all_tokens: Get all tokens and their example values\n- search_tokens: Search for token(s) and their example value(s)\n- get_all_icons: Get all icons and their usage\n- search_icons: Search for icon(s) and their usage\n";
7
+ var instructions = exports.instructions = "\nYou are an expert in the Atlassian Design System (aka ADS). You are able to answer questions about the design system and provide guidance on what offerings to use when building user interfaces.\n\nYou have special expertise in accessibility and can help ensure that interfaces built with ADS components are accessible to all users. You can analyze code for accessibility violations, provide specific fix suggestions, and offer guidance on accessibility best practices.\n\nYou are able to use the provided tools to help answer your questions, but may also access https://atlassian.design/llms.txt, https://atlassian.design/llms-a11y.txt, or https://atlassian.design/ directly for deeper research and information.\n";
@@ -19,7 +19,7 @@ var componentsList = _components.components.map(function (c) {
19
19
  });
20
20
  var listGetComponentsTool = exports.listGetComponentsTool = {
21
21
  name: 'get_components',
22
- description: "You MUST use this to fetch all Atlassian Design System components and parse their names, descriptions, and understand how they might be used (provided in JSON format) before working with components.\nYou should never use a custom component not provided via this API where appropriate, or the custom component is a necessary wrapper around an ADS component.\n\nFor a full example, guidelines, list of props, and more information, you should use the `get_component_details` tool passing one or many component names as the 'names' tool parameter.\n",
22
+ description: "You MUST use this to fetch all Atlassian Design System components and parse their names, descriptions, and understand how they might be used (provided in JSON format) before working with components.\nYou should never use a custom component not provided via this API where appropriate, or the custom component is a necessary wrapper around an ADS component.\n\nFor a full example, guidelines, list of props, and more information, you should use the `search_components` tool passing one or many component names as the 'terms' tool parameter.\n",
23
23
  annotations: {
24
24
  title: 'Get ADS components',
25
25
  readOnlyHint: true,
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.searchComponentsTool = exports.listSearchComponentsTool = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _fuse = _interopRequireDefault(require("fuse.js"));
11
+ var _zod = require("zod");
12
+ var _zodToJsonSchema = require("zod-to-json-schema");
13
+ var _helpers = require("../../helpers");
14
+ var _components = require("../get-components/components");
15
+ var inputSchema = _zod.z.object({
16
+ terms: _zod.z.array(_zod.z.string()).describe('Search term(s) to find components by name, package name, description, or example'),
17
+ limit: _zod.z.number().optional().default(1).describe('Maximum number of results per term to return (default: 1)'),
18
+ exactName: _zod.z.boolean().optional().default(false).describe('Whether to search for exact match only for the component name')
19
+ });
20
+ var listSearchComponentsTool = exports.listSearchComponentsTool = {
21
+ name: 'search_components',
22
+ description: "You SHOULD use this to search for Atlassian Design System components based on multiple query strings (if there are multiple candidates of component names, descriptions, categories, or package names, you SHOULD pass them in a single call). You SHOULD use default `limit` value of 1 first and only set a higher limit like 5 or 10 if you can't find the component you need. Fallback to `get_components` if nothing is found. This tool searches through component names, descriptions, categories, and package names to find the most relevant design system components.\n\nThe search will match against:\n- Component names (e.g., \"Button\", \"TextField\", \"Avatar\")\n- Package names (e.g., \"@atlaskit/button\", \"@atlaskit/textfield\")\n- Component descriptions (descriptive text about what the component does)\n- Component categories (e.g., \"Forms and Input\", \"Navigation\", \"Data Display\")\n\nThe results include the component's name, package name, example, and props.\n\nUsage pattern for found components:\n```tsx\nimport Button from '@atlaskit/button/new';\nimport CopyIcon from '@atlaskit/icon/core/copy';\n\n<Button appearance=\"primary\" iconBefore={CopyIcon}>Copy text</Button>\n```\n",
23
+ annotations: {
24
+ title: 'Search ADS components',
25
+ readOnlyHint: true,
26
+ destructiveHint: false,
27
+ idempotentHint: true,
28
+ openWorldHint: true
29
+ },
30
+ inputSchema: (0, _zodToJsonSchema.zodToJsonSchema)(inputSchema)
31
+ };
32
+
33
+ // Clean component result to only return name, package name, example, and props
34
+ var cleanComponentResult = function cleanComponentResult(result) {
35
+ return {
36
+ name: result.name,
37
+ packageName: result.packageName,
38
+ example: result.example,
39
+ props: result.props
40
+ };
41
+ };
42
+ var searchComponentsTool = exports.searchComponentsTool = /*#__PURE__*/function () {
43
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(params) {
44
+ var terms, _params$limit, limit, _params$exactName, exactName, searchTerms, exactNameMatches, fuse, results;
45
+ return _regenerator.default.wrap(function _callee$(_context) {
46
+ while (1) switch (_context.prev = _context.next) {
47
+ case 0:
48
+ terms = params.terms, _params$limit = params.limit, limit = _params$limit === void 0 ? 1 : _params$limit, _params$exactName = params.exactName, exactName = _params$exactName === void 0 ? false : _params$exactName;
49
+ searchTerms = terms.filter(Boolean).map(_helpers.cleanQuery);
50
+ if (searchTerms.length) {
51
+ _context.next = 4;
52
+ break;
53
+ }
54
+ return _context.abrupt("return", {
55
+ isError: true,
56
+ content: [{
57
+ type: 'text',
58
+ text: "Error: Required parameter 'terms' is missing or empty"
59
+ }]
60
+ });
61
+ case 4:
62
+ if (!exactName) {
63
+ _context.next = 8;
64
+ break;
65
+ }
66
+ // for each search term, search for the exact match
67
+ exactNameMatches = searchTerms.map(function (term) {
68
+ return _components.components.find(function (component) {
69
+ return component.name.toLowerCase() === term.toLowerCase();
70
+ });
71
+ }).filter(Boolean);
72
+ if (!(exactNameMatches.length > 0)) {
73
+ _context.next = 8;
74
+ break;
75
+ }
76
+ return _context.abrupt("return", {
77
+ content: [{
78
+ type: 'text',
79
+ text: JSON.stringify(exactNameMatches.map(cleanComponentResult))
80
+ }]
81
+ });
82
+ case 8:
83
+ // use Fuse.js to fuzzy-search through the components
84
+ fuse = new _fuse.default(_components.components, {
85
+ keys: [{
86
+ name: 'name',
87
+ weight: 3
88
+ }, {
89
+ name: 'packageName',
90
+ weight: 3
91
+ }, {
92
+ name: 'category',
93
+ weight: 2
94
+ }, {
95
+ name: 'description',
96
+ weight: 2
97
+ }, {
98
+ name: 'example',
99
+ weight: 1
100
+ }],
101
+ threshold: 0.4
102
+ }); // every search term, search for the results
103
+ results = searchTerms.map(function (term) {
104
+ // always search exact match from the components first
105
+ var exactNameMatch = _components.components.find(function (component) {
106
+ return component.name.toLowerCase() === term.toLowerCase();
107
+ });
108
+ if (exactNameMatch) {
109
+ return [{
110
+ item: exactNameMatch
111
+ }];
112
+ }
113
+ return fuse.search(term).slice(0, limit);
114
+ }).flat();
115
+ if (results.length) {
116
+ _context.next = 12;
117
+ break;
118
+ }
119
+ return _context.abrupt("return", {
120
+ isError: true,
121
+ content: [{
122
+ type: 'text',
123
+ text: "Error: No components found for '".concat(terms.join(', '), "'. Available components: ").concat(_components.components.map(function (c) {
124
+ return c.name;
125
+ }).join(', '))
126
+ }]
127
+ });
128
+ case 12:
129
+ return _context.abrupt("return", {
130
+ content: [{
131
+ type: 'text',
132
+ text: JSON.stringify(results.map(function (result) {
133
+ return result.item;
134
+ }).map(cleanComponentResult))
135
+ }]
136
+ });
137
+ case 13:
138
+ case "end":
139
+ return _context.stop();
140
+ }
141
+ }, _callee);
142
+ }));
143
+ return function searchComponentsTool(_x) {
144
+ return _ref.apply(this, arguments);
145
+ };
146
+ }();
@@ -12,6 +12,7 @@ var _fuse = _interopRequireDefault(require("fuse.js"));
12
12
  var _zod = require("zod");
13
13
  var _zodToJsonSchema = require("zod-to-json-schema");
14
14
  var _metadata = require("@atlaskit/icon/metadata");
15
+ var _helpers = require("../../helpers");
15
16
  var inputSchema = _zod.z.object({
16
17
  terms: _zod.z.array(_zod.z.string()).describe('Search term(s) to find icons by name, keywords, or categorization'),
17
18
  limit: _zod.z.number().optional().default(1).describe('Maximum number of results per term to return (default: 1)'),
@@ -36,7 +37,7 @@ var icons = Object.entries(_metadata.coreIconMetadata).map(function (_ref) {
36
37
  });
37
38
  var listSearchIconsTool = exports.listSearchIconsTool = {
38
39
  name: 'search_icons',
39
- description: "You SHOULD Search for Atlassian Design System icons based on multiple query strings (if there's multiple candidates of icon names, categorization or keywords, you SHOULD pass them in a single call). You SHOULD use default `limit` value of 1 first and only set a higher limit like 5 or 10 if you can't find the icon you need). Fallback to `get_all_icons` if nothing is found). This tool searches through component names, icon names, keywords, categorization, type and usage to find the most relevant design icons.\n\n\tThe search will match against:\n\t- Icon component names (e.g., \"AddIcon\", \"DeleteIcon\", \"EditIcon\")\n\t- Icon keywords (descriptive terms associated with icons)\n\t- Icon categorization (e.g., \"single-purpose\", \"multi-purpose\", \"utility\")\n\t- Icon usage descriptions (usage guidelines for the icon)\n\n\tThe results include the icon's component name, package path, and usage guidelines.\n\n\tUsage pattern for found icons:\n\t```tsx\n\timport AddIcon from '@atlaskit/icon/core/add';\n\n\t// Usage in isolation\n\t<AddIcon label=\"Add\" size=\"small\" />\n\n\t// Usage with a button\n\timport Button from '@atlaskit/button/new';\n\t<Button iconAfter={AddIcon}>Create</Button>\n\t```\n\n\tYou SHOULD check proper usage (props, example usage, etc.) of the icon component using `get_component_details` tool before using this tool.\n\t",
40
+ description: "You SHOULD Search for Atlassian Design System icons based on multiple query strings (if there's multiple candidates of icon names, categorization or keywords, you SHOULD pass them in a single call). You SHOULD use default `limit` value of 1 first and only set a higher limit like 5 or 10 if you can't find the icon you need). Fallback to `get_all_icons` if nothing is found). This tool searches through component names, icon names, keywords, categorization, type and usage to find the most relevant design icons.\n\n\tThe search will match against:\n\t- Icon component names (e.g., \"AddIcon\", \"DeleteIcon\", \"EditIcon\")\n\t- Icon keywords (descriptive terms associated with icons)\n\t- Icon categorization (e.g., \"single-purpose\", \"multi-purpose\", \"utility\")\n\t- Icon usage descriptions (usage guidelines for the icon)\n\n\tThe results include the icon's component name, package path, and usage guidelines.\n\n\tUsage pattern for found icons:\n\t```tsx\n\timport AddIcon from '@atlaskit/icon/core/add';\n\n\t// Usage in isolation\n\t<AddIcon label=\"Add\" size=\"small\" />\n\n\t// Usage with a button\n\timport Button from '@atlaskit/button/new';\n\t<Button iconAfter={AddIcon}>Create</Button>\n\t```\n\n\tYou SHOULD check proper usage (props, example usage, etc.) of the icon component using `search_components` tool.\n\t",
40
41
  annotations: {
41
42
  title: 'Search ADS icons',
42
43
  readOnlyHint: true,
@@ -46,9 +47,6 @@ var listSearchIconsTool = exports.listSearchIconsTool = {
46
47
  },
47
48
  inputSchema: (0, _zodToJsonSchema.zodToJsonSchema)(inputSchema)
48
49
  };
49
- var cleanQuery = function cleanQuery(query) {
50
- return query.trim().toLowerCase().replace(/\s+/g, '');
51
- };
52
50
  var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
53
51
  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(params) {
54
52
  var terms, _params$limit, limit, _params$exactName, exactName, searchTerms, exactNameMatches, fuse, results, matchedIcons;
@@ -56,9 +54,21 @@ var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
56
54
  while (1) switch (_context.prev = _context.next) {
57
55
  case 0:
58
56
  terms = params.terms, _params$limit = params.limit, limit = _params$limit === void 0 ? 1 : _params$limit, _params$exactName = params.exactName, exactName = _params$exactName === void 0 ? false : _params$exactName;
59
- searchTerms = terms.filter(Boolean).map(cleanQuery);
57
+ searchTerms = terms.filter(Boolean).map(_helpers.cleanQuery);
58
+ if (searchTerms.length) {
59
+ _context.next = 4;
60
+ break;
61
+ }
62
+ return _context.abrupt("return", {
63
+ isError: true,
64
+ content: [{
65
+ type: 'text',
66
+ text: "Error: Required parameter 'terms' is missing or empty"
67
+ }]
68
+ });
69
+ case 4:
60
70
  if (!exactName) {
61
- _context.next = 6;
71
+ _context.next = 8;
62
72
  break;
63
73
  }
64
74
  // for each search term, search for the exact match
@@ -68,7 +78,7 @@ var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
68
78
  });
69
79
  }).filter(Boolean);
70
80
  if (!(exactNameMatches.length > 0)) {
71
- _context.next = 6;
81
+ _context.next = 8;
72
82
  break;
73
83
  }
74
84
  return _context.abrupt("return", {
@@ -77,7 +87,7 @@ var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
77
87
  text: JSON.stringify(exactNameMatches)
78
88
  }]
79
89
  });
80
- case 6:
90
+ case 8:
81
91
  // use Fuse.js to fuzzy-search through the icons
82
92
  fuse = new _fuse.default(icons, {
83
93
  keys: [{
@@ -113,6 +123,20 @@ var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
113
123
  }
114
124
  return fuse.search(term).slice(0, limit);
115
125
  }).flat();
126
+ if (results.length) {
127
+ _context.next = 12;
128
+ break;
129
+ }
130
+ return _context.abrupt("return", {
131
+ isError: true,
132
+ content: [{
133
+ type: 'text',
134
+ text: "Error: No icons found for '".concat(terms.join(', '), "'. Available icons: ").concat(icons.map(function (i) {
135
+ return i.componentName;
136
+ }).join(', '))
137
+ }]
138
+ });
139
+ case 12:
116
140
  matchedIcons = results.map(function (result) {
117
141
  return {
118
142
  componentName: result.item.componentName,
@@ -126,7 +150,7 @@ var searchIconsTool = exports.searchIconsTool = /*#__PURE__*/function () {
126
150
  text: JSON.stringify(matchedIcons)
127
151
  }]
128
152
  });
129
- case 10:
153
+ case 14:
130
154
  case "end":
131
155
  return _context.stop();
132
156
  }
@@ -11,14 +11,12 @@ var _fuse = _interopRequireDefault(require("fuse.js"));
11
11
  var _zod = require("zod");
12
12
  var _zodToJsonSchema = require("zod-to-json-schema");
13
13
  var _tokenMetadata = require("@atlaskit/tokens/token-metadata");
14
+ var _helpers = require("../../helpers");
14
15
  var inputSchema = _zod.z.object({
15
16
  terms: _zod.z.array(_zod.z.string()).describe('Search term(s) to find tokens by name or description'),
16
17
  limit: _zod.z.number().optional().default(1).describe('Maximum number of results per term to return (default: 1)'),
17
18
  exactName: _zod.z.boolean().optional().default(false).describe('Whether to search for exact match only for the token name')
18
19
  });
19
- var cleanQuery = function cleanQuery(query) {
20
- return query.trim().toLowerCase().replace(/\s+/g, '');
21
- };
22
20
  var listSearchTokensTool = exports.listSearchTokensTool = {
23
21
  name: 'search_tokens',
24
22
  description: "You SHOULD Search for Atlassian Design System tokens based on multiple query strings (if there's multiple candidates of token names, descriptions or example values, you SHOULD pass them in a single call). You SHOULD use default `limit` value of 1 first and only set a higher limit like 5 or 10 if you can't find the token you need). Fallback to `get_all_tokens` if nothing is found). This tool searches through token names, descriptions, and example values to find the most relevant design tokens.\n\nThe search will match against:\n- Token names (e.g., \"color.text\", \"space.100\", \"border.radius\")\n- Token descriptions\n- Token example values (eg. \"#2898BD\" -> \"color.icon.accent.teal\")\n\nThe results include the token's name and example value.\n\nUsage pattern for found tokens:\n```tsx\nimport { token } from '@atlaskit/tokens';\n\nconst styles = css({\ncolor: token('color.text'),\npadding: token('space.100'),\nborderRadius: token('border.radius'),\n});\n```\n",
@@ -38,7 +36,7 @@ var searchTokensTool = exports.searchTokensTool = /*#__PURE__*/function () {
38
36
  while (1) switch (_context.prev = _context.next) {
39
37
  case 0:
40
38
  terms = params.terms, _params$limit = params.limit, limit = _params$limit === void 0 ? 1 : _params$limit, _params$exactName = params.exactName, exactName = _params$exactName === void 0 ? false : _params$exactName;
41
- searchTerms = terms.filter(Boolean).map(cleanQuery);
39
+ searchTerms = terms.filter(Boolean).map(_helpers.cleanQuery);
42
40
  if (!exactName) {
43
41
  _context.next = 6;
44
42
  break;
@@ -0,0 +1 @@
1
+ export const cleanQuery = query => query.trim().toLowerCase().replace(/\s+/g, '');
@@ -7,8 +7,8 @@ import { analyzeAccessibilityTool, analyzeLocalhostAccessibilityTool, listAnalyz
7
7
  import { getAccessibilityGuidelinesTool, listGetAccessibilityGuidelinesTool } from './tools/get-accessibility-guidelines';
8
8
  import { getAllIconsTool, listGetAllIconsTool } from './tools/get-all-icons';
9
9
  import { getAllTokensTool, listGetAllTokensTool } from './tools/get-all-tokens';
10
- import { getComponentDetailsTool, listGetComponentDetailsTool } from './tools/get-component-details';
11
10
  import { getComponentsTool, listGetComponentsTool } from './tools/get-components';
11
+ import { listSearchComponentsTool, searchComponentsTool } from './tools/search-components';
12
12
  import { listSearchIconsTool, searchIconsTool } from './tools/search-icons';
13
13
  import { listSearchTokensTool, searchTokensTool } from './tools/search-tokens';
14
14
  import { listSuggestAccessibilityFixesTool, suggestAccessibilityFixesTool } from './tools/suggest-accessibility-fixes';
@@ -27,14 +27,14 @@ const server = new Server({
27
27
  });
28
28
  server.setRequestHandler(ListToolsRequestSchema, async () => {
29
29
  return {
30
- tools: [listGetAllTokensTool, listGetComponentsTool, listGetComponentDetailsTool, listGetAllIconsTool, listSearchIconsTool, listSearchTokensTool, listAnalyzeAccessibilityTool, listAnalyzeLocalhostAccessibilityTool, listGetAccessibilityGuidelinesTool, listSuggestAccessibilityFixesTool]
30
+ tools: [listGetAllTokensTool, listGetComponentsTool, listSearchComponentsTool, listGetAllIconsTool, listSearchIconsTool, listSearchTokensTool, listAnalyzeAccessibilityTool, listAnalyzeLocalhostAccessibilityTool, listGetAccessibilityGuidelinesTool, listSuggestAccessibilityFixesTool]
31
31
  };
32
32
  });
33
33
  const callTools = {
34
34
  get_all_tokens: getAllTokensTool,
35
35
  search_tokens: searchTokensTool,
36
36
  get_components: getComponentsTool,
37
- get_component_details: getComponentDetailsTool,
37
+ search_components: searchComponentsTool,
38
38
  get_all_icons: getAllIconsTool,
39
39
  search_icons: searchIconsTool,
40
40
  analyze_accessibility: analyzeAccessibilityTool,
@@ -4,13 +4,4 @@ You are an expert in the Atlassian Design System (aka ADS). You are able to answ
4
4
  You have special expertise in accessibility and can help ensure that interfaces built with ADS components are accessible to all users. You can analyze code for accessibility violations, provide specific fix suggestions, and offer guidance on accessibility best practices.
5
5
 
6
6
  You are able to use the provided tools to help answer your questions, but may also access https://atlassian.design/llms.txt, https://atlassian.design/llms-a11y.txt, or https://atlassian.design/ directly for deeper research and information.
7
-
8
- Accessibility Tools Available:
9
- - analyze_accessibility: Analyze React component code for accessibility violations
10
- - get_accessibility_guidelines: Get specific accessibility guidelines and best practices
11
- - suggest_accessibility_fixes: Get specific fix suggestions for accessibility violations
12
- - get_all_tokens: Get all tokens and their example values
13
- - search_tokens: Search for token(s) and their example value(s)
14
- - get_all_icons: Get all icons and their usage
15
- - search_icons: Search for icon(s) and their usage
16
7
  `;
@@ -11,7 +11,7 @@ export const listGetComponentsTool = {
11
11
  description: `You MUST use this to fetch all Atlassian Design System components and parse their names, descriptions, and understand how they might be used (provided in JSON format) before working with components.
12
12
  You should never use a custom component not provided via this API where appropriate, or the custom component is a necessary wrapper around an ADS component.
13
13
 
14
- For a full example, guidelines, list of props, and more information, you should use the \`get_component_details\` tool passing one or many component names as the 'names' tool parameter.
14
+ For a full example, guidelines, list of props, and more information, you should use the \`search_components\` tool passing one or many component names as the 'terms' tool parameter.
15
15
  `,
16
16
  annotations: {
17
17
  title: 'Get ADS components',
@@ -0,0 +1,128 @@
1
+ import Fuse from 'fuse.js';
2
+ import { z } from 'zod';
3
+ import { zodToJsonSchema } from 'zod-to-json-schema';
4
+ import { cleanQuery } from '../../helpers';
5
+ import { components } from '../get-components/components';
6
+ const inputSchema = z.object({
7
+ terms: z.array(z.string()).describe('Search term(s) to find components by name, package name, description, or example'),
8
+ limit: z.number().optional().default(1).describe('Maximum number of results per term to return (default: 1)'),
9
+ exactName: z.boolean().optional().default(false).describe('Whether to search for exact match only for the component name')
10
+ });
11
+ export const listSearchComponentsTool = {
12
+ name: 'search_components',
13
+ description: `You SHOULD use this to search for Atlassian Design System components based on multiple query strings (if there are multiple candidates of component names, descriptions, categories, or package names, you SHOULD pass them in a single call). You SHOULD use default \`limit\` value of 1 first and only set a higher limit like 5 or 10 if you can't find the component you need. Fallback to \`get_components\` if nothing is found. This tool searches through component names, descriptions, categories, and package names to find the most relevant design system components.
14
+
15
+ The search will match against:
16
+ - Component names (e.g., "Button", "TextField", "Avatar")
17
+ - Package names (e.g., "@atlaskit/button", "@atlaskit/textfield")
18
+ - Component descriptions (descriptive text about what the component does)
19
+ - Component categories (e.g., "Forms and Input", "Navigation", "Data Display")
20
+
21
+ The results include the component's name, package name, example, and props.
22
+
23
+ Usage pattern for found components:
24
+ \`\`\`tsx
25
+ import Button from '@atlaskit/button/new';
26
+ import CopyIcon from '@atlaskit/icon/core/copy';
27
+
28
+ <Button appearance="primary" iconBefore={CopyIcon}>Copy text</Button>
29
+ \`\`\`
30
+ `,
31
+ annotations: {
32
+ title: 'Search ADS components',
33
+ readOnlyHint: true,
34
+ destructiveHint: false,
35
+ idempotentHint: true,
36
+ openWorldHint: true
37
+ },
38
+ inputSchema: zodToJsonSchema(inputSchema)
39
+ };
40
+
41
+ // Clean component result to only return name, package name, example, and props
42
+ const cleanComponentResult = result => {
43
+ return {
44
+ name: result.name,
45
+ packageName: result.packageName,
46
+ example: result.example,
47
+ props: result.props
48
+ };
49
+ };
50
+ export const searchComponentsTool = async params => {
51
+ const {
52
+ terms,
53
+ limit = 1,
54
+ exactName = false
55
+ } = params;
56
+ const searchTerms = terms.filter(Boolean).map(cleanQuery);
57
+ if (!searchTerms.length) {
58
+ return {
59
+ isError: true,
60
+ content: [{
61
+ type: 'text',
62
+ text: `Error: Required parameter 'terms' is missing or empty`
63
+ }]
64
+ };
65
+ }
66
+ if (exactName) {
67
+ // for each search term, search for the exact match
68
+ const exactNameMatches = searchTerms.map(term => {
69
+ return components.find(component => component.name.toLowerCase() === term.toLowerCase());
70
+ }).filter(Boolean);
71
+ if (exactNameMatches.length > 0) {
72
+ return {
73
+ content: [{
74
+ type: 'text',
75
+ text: JSON.stringify(exactNameMatches.map(cleanComponentResult))
76
+ }]
77
+ };
78
+ }
79
+ }
80
+
81
+ // use Fuse.js to fuzzy-search through the components
82
+ const fuse = new Fuse(components, {
83
+ keys: [{
84
+ name: 'name',
85
+ weight: 3
86
+ }, {
87
+ name: 'packageName',
88
+ weight: 3
89
+ }, {
90
+ name: 'category',
91
+ weight: 2
92
+ }, {
93
+ name: 'description',
94
+ weight: 2
95
+ }, {
96
+ name: 'example',
97
+ weight: 1
98
+ }],
99
+ threshold: 0.4
100
+ });
101
+
102
+ // every search term, search for the results
103
+ const results = searchTerms.map(term => {
104
+ // always search exact match from the components first
105
+ const exactNameMatch = components.find(component => component.name.toLowerCase() === term.toLowerCase());
106
+ if (exactNameMatch) {
107
+ return [{
108
+ item: exactNameMatch
109
+ }];
110
+ }
111
+ return fuse.search(term).slice(0, limit);
112
+ }).flat();
113
+ if (!results.length) {
114
+ return {
115
+ isError: true,
116
+ content: [{
117
+ type: 'text',
118
+ text: `Error: No components found for '${terms.join(', ')}'. Available components: ${components.map(c => c.name).join(', ')}`
119
+ }]
120
+ };
121
+ }
122
+ return {
123
+ content: [{
124
+ type: 'text',
125
+ text: JSON.stringify(results.map(result => result.item).map(cleanComponentResult))
126
+ }]
127
+ };
128
+ };
@@ -2,6 +2,7 @@ import Fuse from 'fuse.js';
2
2
  import { z } from 'zod';
3
3
  import { zodToJsonSchema } from 'zod-to-json-schema';
4
4
  import { coreIconMetadata } from '@atlaskit/icon/metadata';
5
+ import { cleanQuery } from '../../helpers';
5
6
  const inputSchema = z.object({
6
7
  terms: z.array(z.string()).describe('Search term(s) to find icons by name, keywords, or categorization'),
7
8
  limit: z.number().optional().default(1).describe('Maximum number of results per term to return (default: 1)'),
@@ -41,7 +42,7 @@ export const listSearchIconsTool = {
41
42
  <Button iconAfter={AddIcon}>Create</Button>
42
43
  \`\`\`
43
44
 
44
- You SHOULD check proper usage (props, example usage, etc.) of the icon component using \`get_component_details\` tool before using this tool.
45
+ You SHOULD check proper usage (props, example usage, etc.) of the icon component using \`search_components\` tool.
45
46
  `,
46
47
  annotations: {
47
48
  title: 'Search ADS icons',
@@ -52,7 +53,6 @@ export const listSearchIconsTool = {
52
53
  },
53
54
  inputSchema: zodToJsonSchema(inputSchema)
54
55
  };
55
- const cleanQuery = query => query.trim().toLowerCase().replace(/\s+/g, '');
56
56
  export const searchIconsTool = async params => {
57
57
  const {
58
58
  terms,
@@ -60,6 +60,15 @@ export const searchIconsTool = async params => {
60
60
  exactName = false
61
61
  } = params;
62
62
  const searchTerms = terms.filter(Boolean).map(cleanQuery);
63
+ if (!searchTerms.length) {
64
+ return {
65
+ isError: true,
66
+ content: [{
67
+ type: 'text',
68
+ text: `Error: Required parameter 'terms' is missing or empty`
69
+ }]
70
+ };
71
+ }
63
72
  if (exactName) {
64
73
  // for each search term, search for the exact match
65
74
  const exactNameMatches = searchTerms.map(term => {
@@ -110,6 +119,15 @@ export const searchIconsTool = async params => {
110
119
  }
111
120
  return fuse.search(term).slice(0, limit);
112
121
  }).flat();
122
+ if (!results.length) {
123
+ return {
124
+ isError: true,
125
+ content: [{
126
+ type: 'text',
127
+ text: `Error: No icons found for '${terms.join(', ')}'. Available icons: ${icons.map(i => i.componentName).join(', ')}`
128
+ }]
129
+ };
130
+ }
113
131
  const matchedIcons = results.map(result => {
114
132
  return {
115
133
  componentName: result.item.componentName,