modality-mcp-kit 1.3.0 → 1.3.2
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/FastHonoMcp.js
CHANGED
|
@@ -24,11 +24,13 @@
|
|
|
24
24
|
* https://modelcontextprotocol.io/specification/2025-11-25/schema
|
|
25
25
|
*/
|
|
26
26
|
import { ModalityFastMCP } from "./util_mcp_tools_converter.js";
|
|
27
|
+
import { createMcpConnectionDemoHandler } from "./util_mcp_connection_demo.js";
|
|
27
28
|
import { JSONRPCManager, getLoggerInstance, } from "modality-kit";
|
|
28
29
|
import { sseNotification, sseError, SSE_HEADERS, createSSEStream, } from "./sse-wrapper.js";
|
|
29
30
|
import { McpSessionManager } from "./McpSessionManager.js";
|
|
30
31
|
import { handleToolCall } from "./handlers/tools-call-handler.js";
|
|
31
32
|
const defaultMcpPath = "/mcp";
|
|
33
|
+
const defaultMcpDemoPath = "/";
|
|
32
34
|
const mcpSchemaVersion = "2025-11-25";
|
|
33
35
|
// Initialize FastMCP instance for internal use (NO SERVER)
|
|
34
36
|
export class FastHonoMcp extends ModalityFastMCP {
|
|
@@ -41,6 +43,20 @@ export class FastHonoMcp extends ModalityFastMCP {
|
|
|
41
43
|
super();
|
|
42
44
|
this.config = config;
|
|
43
45
|
}
|
|
46
|
+
initHono(app) {
|
|
47
|
+
const { name, version, helloWorld, mcpPath = defaultMcpPath, mcpDemoPath = defaultMcpDemoPath, } = this.config;
|
|
48
|
+
this.mcpPath = mcpPath;
|
|
49
|
+
const middlewareHandler = this.handler();
|
|
50
|
+
app.use(mcpPath, middlewareHandler);
|
|
51
|
+
app.use(`${mcpPath}/*`, middlewareHandler);
|
|
52
|
+
app.get(mcpDemoPath, createMcpConnectionDemoHandler({
|
|
53
|
+
serverName: name,
|
|
54
|
+
serverVersion: version,
|
|
55
|
+
mcpPath,
|
|
56
|
+
helloWorld,
|
|
57
|
+
}));
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
44
60
|
/**
|
|
45
61
|
* Disconnect and cleanup a session
|
|
46
62
|
*/
|
|
@@ -125,13 +141,6 @@ export class FastHonoMcp extends ModalityFastMCP {
|
|
|
125
141
|
}
|
|
126
142
|
};
|
|
127
143
|
}
|
|
128
|
-
initHono(app, path = defaultMcpPath) {
|
|
129
|
-
this.mcpPath = path;
|
|
130
|
-
const middlewareHandler = this.handler();
|
|
131
|
-
app.use(path, middlewareHandler);
|
|
132
|
-
app.use(`${path}/*`, middlewareHandler);
|
|
133
|
-
return this;
|
|
134
|
-
}
|
|
135
144
|
}
|
|
136
145
|
class HonoJSONRPCManager extends JSONRPCManager {
|
|
137
146
|
async sendMessage(message) {
|
package/dist/index.js
CHANGED
|
@@ -30,14 +30,18 @@ import { McpSessionManager } from "./McpSessionManager.js";
|
|
|
30
30
|
export interface FastHonoMcpConfig extends Record<string, unknown> {
|
|
31
31
|
name: string;
|
|
32
32
|
version: string;
|
|
33
|
+
mcpPath?: string;
|
|
34
|
+
mcpDemoPath?: string;
|
|
35
|
+
helloWorld?: string;
|
|
33
36
|
}
|
|
34
37
|
export declare class FastHonoMcp extends ModalityFastMCP {
|
|
35
38
|
logger: ReturnType<typeof getLoggerInstance>;
|
|
36
39
|
config: FastHonoMcpConfig;
|
|
37
40
|
sessions: McpSessionManager;
|
|
38
41
|
private currentSessionId;
|
|
39
|
-
|
|
42
|
+
mcpPath: string;
|
|
40
43
|
constructor(config: FastHonoMcpConfig);
|
|
44
|
+
initHono(app: Hono): this;
|
|
41
45
|
/**
|
|
42
46
|
* Disconnect and cleanup a session
|
|
43
47
|
*/
|
|
@@ -47,5 +51,4 @@ export declare class FastHonoMcp extends ModalityFastMCP {
|
|
|
47
51
|
*/
|
|
48
52
|
private ensureSession;
|
|
49
53
|
handler(): MiddlewareHandler;
|
|
50
|
-
initHono(app: Hono, path?: string): this;
|
|
51
54
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { setupAITools, ModalityFastMCP } from "./util_mcp_tools_converter";
|
|
|
3
3
|
export type { AITools, AITool, FastMCPTool, } from "./schemas/schemas_tool_config";
|
|
4
4
|
export type { FastMCPCompatible, BasePrompt, } from "./util_mcp_tools_converter";
|
|
5
5
|
export { FastHonoMcp } from "./FastHonoMcp";
|
|
6
|
+
export { mcpProxyHandler, mcpProxyListHandler, mcpProxyCacheHandler, type McpProxyConfig, } from "./util_mcp_proxy";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Connection Demo Handler
|
|
3
|
+
*
|
|
4
|
+
* Provides an interactive demonstration page for MCP connection patterns
|
|
5
|
+
* with examples showing how to connect various AI tools and development utilities.
|
|
6
|
+
*
|
|
7
|
+
* Usage: /mcp-demo - returns MCP connection demo documentation and tool showcase
|
|
8
|
+
*/
|
|
9
|
+
interface MCPConnectionConfig {
|
|
10
|
+
serverName: string;
|
|
11
|
+
serverVersion?: string;
|
|
12
|
+
serverUrl?: string;
|
|
13
|
+
mcpPath?: string;
|
|
14
|
+
defaultFormat?: "json" | "markdown" | "html";
|
|
15
|
+
helloWorld?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create MCP connection demo handler with server configuration
|
|
19
|
+
* @param config - Server name and version for consistency
|
|
20
|
+
* @returns Hono handler function
|
|
21
|
+
*/
|
|
22
|
+
export declare const createMcpConnectionDemoHandler: (config: MCPConnectionConfig) => (c: any) => Promise<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Hono handler for MCP connection demo
|
|
25
|
+
* Returns documentation and tool showcase data
|
|
26
|
+
* @param c - Hono context
|
|
27
|
+
* @param config - Optional server configuration
|
|
28
|
+
* @returns Demo page with connection information
|
|
29
|
+
*/
|
|
30
|
+
export declare const mcpConnectionDemoHandler: (c: any, config?: MCPConnectionConfig) => Promise<any>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Connection Demo Handler
|
|
3
|
+
*
|
|
4
|
+
* Provides an interactive demonstration page for MCP connection patterns
|
|
5
|
+
* with examples showing how to connect various AI tools and development utilities.
|
|
6
|
+
*
|
|
7
|
+
* Usage: /mcp-demo - returns MCP connection demo documentation and tool showcase
|
|
8
|
+
*/
|
|
9
|
+
const defaultOutputFormat = "html";
|
|
10
|
+
const connectAIShowcase = (serverName, serverUrl, mcpPath = "/mcp") => ({
|
|
11
|
+
claudeCode: {
|
|
12
|
+
name: "Claude Code",
|
|
13
|
+
description: "Official Claude IDE tool for seamless development workflow",
|
|
14
|
+
connectionCode: `claude mcp add -s user --transport http ${serverName} ${serverUrl}${mcpPath}`,
|
|
15
|
+
type: "editor",
|
|
16
|
+
},
|
|
17
|
+
githubCli: {
|
|
18
|
+
name: "GitHub CLI",
|
|
19
|
+
description: "Command-line tool with MCP support for GitHub operations",
|
|
20
|
+
connectionCode: `vim ~/.copilot/mcp-config.json
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"${serverName}": {
|
|
25
|
+
"type": "http",
|
|
26
|
+
"url": "${serverUrl}${mcpPath}",
|
|
27
|
+
"headers": {},
|
|
28
|
+
"tools": ["*"]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}`,
|
|
32
|
+
type: "terminal",
|
|
33
|
+
},
|
|
34
|
+
vscode: {
|
|
35
|
+
name: "VS Code",
|
|
36
|
+
description: "Popular code editor with MCP extension support",
|
|
37
|
+
connectionCode: `code --add-mcp '{"name":"${serverName}", "url": "${serverUrl}${mcpPath}", "type": "http"}'`,
|
|
38
|
+
type: "editor",
|
|
39
|
+
},
|
|
40
|
+
mytyAi: {
|
|
41
|
+
name: "Myty AI",
|
|
42
|
+
description: "AI assistant platform with comprehensive MCP capabilities",
|
|
43
|
+
connectionCode: `{
|
|
44
|
+
"mcpServers": {
|
|
45
|
+
"${serverName}": {
|
|
46
|
+
"command": "npx",
|
|
47
|
+
"args": [
|
|
48
|
+
"mcp-remote",
|
|
49
|
+
"${serverUrl}${mcpPath}"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}`,
|
|
54
|
+
type: "platform",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
// ============================================
|
|
58
|
+
// DEMO CONTENT - MARKDOWN-BASED
|
|
59
|
+
// ============================================
|
|
60
|
+
const generateDemoDocumentation = (serverName, serverUrl, mcpPath = "/mcp", helloWorld) => {
|
|
61
|
+
const tools = connectAIShowcase(serverName, serverUrl, mcpPath);
|
|
62
|
+
return `# MCP Connection Guide
|
|
63
|
+
|
|
64
|
+
${helloWorld ? `## Hello Prompt\n\n${helloWorld}\n` : ""}## How to Connect
|
|
65
|
+
|
|
66
|
+
1. Copy the connection code for your tool
|
|
67
|
+
2. Add it to your MCP configuration
|
|
68
|
+
3. Establish the session
|
|
69
|
+
|
|
70
|
+
## Connection Codes
|
|
71
|
+
|
|
72
|
+
${Object.entries(tools)
|
|
73
|
+
.map(([, tool]) => `### ${tool.name}
|
|
74
|
+
\`\`\`
|
|
75
|
+
${tool.connectionCode}
|
|
76
|
+
\`\`\``)
|
|
77
|
+
.join("\n\n")}
|
|
78
|
+
`;
|
|
79
|
+
};
|
|
80
|
+
// ============================================
|
|
81
|
+
// HONO HANDLER
|
|
82
|
+
// ============================================
|
|
83
|
+
/**
|
|
84
|
+
* Create MCP connection demo handler with server configuration
|
|
85
|
+
* @param config - Server name and version for consistency
|
|
86
|
+
* @returns Hono handler function
|
|
87
|
+
*/
|
|
88
|
+
export const createMcpConnectionDemoHandler = (config) => {
|
|
89
|
+
return async (c) => {
|
|
90
|
+
return mcpConnectionDemoHandler(c, config);
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Hono handler for MCP connection demo
|
|
95
|
+
* Returns documentation and tool showcase data
|
|
96
|
+
* @param c - Hono context
|
|
97
|
+
* @param config - Optional server configuration
|
|
98
|
+
* @returns Demo page with connection information
|
|
99
|
+
*/
|
|
100
|
+
export const mcpConnectionDemoHandler = async (c, config) => {
|
|
101
|
+
const format = c.req.query("format") || config?.defaultFormat || defaultOutputFormat;
|
|
102
|
+
const serverName = config?.serverName || "mcp-server";
|
|
103
|
+
const mcpPath = config?.mcpPath || "/mcp";
|
|
104
|
+
// Get server URL: from config first, then extract from request
|
|
105
|
+
let serverUrl = "";
|
|
106
|
+
if (!config?.serverUrl && c.req.url) {
|
|
107
|
+
try {
|
|
108
|
+
const url = new URL(c.req.url);
|
|
109
|
+
serverUrl = `${url.protocol}//${url.host}`;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Fallback to default if URL parsing fails
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else if (config?.serverUrl) {
|
|
116
|
+
serverUrl = config?.serverUrl;
|
|
117
|
+
}
|
|
118
|
+
const tools = connectAIShowcase(serverName, serverUrl, mcpPath);
|
|
119
|
+
const documentation = generateDemoDocumentation(serverName, serverUrl, mcpPath, config?.helloWorld);
|
|
120
|
+
// Handle different format requests
|
|
121
|
+
if (format === "markdown" || format === "md") {
|
|
122
|
+
return new Response(documentation, {
|
|
123
|
+
status: 200,
|
|
124
|
+
headers: {
|
|
125
|
+
"Content-Type": "text/markdown; charset=utf-8",
|
|
126
|
+
"Cache-Control": "public, max-age=3600",
|
|
127
|
+
"Access-Control-Allow-Origin": "*",
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (format === "html") {
|
|
132
|
+
const htmlContent = generateHtmlPage(serverUrl, config, tools, mcpPath);
|
|
133
|
+
return new Response(htmlContent, {
|
|
134
|
+
status: 200,
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
137
|
+
"Cache-Control": "public, max-age=3600",
|
|
138
|
+
"Access-Control-Allow-Origin": "*",
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Default: JSON format with complete data
|
|
143
|
+
const demoData = {
|
|
144
|
+
documentation,
|
|
145
|
+
tools: Object.entries(tools).map(([key, tool]) => ({
|
|
146
|
+
id: key,
|
|
147
|
+
...tool,
|
|
148
|
+
})),
|
|
149
|
+
server: {
|
|
150
|
+
name: serverName,
|
|
151
|
+
version: config?.serverVersion || "unknown",
|
|
152
|
+
url: serverUrl,
|
|
153
|
+
mcpPath: mcpPath,
|
|
154
|
+
},
|
|
155
|
+
metadata: {
|
|
156
|
+
toolCount: Object.keys(tools).length,
|
|
157
|
+
lastUpdated: new Date().toISOString(),
|
|
158
|
+
format: "json",
|
|
159
|
+
availableFormats: ["json", "markdown", "html"],
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
return c.json(demoData, {
|
|
163
|
+
headers: {
|
|
164
|
+
"Cache-Control": "public, max-age=3600",
|
|
165
|
+
"Access-Control-Allow-Origin": "*",
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
// ============================================
|
|
170
|
+
// HTML GENERATION
|
|
171
|
+
// ============================================
|
|
172
|
+
function escapeHtml(text) {
|
|
173
|
+
const map = {
|
|
174
|
+
"&": "&",
|
|
175
|
+
"<": "<",
|
|
176
|
+
">": ">",
|
|
177
|
+
'"': """,
|
|
178
|
+
"'": "'",
|
|
179
|
+
};
|
|
180
|
+
return text.replace(/[&<>"']/g, (char) => map[char] || char);
|
|
181
|
+
}
|
|
182
|
+
function escapeForJs(text) {
|
|
183
|
+
return text.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
184
|
+
}
|
|
185
|
+
function generateHtmlPage(serverUrl, config, tools, mcpPath = "/mcp") {
|
|
186
|
+
const toolsToDisplay = tools || connectAIShowcase(config?.serverName || "mcp-server", serverUrl, mcpPath);
|
|
187
|
+
const toolsHtml = Object.entries(toolsToDisplay)
|
|
188
|
+
.map(([, tool]) => `
|
|
189
|
+
<div class="tool-card">
|
|
190
|
+
<h3>${tool.name}</h3>
|
|
191
|
+
<p class="tool-type">${tool.type}</p>
|
|
192
|
+
<p class="tool-description">${tool.description}</p>
|
|
193
|
+
<div class="connection-section">
|
|
194
|
+
<label>Connection Code</label>
|
|
195
|
+
<pre class="code-block"><code>${escapeHtml(tool.connectionCode)}</code></pre>
|
|
196
|
+
<button class="copy-btn" onclick="copyToClipboard(\`${escapeForJs(tool.connectionCode)}\`)">
|
|
197
|
+
Copy
|
|
198
|
+
</button>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
`)
|
|
202
|
+
.join("\n");
|
|
203
|
+
return `
|
|
204
|
+
<!DOCTYPE html>
|
|
205
|
+
<html lang="en">
|
|
206
|
+
<head>
|
|
207
|
+
<meta charset="UTF-8">
|
|
208
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
209
|
+
<title>${config?.serverName || "MCP Connection Demo"}</title>
|
|
210
|
+
<style>
|
|
211
|
+
* {
|
|
212
|
+
margin: 0;
|
|
213
|
+
padding: 0;
|
|
214
|
+
box-sizing: border-box;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
body {
|
|
218
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
219
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
220
|
+
min-height: 100vh;
|
|
221
|
+
padding: 2rem;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.container {
|
|
225
|
+
max-width: 1200px;
|
|
226
|
+
margin: 0 auto;
|
|
227
|
+
background: white;
|
|
228
|
+
border-radius: 12px;
|
|
229
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
230
|
+
overflow: hidden;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
header {
|
|
234
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
235
|
+
color: white;
|
|
236
|
+
padding: 3rem 2rem;
|
|
237
|
+
text-align: center;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
header h1 {
|
|
241
|
+
font-size: 2.5rem;
|
|
242
|
+
margin-bottom: 0.5rem;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
header p {
|
|
246
|
+
font-size: 1.1rem;
|
|
247
|
+
opacity: 0.9;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.content {
|
|
251
|
+
padding: 2rem;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.intro-section {
|
|
255
|
+
margin-bottom: 3rem;
|
|
256
|
+
padding: 2rem;
|
|
257
|
+
background: #f8f9fa;
|
|
258
|
+
border-radius: 8px;
|
|
259
|
+
border-left: 4px solid #667eea;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.intro-section h2 {
|
|
263
|
+
color: #333;
|
|
264
|
+
margin-bottom: 1rem;
|
|
265
|
+
font-size: 1.5rem;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.intro-section p {
|
|
269
|
+
color: #666;
|
|
270
|
+
line-height: 1.6;
|
|
271
|
+
margin-bottom: 1rem;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.tools-section {
|
|
275
|
+
margin-top: 3rem;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.tools-section h2 {
|
|
279
|
+
color: #333;
|
|
280
|
+
margin-bottom: 2rem;
|
|
281
|
+
font-size: 1.5rem;
|
|
282
|
+
border-bottom: 2px solid #667eea;
|
|
283
|
+
padding-bottom: 1rem;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.tools-grid {
|
|
287
|
+
display: grid;
|
|
288
|
+
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
289
|
+
gap: 2rem;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.tool-card {
|
|
293
|
+
border: 1px solid #e0e0e0;
|
|
294
|
+
border-radius: 8px;
|
|
295
|
+
padding: 1.5rem;
|
|
296
|
+
transition: all 0.3s ease;
|
|
297
|
+
background: white;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.tool-card:hover {
|
|
301
|
+
border-color: #667eea;
|
|
302
|
+
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
|
|
303
|
+
transform: translateY(-2px);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.tool-card h3 {
|
|
307
|
+
color: #333;
|
|
308
|
+
margin-bottom: 0.5rem;
|
|
309
|
+
font-size: 1.3rem;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.tool-type {
|
|
313
|
+
display: inline-block;
|
|
314
|
+
background: #667eea;
|
|
315
|
+
color: white;
|
|
316
|
+
padding: 0.25rem 0.75rem;
|
|
317
|
+
border-radius: 20px;
|
|
318
|
+
font-size: 0.75rem;
|
|
319
|
+
font-weight: 600;
|
|
320
|
+
text-transform: uppercase;
|
|
321
|
+
margin-bottom: 1rem;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.tool-description {
|
|
325
|
+
color: #666;
|
|
326
|
+
margin-bottom: 1.5rem;
|
|
327
|
+
line-height: 1.6;
|
|
328
|
+
font-size: 0.95rem;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.connection-section {
|
|
332
|
+
margin-top: 1rem;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.connection-section label {
|
|
336
|
+
display: block;
|
|
337
|
+
color: #333;
|
|
338
|
+
font-weight: 600;
|
|
339
|
+
margin-bottom: 0.5rem;
|
|
340
|
+
font-size: 0.9rem;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.url-container {
|
|
344
|
+
display: flex;
|
|
345
|
+
gap: 0.5rem;
|
|
346
|
+
align-items: center;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
code {
|
|
350
|
+
background: transparent;
|
|
351
|
+
padding: 0;
|
|
352
|
+
border: none;
|
|
353
|
+
color: #333;
|
|
354
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
355
|
+
font-size: 0.85rem;
|
|
356
|
+
word-break: break-all;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.code-block {
|
|
360
|
+
background: #f5f5f5;
|
|
361
|
+
padding: 1rem;
|
|
362
|
+
border-radius: 4px;
|
|
363
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
364
|
+
font-size: 0.85rem;
|
|
365
|
+
color: #333;
|
|
366
|
+
border: 1px solid #e0e0e0;
|
|
367
|
+
overflow-x: auto;
|
|
368
|
+
margin: 0.5rem 0 1rem 0;
|
|
369
|
+
white-space: pre-wrap;
|
|
370
|
+
word-wrap: break-word;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.copy-btn {
|
|
374
|
+
background: #667eea;
|
|
375
|
+
color: white;
|
|
376
|
+
border: none;
|
|
377
|
+
padding: 0.5rem 1rem;
|
|
378
|
+
border-radius: 4px;
|
|
379
|
+
cursor: pointer;
|
|
380
|
+
font-weight: 600;
|
|
381
|
+
font-size: 0.85rem;
|
|
382
|
+
transition: background 0.2s ease;
|
|
383
|
+
white-space: nowrap;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.copy-btn:hover {
|
|
387
|
+
background: #764ba2;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.copy-btn:active {
|
|
391
|
+
transform: scale(0.98);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
footer {
|
|
395
|
+
background: #f8f9fa;
|
|
396
|
+
padding: 2rem;
|
|
397
|
+
text-align: center;
|
|
398
|
+
color: #666;
|
|
399
|
+
border-top: 1px solid #e0e0e0;
|
|
400
|
+
font-size: 0.9rem;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
@media (max-width: 768px) {
|
|
404
|
+
header h1 {
|
|
405
|
+
font-size: 1.8rem;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.tools-grid {
|
|
409
|
+
grid-template-columns: 1fr;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.content {
|
|
413
|
+
padding: 1rem;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.url-container {
|
|
417
|
+
flex-direction: column;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.copy-btn {
|
|
421
|
+
width: 100%;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
</style>
|
|
425
|
+
</head>
|
|
426
|
+
<body>
|
|
427
|
+
<div class="container">
|
|
428
|
+
<header>
|
|
429
|
+
<h1>🌐 ${config?.serverName || "MCP Connection Demo"}</h1>
|
|
430
|
+
<p>Interactive guide for connecting AI tools and development utilities</p>
|
|
431
|
+
${config
|
|
432
|
+
? `<p style="font-size: 0.95rem; margin-top: 1rem; opacity: 0.8;">Server: <strong>${config.serverName}</strong> v${config.serverVersion || "unknown"}</p>`
|
|
433
|
+
: ""}
|
|
434
|
+
</header>
|
|
435
|
+
|
|
436
|
+
<div class="content">
|
|
437
|
+
${config?.helloWorld
|
|
438
|
+
? `<div class="intro-section">
|
|
439
|
+
<h2>Hello Prompt</h2>
|
|
440
|
+
<p>${config.helloWorld}</p>
|
|
441
|
+
</div>`
|
|
442
|
+
: `<div class="intro-section">
|
|
443
|
+
<h2>Welcome to MCP</h2>
|
|
444
|
+
<p>
|
|
445
|
+
The Model Context Protocol (MCP) provides a standardized way for AI tools
|
|
446
|
+
and development utilities to exchange information and capabilities.
|
|
447
|
+
</p>
|
|
448
|
+
<p>
|
|
449
|
+
Below you'll find connection URLs for popular tools. Copy the URL for your
|
|
450
|
+
tool and add it to your MCP configuration.
|
|
451
|
+
</p>
|
|
452
|
+
</div>`}
|
|
453
|
+
|
|
454
|
+
<div class="tools-section">
|
|
455
|
+
<h2>Connect your AI assistant</h2>
|
|
456
|
+
<div class="tools-grid">
|
|
457
|
+
${toolsHtml}
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
|
|
462
|
+
<footer>
|
|
463
|
+
<p>${config?.serverName || "MCP Connection Demo"} © 2026 | Last updated: ${new Date().toLocaleDateString()}</p>
|
|
464
|
+
${config
|
|
465
|
+
? `<p>Server: <strong>${config.serverName}</strong> | URL: <code>${serverUrl}</code></p>`
|
|
466
|
+
: ""}
|
|
467
|
+
</footer>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<script>
|
|
471
|
+
function copyToClipboard(text) {
|
|
472
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
473
|
+
const btn = event.target;
|
|
474
|
+
const originalText = btn.textContent;
|
|
475
|
+
btn.textContent = '✓ Copied!';
|
|
476
|
+
setTimeout(() => {
|
|
477
|
+
btn.textContent = originalText;
|
|
478
|
+
}, 2000);
|
|
479
|
+
}).catch(err => {
|
|
480
|
+
console.error('Failed to copy:', err);
|
|
481
|
+
alert('Failed to copy to clipboard');
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Log page load performance
|
|
486
|
+
window.addEventListener('load', () => {
|
|
487
|
+
const perfData = performance.getEntriesByType('navigation')[0];
|
|
488
|
+
if (perfData) {
|
|
489
|
+
console.log('Page Load Time:', perfData.loadEventEnd - perfData.fetchStart, 'ms');
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
</script>
|
|
493
|
+
</body>
|
|
494
|
+
</html>
|
|
495
|
+
`.trim();
|
|
496
|
+
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.2",
|
|
3
3
|
"name": "modality-mcp-kit",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"license": "ISC",
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"zod": "^4.3.5",
|
|
26
|
-
"hono": "
|
|
26
|
+
"hono": "^4.11.3"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@valibot/to-json-schema": "^1.5.0",
|