@ehrocks/fe-mcp-server 1.0.6 → 1.0.7
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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +42 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ An MCP server for searching Hero Design System components.
|
|
|
22
22
|
## Troubleshooting
|
|
23
23
|
- MCP connection gets `Client closed` error: *Ensure that Node.js is accessible globally.* Example: If you're using `asdf`, you can set the default Node.js version with:
|
|
24
24
|
```
|
|
25
|
-
asdf set -u nodejs
|
|
25
|
+
asdf set -u nodejs 22.22.0
|
|
26
26
|
```
|
|
27
27
|
- Connect error or timeout: Because our MCP service is deployed to Employment Hero staging cluster, ensure you have the connection via VPN. [Read more](https://employmenthero.atlassian.net/wiki/spaces/PLAT/pages/1648525859/VPN+-+Internal+services+and+sandbox+accessibility)
|
|
28
28
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
|
-
const
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const { version } = require("../package.json");
|
|
8
|
+
const HERO_DESIGN_COMPONENT_EXAMPLES_HOST = process.env.ENVIRONMENT === "LOCAL"
|
|
9
|
+
? "http://localhost:8000"
|
|
10
|
+
: "https://fe-mcp-service.staging.ehrocks.com";
|
|
6
11
|
export const searchHeroDesignComponentExamples = async (query, limit = 5, threshold = 0.4) => {
|
|
7
12
|
try {
|
|
8
13
|
const response = await fetch(`${HERO_DESIGN_COMPONENT_EXAMPLES_HOST}/retrieve_hero_design`, {
|
|
9
|
-
method:
|
|
14
|
+
method: "POST",
|
|
10
15
|
headers: {
|
|
11
|
-
|
|
16
|
+
"Content-Type": "application/json",
|
|
12
17
|
},
|
|
13
|
-
body: JSON.stringify({ query, limit, threshold })
|
|
18
|
+
body: JSON.stringify({ query, limit, threshold }),
|
|
14
19
|
});
|
|
15
20
|
if (!response.ok) {
|
|
16
21
|
throw new Error(`HTTP error status: ${response.status}`);
|
|
17
22
|
}
|
|
18
23
|
const examples = await response.json();
|
|
19
24
|
if (!examples.length) {
|
|
20
|
-
return [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: "I couldn't find any relevant component examples for your query.",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
24
31
|
}
|
|
25
32
|
const responseParts = [];
|
|
26
33
|
examples.forEach((example, index) => {
|
|
@@ -40,59 +47,46 @@ export const searchHeroDesignComponentExamples = async (query, limit = 5, thresh
|
|
|
40
47
|
if (example.matched_embedding_type) {
|
|
41
48
|
responseParts.push(`\nMatched Embedding Type: ${example.matched_embedding_type}`);
|
|
42
49
|
}
|
|
43
|
-
responseParts.push(
|
|
50
|
+
responseParts.push("\n" + "=".repeat(80) + "\n");
|
|
44
51
|
});
|
|
45
|
-
return [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: "Here are the most relevant component examples I found:\n" +
|
|
56
|
+
responseParts.join("\n"),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
49
59
|
}
|
|
50
60
|
catch (error) {
|
|
51
|
-
return [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: `An error occurred while processing your request: ${error}`,
|
|
65
|
+
},
|
|
66
|
+
];
|
|
55
67
|
}
|
|
56
68
|
};
|
|
57
69
|
async function startServer() {
|
|
58
|
-
const server = new McpServer({
|
|
59
|
-
|
|
60
|
-
version: "1.0.0"
|
|
70
|
+
const server = new McpServer({ name: "hero-design-mcp-server", version }, {
|
|
71
|
+
instructions: "Invoke for any @hero-design/react implementation task: selecting the right component for a UI need, retrieving JSX code examples, or exploring design patterns and design system resources.",
|
|
61
72
|
});
|
|
62
|
-
server.tool("search_hero_design_component_examples", `
|
|
63
|
-
|
|
64
|
-
This tool performs semantic search across multiple specialized collections to find the most relevant component examples based on your query. The search covers:
|
|
73
|
+
server.tool("search_hero_design_component_examples", `Retrieve Hero Design System examples, patterns, and references using natural language.
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
2. Code Examples: Specifically searches through code implementations and syntax
|
|
68
|
-
3. Component Descriptions: Focuses on component usage descriptions and explanations
|
|
69
|
-
4. Purpose & Use Cases: Matches queries about component purposes and intended use cases
|
|
70
|
-
5. Technical Details: Searches through technical implementation details and specifications
|
|
71
|
-
6. Props & Configuration: Finds examples based on prop usage and configuration options
|
|
72
|
-
7. Design Patterns: Matches React patterns and best practices demonstrated in examples
|
|
73
|
-
8. Use Case Scenarios: Searches through real-world application scenarios
|
|
75
|
+
Describe the UI behavior, component, or pattern you need. Covers component selection guidance, JSX code examples, design patterns, and use cases across @hero-design/react. Not a prop API reference — use the component library docs for precise prop signatures.
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
- Find examples of specific components (e.g., "Button with icon")
|
|
77
|
-
- Search for implementation patterns (e.g., "how to handle form validation")
|
|
78
|
-
- Look up prop usage (e.g., "Button with custom colors")
|
|
79
|
-
- Find examples of specific features (e.g., "dropdown with search")
|
|
80
|
-
- Search for specific use cases (e.g., "loading state in forms")
|
|
81
|
-
- Find technical implementations (e.g., "async data loading pattern")
|
|
77
|
+
Common queries: button loading state, form validation error, dropdown with search, empty state, date picker range, modal confirmation dialog, toast notification.
|
|
82
78
|
|
|
83
|
-
|
|
84
|
-
- Component name and
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
- Props and configuration details
|
|
89
|
-
- Design patterns and best practices`, {
|
|
79
|
+
Returns for each match:
|
|
80
|
+
- Component name and similarity score
|
|
81
|
+
- Component and example descriptions
|
|
82
|
+
- Code example (JSX)
|
|
83
|
+
- Technical details, design patterns, and props context when available`, {
|
|
90
84
|
query: z
|
|
91
85
|
.string()
|
|
92
86
|
.describe("The search query describing what you're looking for in the component examples. Be specific about what aspects you're interested in (code, usage, props, patterns, etc.)"),
|
|
93
87
|
limit: z
|
|
94
88
|
.string()
|
|
95
|
-
.transform(val => {
|
|
89
|
+
.transform((val) => {
|
|
96
90
|
const num = Number(val);
|
|
97
91
|
if (isNaN(num) || num <= 0)
|
|
98
92
|
return 5;
|
|
@@ -103,7 +97,7 @@ The tool will return the most relevant examples, including:
|
|
|
103
97
|
.describe("Maximum number of distinct component examples to return"),
|
|
104
98
|
threshold: z
|
|
105
99
|
.string()
|
|
106
|
-
.transform(val => {
|
|
100
|
+
.transform((val) => {
|
|
107
101
|
const num = parseFloat(val);
|
|
108
102
|
if (isNaN(num) || num <= 0)
|
|
109
103
|
return 0.4;
|
|
@@ -111,7 +105,7 @@ The tool will return the most relevant examples, including:
|
|
|
111
105
|
})
|
|
112
106
|
.optional()
|
|
113
107
|
.default("0.4")
|
|
114
|
-
.describe("Minimum similarity score (0.0 to 1.0) for returned examples. Lower values return more results but might be less relevant")
|
|
108
|
+
.describe("Minimum similarity score (0.0 to 1.0) for returned examples. Lower values return more results but might be less relevant"),
|
|
115
109
|
}, async ({ query, limit, threshold }) => {
|
|
116
110
|
const content = await searchHeroDesignComponentExamples(query, limit, threshold);
|
|
117
111
|
return { content };
|