gem-context-server 0.0.4 → 0.0.5
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.js +188 -0
- package/dist/index.js.map +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
26
|
+
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
27
|
+
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
28
|
+
var import_adm_zip = __toESM(require("adm-zip"));
|
|
29
|
+
var import_dedent = __toESM(require("dedent"));
|
|
30
|
+
var import_zod = require("zod");
|
|
31
|
+
async function downloadDocs() {
|
|
32
|
+
const res = await fetch("https://github.com/mantou132/gem/archive/refs/heads/main.zip");
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw new Error(`Failed to download docs: ${res.status} ${res.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
const buf = await res.arrayBuffer();
|
|
37
|
+
const zip = new import_adm_zip.default(Buffer.from(buf));
|
|
38
|
+
const zipEntries = zip.getEntries();
|
|
39
|
+
return zipEntries.filter((entry) => entry.entryName.includes("packages/gem/docs/en") && entry.entryName.endsWith(".md")).map((e) => ({
|
|
40
|
+
entryName: e.entryName,
|
|
41
|
+
name: e.entryName.split("/").pop()?.replace(".md", "") || e.entryName,
|
|
42
|
+
content: zip.readAsText(e)
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
var docsCache;
|
|
46
|
+
async function getDocs() {
|
|
47
|
+
if (!docsCache) docsCache = await downloadDocs();
|
|
48
|
+
return docsCache;
|
|
49
|
+
}
|
|
50
|
+
var server = new import_mcp.McpServer({
|
|
51
|
+
name: "Gem Framework Documentation",
|
|
52
|
+
version: "1.0.0"
|
|
53
|
+
});
|
|
54
|
+
server.resource(
|
|
55
|
+
"gem-documentation",
|
|
56
|
+
"docs://gem/all",
|
|
57
|
+
{
|
|
58
|
+
description: import_dedent.default`Complete documentation for the Gem framework - a lightweight, reactive web framework for building modern web applications.
|
|
59
|
+
|
|
60
|
+
This resource contains all English documentation files including:
|
|
61
|
+
- Getting Started guides
|
|
62
|
+
- Component creation and lifecycle
|
|
63
|
+
- State management patterns
|
|
64
|
+
- Routing and navigation
|
|
65
|
+
- API references
|
|
66
|
+
- Best practices and examples
|
|
67
|
+
|
|
68
|
+
Documentation is organized in markdown files covering different aspects of the framework.
|
|
69
|
+
Use the search-gem-docs tool for targeted searches within the documentation.`,
|
|
70
|
+
mimeType: "text/markdown"
|
|
71
|
+
},
|
|
72
|
+
async () => {
|
|
73
|
+
const docs = await getDocs();
|
|
74
|
+
return {
|
|
75
|
+
contents: docs.map(({ entryName, content }) => ({
|
|
76
|
+
uri: `docs://gem/${entryName}`,
|
|
77
|
+
text: content,
|
|
78
|
+
mimeType: "text/markdown"
|
|
79
|
+
}))
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
server.tool(
|
|
84
|
+
"search-gem-docs",
|
|
85
|
+
"Search through Gem framework documentation by keyword. Returns relevant sections with context.",
|
|
86
|
+
{
|
|
87
|
+
query: import_zod.z.string().describe(
|
|
88
|
+
'Search query to find relevant documentation. Examples: "component", "state", "lifecycle", "router", "reactive"'
|
|
89
|
+
),
|
|
90
|
+
maxResults: import_zod.z.number().optional().default(5).describe("Maximum number of results to return (default: 5)")
|
|
91
|
+
},
|
|
92
|
+
async ({ query, maxResults = 5 }) => {
|
|
93
|
+
const docs = await getDocs();
|
|
94
|
+
const lowerQuery = query.toLowerCase();
|
|
95
|
+
const results = docs.filter(({ content, name }) => `${name} ${content}`.toLowerCase().includes(lowerQuery)).slice(0, maxResults).map(({ name, content }) => {
|
|
96
|
+
const lines = content.split("\n");
|
|
97
|
+
const matchedIndices = [];
|
|
98
|
+
lines.forEach((line, index) => {
|
|
99
|
+
if (line.toLowerCase().includes(lowerQuery)) {
|
|
100
|
+
matchedIndices.push(index);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const contextLines = /* @__PURE__ */ new Set();
|
|
104
|
+
matchedIndices.forEach((idx) => {
|
|
105
|
+
for (let i = Math.max(0, idx - 2); i <= Math.min(lines.length - 1, idx + 2); i++) {
|
|
106
|
+
contextLines.add(i);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const context = Array.from(contextLines).sort((a, b) => a - b).map((i) => `Line ${i + 1}: ${lines[i].trim()}`).join("\n");
|
|
110
|
+
return `## ${name}
|
|
111
|
+
${context}`;
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: "text",
|
|
117
|
+
text: results.length > 0 ? import_dedent.default`Found ${results.length} result(s) for "${query}":
|
|
118
|
+
|
|
119
|
+
${results.join("\n\n---\n\n")}` : import_dedent.default`No results found for "${query}". Try different keywords like "component", "state", "router", etc.`
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
server.prompt(
|
|
126
|
+
"gem-help",
|
|
127
|
+
"Get help understanding Gem framework concepts with documentation lookup",
|
|
128
|
+
{
|
|
129
|
+
topic: import_zod.z.string().describe(
|
|
130
|
+
'The Gem framework topic you need help with (e.g., "creating components", "state management", "routing", "lifecycle hooks")'
|
|
131
|
+
)
|
|
132
|
+
},
|
|
133
|
+
({ topic }) => ({
|
|
134
|
+
messages: [
|
|
135
|
+
{
|
|
136
|
+
role: "user",
|
|
137
|
+
content: {
|
|
138
|
+
type: "text",
|
|
139
|
+
text: import_dedent.default`I need help understanding "${topic}" in the Gem framework.
|
|
140
|
+
Please use the search-gem-docs tool to find relevant documentation and provide a comprehensive explanation with code examples if available.`
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
server.prompt("learn-gem", "Start learning the Gem framework from scratch", () => ({
|
|
147
|
+
messages: [
|
|
148
|
+
{
|
|
149
|
+
role: "user",
|
|
150
|
+
content: {
|
|
151
|
+
type: "text",
|
|
152
|
+
text: import_dedent.default`I want to learn the Gem framework. Please:
|
|
153
|
+
1. Use the search-gem-docs tool to find "getting started" documentation
|
|
154
|
+
2. Explain the core concepts and philosophy
|
|
155
|
+
3. Show me a simple example to begin with
|
|
156
|
+
4. Guide me on what to learn next`
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}));
|
|
161
|
+
server.prompt(
|
|
162
|
+
"debug-gem",
|
|
163
|
+
"Debug issues in a Gem framework application",
|
|
164
|
+
{
|
|
165
|
+
problem: import_zod.z.string().describe(
|
|
166
|
+
`Description of the problem you're facing (e.g., "component not rendering", "state not updating", "router not working")`
|
|
167
|
+
)
|
|
168
|
+
},
|
|
169
|
+
({ problem }) => ({
|
|
170
|
+
messages: [
|
|
171
|
+
{
|
|
172
|
+
role: "user",
|
|
173
|
+
content: {
|
|
174
|
+
type: "text",
|
|
175
|
+
text: import_dedent.default`I'm having an issue with my Gem framework application: ${problem}
|
|
176
|
+
|
|
177
|
+
Please use the search-gem-docs tool to find relevant documentation about this issue and suggest possible solutions or debugging steps.`
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
var transport = new import_stdio.StdioServerTransport();
|
|
184
|
+
server.connect(transport).catch((error) => {
|
|
185
|
+
console.error("Failed to start MCP server:", error);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
});
|
|
188
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport AdmZip from 'adm-zip';\nimport dedent from 'dedent';\nimport { z } from 'zod';\n\nasync function downloadDocs() {\n const res = await fetch('https://github.com/mantou132/gem/archive/refs/heads/main.zip');\n if (!res.ok) {\n throw new Error(`Failed to download docs: ${res.status} ${res.statusText}`);\n }\n const buf = await res.arrayBuffer();\n const zip = new AdmZip(Buffer.from(buf));\n const zipEntries = zip.getEntries();\n return zipEntries\n .filter((entry) => entry.entryName.includes('packages/gem/docs/en') && entry.entryName.endsWith('.md'))\n .map((e) => ({\n entryName: e.entryName,\n name: e.entryName.split('/').pop()?.replace('.md', '') || e.entryName,\n content: zip.readAsText(e),\n }));\n}\n\nlet docsCache: Awaited<ReturnType<typeof downloadDocs>> | undefined;\nasync function getDocs() {\n if (!docsCache) docsCache = await downloadDocs();\n return docsCache;\n}\n\nconst server = new McpServer({\n name: 'Gem Framework Documentation',\n version: '1.0.0',\n});\n\nserver.resource(\n 'gem-documentation',\n 'docs://gem/all',\n {\n description: dedent`Complete documentation for the Gem framework - a lightweight, reactive web framework for building modern web applications.\n\n This resource contains all English documentation files including:\n - Getting Started guides\n - Component creation and lifecycle\n - State management patterns\n - Routing and navigation\n - API references\n - Best practices and examples\n\n Documentation is organized in markdown files covering different aspects of the framework.\n Use the search-gem-docs tool for targeted searches within the documentation.`,\n mimeType: 'text/markdown',\n },\n async () => {\n const docs = await getDocs();\n return {\n contents: docs.map(({ entryName, content }) => ({\n uri: `docs://gem/${entryName}`,\n text: content,\n mimeType: 'text/markdown',\n })),\n };\n },\n);\n\nserver.tool(\n 'search-gem-docs',\n 'Search through Gem framework documentation by keyword. Returns relevant sections with context.',\n {\n query: z\n .string()\n .describe(\n 'Search query to find relevant documentation. Examples: \"component\", \"state\", \"lifecycle\", \"router\", \"reactive\"',\n ),\n maxResults: z.number().optional().default(5).describe('Maximum number of results to return (default: 5)'),\n },\n async ({ query, maxResults = 5 }) => {\n const docs = await getDocs();\n const lowerQuery = query.toLowerCase();\n\n const results = docs\n .filter(({ content, name }) => `${name} ${content}`.toLowerCase().includes(lowerQuery))\n .slice(0, maxResults)\n .map(({ name, content }) => {\n const lines = content.split('\\n');\n const matchedIndices: number[] = [];\n\n lines.forEach((line, index) => {\n if (line.toLowerCase().includes(lowerQuery)) {\n matchedIndices.push(index);\n }\n });\n\n const contextLines = new Set<number>();\n matchedIndices.forEach((idx) => {\n for (let i = Math.max(0, idx - 2); i <= Math.min(lines.length - 1, idx + 2); i++) {\n contextLines.add(i);\n }\n });\n\n const context = Array.from(contextLines)\n .sort((a, b) => a - b)\n .map((i) => `Line ${i + 1}: ${lines[i].trim()}`)\n .join('\\n');\n\n return `## ${name}\\n${context}`;\n });\n\n return {\n content: [\n {\n type: 'text',\n text:\n results.length > 0\n ? dedent`Found ${results.length} result(s) for \"${query}\":\n\n ${results.join('\\n\\n---\\n\\n')}`\n : dedent`No results found for \"${query}\". Try different keywords like \"component\", \"state\", \"router\", etc.`,\n },\n ],\n };\n },\n);\n\nserver.prompt(\n 'gem-help',\n 'Get help understanding Gem framework concepts with documentation lookup',\n {\n topic: z\n .string()\n .describe(\n 'The Gem framework topic you need help with (e.g., \"creating components\", \"state management\", \"routing\", \"lifecycle hooks\")',\n ),\n },\n ({ topic }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: dedent`I need help understanding \"${topic}\" in the Gem framework.\n Please use the search-gem-docs tool to find relevant documentation and provide a comprehensive explanation with code examples if available.`,\n },\n },\n ],\n }),\n);\n\nserver.prompt('learn-gem', 'Start learning the Gem framework from scratch', () => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: dedent`I want to learn the Gem framework. Please:\n 1. Use the search-gem-docs tool to find \"getting started\" documentation\n 2. Explain the core concepts and philosophy\n 3. Show me a simple example to begin with\n 4. Guide me on what to learn next`,\n },\n },\n ],\n}));\n\nserver.prompt(\n 'debug-gem',\n 'Debug issues in a Gem framework application',\n {\n problem: z\n .string()\n .describe(\n 'Description of the problem you\\'re facing (e.g., \"component not rendering\", \"state not updating\", \"router not working\")',\n ),\n },\n ({ problem }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: dedent`I'm having an issue with my Gem framework application: ${problem}\n\n Please use the search-gem-docs tool to find relevant documentation about this issue and suggest possible solutions or debugging steps.`,\n },\n },\n ],\n }),\n);\n\nconst transport = new StdioServerTransport();\nserver.connect(transport).catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["AdmZip", "dedent"]
|
|
7
|
+
}
|