@elsahafy/ux-mcp-server 2.0.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.
@@ -0,0 +1,344 @@
1
+ {
2
+ "name": "Common UI Patterns Library",
3
+ "description": "Proven user interface patterns for common scenarios",
4
+ "patterns": {
5
+ "navigation": {
6
+ "header_navigation": {
7
+ "name": "Header Navigation",
8
+ "when_to_use": "Primary navigation for websites and web apps with 5-7 main sections",
9
+ "structure": "Logo (left) + Nav items (center/right) + Actions (right)",
10
+ "best_practices": [
11
+ "Highlight current page in navigation",
12
+ "Use descriptive labels (not 'Products' → 'Our Solutions')",
13
+ "Mobile: Collapse to hamburger menu",
14
+ "Sticky header for long pages",
15
+ "Max 7 items (Miller's Law)"
16
+ ],
17
+ "accessibility": [
18
+ "nav element with aria-label",
19
+ "Current page marked with aria-current='page'",
20
+ "Keyboard navigation support"
21
+ ],
22
+ "example_structure": "header > nav > ul > li > a"
23
+ },
24
+ "breadcrumbs": {
25
+ "name": "Breadcrumbs",
26
+ "when_to_use": "Deep hierarchical navigation, e-commerce, documentation",
27
+ "structure": "Home > Category > Subcategory > Current Page",
28
+ "best_practices": [
29
+ "Show user's current location",
30
+ "Make each level clickable except current",
31
+ "Use chevrons (>) or slashes (/) as separators",
32
+ "Place above page title",
33
+ "Keep concise (truncate long names)"
34
+ ],
35
+ "accessibility": [
36
+ "nav element with aria-label='Breadcrumb'",
37
+ "Structured data (schema.org/BreadcrumbList)",
38
+ "Current page marked with aria-current='page'"
39
+ ]
40
+ },
41
+ "tabs": {
42
+ "name": "Tabs",
43
+ "when_to_use": "Organize related content into separate views without navigation",
44
+ "structure": "Tab list (horizontal) + Tab panels",
45
+ "best_practices": [
46
+ "3-6 tabs is optimal",
47
+ "Clear active state",
48
+ "Lazy load content if heavy",
49
+ "Don't use for sequential steps (use wizard)",
50
+ "Keep tab labels short"
51
+ ],
52
+ "accessibility": [
53
+ "role='tablist' on container",
54
+ "role='tab' on each tab",
55
+ "role='tabpanel' on panels",
56
+ "Arrow keys to navigate tabs",
57
+ "aria-selected and aria-controls"
58
+ ]
59
+ }
60
+ },
61
+ "forms": {
62
+ "single_column_form": {
63
+ "name": "Single Column Form",
64
+ "when_to_use": "Most forms, especially on mobile",
65
+ "structure": "Label above input, helper text, error below",
66
+ "best_practices": [
67
+ "One column layout (faster completion)",
68
+ "Labels above fields (not placeholder-only)",
69
+ "Group related fields",
70
+ "Show password requirements upfront",
71
+ "Disable submit until valid (with visual feedback)",
72
+ "Use appropriate input types",
73
+ "Autofocus first field"
74
+ ],
75
+ "accessibility": [
76
+ "Label associated with for/id",
77
+ "Required fields marked with aria-required",
78
+ "Errors announced with aria-live",
79
+ "Fieldsets for radio/checkbox groups"
80
+ ],
81
+ "validation": {
82
+ "timing": "Validate on blur, show success on input",
83
+ "messages": "Specific and actionable",
84
+ "visual": "Icon + color + text (not color alone)"
85
+ }
86
+ },
87
+ "multi_step_wizard": {
88
+ "name": "Multi-Step Wizard",
89
+ "when_to_use": "Complex forms, checkout flows, onboarding",
90
+ "structure": "Progress indicator + Step content + Navigation",
91
+ "best_practices": [
92
+ "Show progress (steps completed / total)",
93
+ "Allow editing previous steps",
94
+ "Save progress automatically",
95
+ "Validate each step before proceeding",
96
+ "Provide clear 'Next' and 'Back' buttons",
97
+ "Review step before final submission"
98
+ ],
99
+ "accessibility": [
100
+ "Announce step changes",
101
+ "Keyboard navigation between steps",
102
+ "Clear heading for each step"
103
+ ]
104
+ },
105
+ "inline_validation": {
106
+ "name": "Inline Validation",
107
+ "when_to_use": "Real-time feedback on form inputs",
108
+ "timing": {
109
+ "on_blur": "Check when user leaves field",
110
+ "on_input": "Show success state as user types (for password strength, username availability)",
111
+ "on_submit": "Final validation before submission"
112
+ },
113
+ "best_practices": [
114
+ "Don't validate on first keystroke",
115
+ "Show success states (green checkmark)",
116
+ "Keep error messages visible",
117
+ "Place errors below field",
118
+ "Use icons + color + text"
119
+ ]
120
+ }
121
+ },
122
+ "feedback": {
123
+ "toast_notification": {
124
+ "name": "Toast/Snackbar",
125
+ "when_to_use": "Non-critical, brief messages (success, info, warning)",
126
+ "structure": "Message + Optional action + Dismiss",
127
+ "best_practices": [
128
+ "Auto-dismiss after 4-6 seconds",
129
+ "One toast at a time",
130
+ "Position: bottom-left or top-right",
131
+ "Allow manual dismiss",
132
+ "Don't block important content",
133
+ "Stack multiple toasts vertically"
134
+ ],
135
+ "accessibility": [
136
+ "role='status' for non-critical",
137
+ "role='alert' for urgent",
138
+ "Announce to screen readers"
139
+ ],
140
+ "types": {
141
+ "success": "Green, checkmark icon, 'Action completed'",
142
+ "error": "Red, X icon, 'Action failed: [reason]'",
143
+ "warning": "Yellow, alert icon, 'Caution: [message]'",
144
+ "info": "Blue, info icon, 'FYI: [message]'"
145
+ }
146
+ },
147
+ "modal_dialog": {
148
+ "name": "Modal Dialog",
149
+ "when_to_use": "Require user attention/decision, prevent errors",
150
+ "structure": "Backdrop + Dialog (Title + Content + Actions)",
151
+ "best_practices": [
152
+ "Use sparingly (interrupts workflow)",
153
+ "Darken background (80% opacity)",
154
+ "Clear title describing action",
155
+ "Primary action on right",
156
+ "Allow dismiss (X, ESC, click outside)",
157
+ "Trap focus inside modal",
158
+ "Return focus on close"
159
+ ],
160
+ "accessibility": [
161
+ "role='dialog' or 'alertdialog'",
162
+ "aria-labelledby points to title",
163
+ "aria-modal='true'",
164
+ "ESC to close",
165
+ "Focus trap implemented",
166
+ "Announce to screen readers"
167
+ ],
168
+ "types": {
169
+ "confirmation": "Are you sure? [Cancel] [Confirm]",
170
+ "form": "Collect information, [Cancel] [Submit]",
171
+ "alert": "Error/warning that requires acknowledgment"
172
+ }
173
+ },
174
+ "loading_states": {
175
+ "name": "Loading Indicators",
176
+ "when_to_use": "Operations taking > 200ms",
177
+ "types": {
178
+ "spinner": "General loading (< 2 seconds)",
179
+ "progress_bar": "Known duration, show percentage",
180
+ "skeleton_screen": "Content loading, preserve layout",
181
+ "button_loading": "Disable + show spinner + 'Loading...' text"
182
+ },
183
+ "best_practices": [
184
+ "Show immediately for ops > 200ms",
185
+ "Estimate time if possible",
186
+ "Keep UI responsive",
187
+ "Disable actions during loading",
188
+ "Provide cancel option for long operations"
189
+ ]
190
+ }
191
+ },
192
+ "data_display": {
193
+ "data_table": {
194
+ "name": "Data Table",
195
+ "when_to_use": "Display structured data, comparisons",
196
+ "features": [
197
+ "Sortable columns (click header)",
198
+ "Pagination for large datasets",
199
+ "Row selection (checkbox)",
200
+ "Filters and search",
201
+ "Fixed header on scroll",
202
+ "Responsive: stack on mobile",
203
+ "Zebra striping for readability"
204
+ ],
205
+ "best_practices": [
206
+ "Left-align text, right-align numbers",
207
+ "Highlight row on hover",
208
+ "Show loading state for data",
209
+ "Empty state with helpful message",
210
+ "Export functionality if needed"
211
+ ],
212
+ "accessibility": [
213
+ "table, thead, tbody, th, td elements",
214
+ "scope attribute on headers",
215
+ "caption for table description",
216
+ "Sortable columns announce state"
217
+ ]
218
+ },
219
+ "cards": {
220
+ "name": "Card Pattern",
221
+ "when_to_use": "Group related information, scannable content",
222
+ "structure": "Image + Title + Description + Actions",
223
+ "best_practices": [
224
+ "Consistent card dimensions",
225
+ "Clear visual hierarchy",
226
+ "Subtle shadow for depth",
227
+ "Hover state (lift effect)",
228
+ "Make entire card clickable if one action",
229
+ "Use grid layout (2-4 columns)"
230
+ ],
231
+ "accessibility": [
232
+ "Semantic markup (article)",
233
+ "Descriptive headings",
234
+ "Link text describes destination"
235
+ ]
236
+ },
237
+ "empty_states": {
238
+ "name": "Empty State",
239
+ "when_to_use": "No data to display, first-time use",
240
+ "structure": "Illustration + Message + Call-to-action",
241
+ "best_practices": [
242
+ "Explain why it's empty",
243
+ "Provide clear next action",
244
+ "Use friendly illustration",
245
+ "Match tone to context",
246
+ "Don't use 'No results found' alone"
247
+ ],
248
+ "examples": [
249
+ "No items yet: 'Start by adding your first item'",
250
+ "Search no results: 'Try different keywords'",
251
+ "Filter no results: 'Adjust your filters'"
252
+ ]
253
+ }
254
+ },
255
+ "input_components": {
256
+ "search": {
257
+ "name": "Search Input",
258
+ "features": [
259
+ "Clear icon (X) to reset",
260
+ "Search icon (magnifying glass)",
261
+ "Auto-complete suggestions",
262
+ "Recent searches",
263
+ "Highlight matching text",
264
+ "Show result count"
265
+ ],
266
+ "best_practices": [
267
+ "Prominent placement",
268
+ "Keyboard shortcut (/, Cmd+K)",
269
+ "Show search while typing (if fast)",
270
+ "Preserve query in URL",
271
+ "Empty state for no results"
272
+ ],
273
+ "accessibility": [
274
+ "role='search' on form",
275
+ "aria-label for input",
276
+ "Announce results count"
277
+ ]
278
+ },
279
+ "date_picker": {
280
+ "name": "Date Picker",
281
+ "structure": "Input field + Calendar popup",
282
+ "best_practices": [
283
+ "Allow manual input (MM/DD/YYYY)",
284
+ "Today button in calendar",
285
+ "Disable invalid dates",
286
+ "Show selected date clearly",
287
+ "Support keyboard navigation",
288
+ "Localize format"
289
+ ],
290
+ "accessibility": [
291
+ "Input has label",
292
+ "Calendar has role='dialog'",
293
+ "Arrow keys navigate dates",
294
+ "ESC closes calendar"
295
+ ]
296
+ },
297
+ "file_upload": {
298
+ "name": "File Upload",
299
+ "structure": "Drop zone + Browse button + Preview",
300
+ "best_practices": [
301
+ "Drag and drop support",
302
+ "Show accepted file types",
303
+ "Display file size limits",
304
+ "Upload progress indicator",
305
+ "Preview before upload",
306
+ "Multiple file support",
307
+ "Remove uploaded files"
308
+ ],
309
+ "accessibility": [
310
+ "Input type='file' with label",
311
+ "Keyboard accessible",
312
+ "Announce upload status"
313
+ ]
314
+ }
315
+ }
316
+ },
317
+ "anti_patterns": [
318
+ {
319
+ "name": "Placeholder as Label",
320
+ "problem": "Placeholder disappears when user types, hard to remember what field is for",
321
+ "solution": "Always use visible labels above fields"
322
+ },
323
+ {
324
+ "name": "Infinite Scroll Only",
325
+ "problem": "Can't return to specific item, no footer access, hard to bookmark",
326
+ "solution": "Offer pagination option or 'Load More' button"
327
+ },
328
+ {
329
+ "name": "Carousel/Slider for Critical Content",
330
+ "problem": "Users rarely interact with slides beyond first, important content gets missed",
331
+ "solution": "Display critical information statically"
332
+ },
333
+ {
334
+ "name": "Disabled Buttons Without Explanation",
335
+ "problem": "Users don't know why they can't proceed",
336
+ "solution": "Show tooltip explaining what's needed to enable"
337
+ },
338
+ {
339
+ "name": "Generic 'Click Here' Links",
340
+ "problem": "Not accessible, no context out of flow",
341
+ "solution": "Use descriptive link text: 'Read the full report'"
342
+ }
343
+ ]
344
+ }
@@ -0,0 +1,201 @@
1
+ {
2
+ "version": "WCAG 2.1 Level AA",
3
+ "categories": {
4
+ "perceivable": {
5
+ "name": "Perceivable",
6
+ "description": "Information and user interface components must be presentable to users in ways they can perceive",
7
+ "guidelines": [
8
+ {
9
+ "id": "1.1.1",
10
+ "name": "Non-text Content",
11
+ "level": "A",
12
+ "description": "All non-text content has a text alternative",
13
+ "examples": [
14
+ "Images must have alt text",
15
+ "Form inputs must have labels",
16
+ "Icon buttons must have aria-label or aria-labelledby"
17
+ ],
18
+ "code_checks": [
19
+ "img elements have alt attribute",
20
+ "input elements have associated label",
21
+ "button elements with only icons have aria-label"
22
+ ]
23
+ },
24
+ {
25
+ "id": "1.3.1",
26
+ "name": "Info and Relationships",
27
+ "level": "A",
28
+ "description": "Information, structure, and relationships conveyed through presentation can be programmatically determined",
29
+ "examples": [
30
+ "Use semantic HTML (header, nav, main, footer)",
31
+ "Headings follow logical hierarchy (h1 > h2 > h3)",
32
+ "Lists use ul/ol elements",
33
+ "Tables use proper table markup with th and scope"
34
+ ]
35
+ },
36
+ {
37
+ "id": "1.4.3",
38
+ "name": "Contrast (Minimum)",
39
+ "level": "AA",
40
+ "description": "Text has contrast ratio of at least 4.5:1 (3:1 for large text)",
41
+ "examples": [
42
+ "Normal text: 4.5:1 contrast ratio",
43
+ "Large text (18pt+ or 14pt+ bold): 3:1 contrast ratio",
44
+ "Use tools to verify: WebAIM Contrast Checker"
45
+ ],
46
+ "code_checks": [
47
+ "Check color values against background",
48
+ "Verify contrast for all text states (hover, focus, disabled)"
49
+ ]
50
+ },
51
+ {
52
+ "id": "1.4.11",
53
+ "name": "Non-text Contrast",
54
+ "level": "AA",
55
+ "description": "UI components and graphical objects have contrast ratio of at least 3:1",
56
+ "examples": [
57
+ "Form borders and focus indicators",
58
+ "Interactive component boundaries",
59
+ "Icons and graphical elements"
60
+ ]
61
+ }
62
+ ]
63
+ },
64
+ "operable": {
65
+ "name": "Operable",
66
+ "description": "User interface components and navigation must be operable",
67
+ "guidelines": [
68
+ {
69
+ "id": "2.1.1",
70
+ "name": "Keyboard",
71
+ "level": "A",
72
+ "description": "All functionality available from keyboard",
73
+ "examples": [
74
+ "Tab through all interactive elements",
75
+ "Use Enter/Space to activate buttons",
76
+ "Arrow keys for radio groups and menus",
77
+ "Escape to close modals/dialogs"
78
+ ],
79
+ "code_checks": [
80
+ "No keyboard traps",
81
+ "Custom widgets handle keyboard events",
82
+ "Avoid onclick on non-interactive elements"
83
+ ]
84
+ },
85
+ {
86
+ "id": "2.4.3",
87
+ "name": "Focus Order",
88
+ "level": "A",
89
+ "description": "Focusable components receive focus in logical order",
90
+ "examples": [
91
+ "Tab order follows visual layout",
92
+ "Avoid positive tabindex values",
93
+ "Use tabindex=-1 for programmatic focus only"
94
+ ]
95
+ },
96
+ {
97
+ "id": "2.4.7",
98
+ "name": "Focus Visible",
99
+ "level": "AA",
100
+ "description": "Keyboard focus indicator is visible",
101
+ "examples": [
102
+ "Never use outline: none without replacement",
103
+ "Focus rings should be 2px minimum",
104
+ "High contrast focus indicators",
105
+ "Use :focus-visible for modern browsers"
106
+ ],
107
+ "code_checks": [
108
+ "All interactive elements show focus state",
109
+ "Focus indicator has 3:1 contrast ratio"
110
+ ]
111
+ },
112
+ {
113
+ "id": "2.5.5",
114
+ "name": "Target Size",
115
+ "level": "AAA",
116
+ "description": "Touch targets are at least 44x44 CSS pixels",
117
+ "examples": [
118
+ "Buttons should be minimum 44x44px",
119
+ "Add padding to increase clickable area",
120
+ "Ensure adequate spacing between targets"
121
+ ]
122
+ }
123
+ ]
124
+ },
125
+ "understandable": {
126
+ "name": "Understandable",
127
+ "description": "Information and operation of user interface must be understandable",
128
+ "guidelines": [
129
+ {
130
+ "id": "3.2.1",
131
+ "name": "On Focus",
132
+ "level": "A",
133
+ "description": "Focus does not trigger unexpected context changes",
134
+ "examples": [
135
+ "Don't auto-submit forms on focus",
136
+ "Don't navigate away when element receives focus"
137
+ ]
138
+ },
139
+ {
140
+ "id": "3.3.1",
141
+ "name": "Error Identification",
142
+ "level": "A",
143
+ "description": "Errors are clearly identified and described",
144
+ "examples": [
145
+ "Form validation messages are specific",
146
+ "Error messages appear near the field",
147
+ "Use aria-invalid and aria-describedby",
148
+ "Visual indicators beyond color"
149
+ ]
150
+ },
151
+ {
152
+ "id": "3.3.2",
153
+ "name": "Labels or Instructions",
154
+ "level": "A",
155
+ "description": "Labels or instructions provided when input required",
156
+ "examples": [
157
+ "Every form field has a label",
158
+ "Required fields are clearly marked",
159
+ "Format requirements stated upfront",
160
+ "Use aria-required or required attribute"
161
+ ]
162
+ }
163
+ ]
164
+ },
165
+ "robust": {
166
+ "name": "Robust",
167
+ "description": "Content must be robust enough to work with assistive technologies",
168
+ "guidelines": [
169
+ {
170
+ "id": "4.1.2",
171
+ "name": "Name, Role, Value",
172
+ "level": "A",
173
+ "description": "All UI components have accessible name and role",
174
+ "examples": [
175
+ "Use semantic HTML elements",
176
+ "ARIA roles when semantic HTML insufficient",
177
+ "aria-label or aria-labelledby for names",
178
+ "State changes announced (aria-expanded, aria-pressed)"
179
+ ],
180
+ "code_checks": [
181
+ "Custom components have role attribute",
182
+ "Interactive elements have accessible names",
183
+ "State changes update ARIA attributes"
184
+ ]
185
+ }
186
+ ]
187
+ }
188
+ },
189
+ "quick_checklist": [
190
+ "All images have alt text",
191
+ "Color is not the only visual means of conveying information",
192
+ "Text has sufficient contrast (4.5:1 minimum)",
193
+ "All functionality available via keyboard",
194
+ "Focus indicators are visible",
195
+ "Form inputs have labels",
196
+ "Error messages are clear and specific",
197
+ "Page has proper heading structure",
198
+ "Links have descriptive text (no 'click here')",
199
+ "Content is organized with semantic HTML"
200
+ ]
201
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@elsahafy/ux-mcp-server",
3
+ "version": "2.0.0",
4
+ "description": "Model Context Protocol server for UX best practices, accessibility guidelines (WCAG), usability heuristics (Nielsen), UI patterns, and design systems",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "ux-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "knowledge",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "watch": "tsc --watch",
18
+ "dev": "tsc && node dist/index.js",
19
+ "prepare": "npm run build",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "ux",
26
+ "user-experience",
27
+ "accessibility",
28
+ "a11y",
29
+ "wcag",
30
+ "wcag-aa",
31
+ "design-systems",
32
+ "design-tokens",
33
+ "usability",
34
+ "nielsen-heuristics",
35
+ "ui-patterns",
36
+ "accessible",
37
+ "frontend",
38
+ "web-design",
39
+ "claude",
40
+ "ai-tools"
41
+ ],
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/elsahafy/ux-mcp-server.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/elsahafy/ux-mcp-server/issues"
48
+ },
49
+ "homepage": "https://github.com/elsahafy/ux-mcp-server#readme",
50
+ "author": "Ibrahim Elsahafy",
51
+ "license": "MIT",
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "dependencies": {
56
+ "@modelcontextprotocol/sdk": "^1.0.4"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^22.10.2",
60
+ "typescript": "^5.7.2"
61
+ }
62
+ }