@nitrostack/core 1.0.11 → 1.0.13
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/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +17 -0
- package/dist/auth/middleware.js.map +1 -1
- package/dist/auth/token-validation.d.ts.map +1 -1
- package/dist/auth/token-validation.js +12 -2
- package/dist/auth/token-validation.js.map +1 -1
- package/dist/core/app-decorator.d.ts +6 -0
- package/dist/core/app-decorator.d.ts.map +1 -1
- package/dist/core/app-decorator.js +5 -3
- package/dist/core/app-decorator.js.map +1 -1
- package/dist/core/builders.d.ts.map +1 -1
- package/dist/core/builders.js +14 -4
- package/dist/core/builders.js.map +1 -1
- package/dist/core/decorators.d.ts +30 -0
- package/dist/core/decorators.d.ts.map +1 -1
- package/dist/core/decorators.js +42 -4
- package/dist/core/decorators.js.map +1 -1
- package/dist/core/di/container.d.ts +18 -0
- package/dist/core/di/container.d.ts.map +1 -1
- package/dist/core/di/container.js +31 -0
- package/dist/core/di/container.js.map +1 -1
- package/dist/core/di/injectable.decorator.d.ts.map +1 -1
- package/dist/core/di/injectable.decorator.js +2 -1
- package/dist/core/di/injectable.decorator.js.map +1 -1
- package/dist/core/events/event.decorator.d.ts.map +1 -1
- package/dist/core/events/event.decorator.js +2 -1
- package/dist/core/events/event.decorator.js.map +1 -1
- package/dist/core/index.d.ts +4 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/lifecycle.d.ts +44 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +62 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/oauth-module.d.ts +76 -5
- package/dist/core/oauth-module.d.ts.map +1 -1
- package/dist/core/oauth-module.js +343 -83
- package/dist/core/oauth-module.js.map +1 -1
- package/dist/core/pipes/pipe.decorator.d.ts.map +1 -1
- package/dist/core/pipes/pipe.decorator.js +2 -1
- package/dist/core/pipes/pipe.decorator.js.map +1 -1
- package/dist/core/prompt.d.ts +0 -3
- package/dist/core/prompt.d.ts.map +1 -1
- package/dist/core/prompt.js +28 -1
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/server.d.ts +39 -26
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +222 -102
- package/dist/core/server.js.map +1 -1
- package/dist/core/transports/streamable-http.d.ts +64 -61
- package/dist/core/transports/streamable-http.d.ts.map +1 -1
- package/dist/core/transports/streamable-http.js +1591 -823
- package/dist/core/transports/streamable-http.js.map +1 -1
- package/package.json +5 -7
|
@@ -14,27 +14,40 @@
|
|
|
14
14
|
* - Protocol version header support
|
|
15
15
|
*/
|
|
16
16
|
import express from 'express';
|
|
17
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
17
18
|
import { v4 as uuidv4 } from 'uuid';
|
|
18
19
|
import { readFileSync } from 'fs';
|
|
19
20
|
import { fileURLToPath } from 'url';
|
|
20
21
|
import { dirname, join } from 'path';
|
|
22
|
+
const DEFAULT_LOGO_BASE64 = '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';
|
|
21
23
|
/**
|
|
22
|
-
* Streamable HTTP
|
|
23
|
-
*
|
|
24
|
+
* Streamable HTTP host.
|
|
25
|
+
*
|
|
26
|
+
* This class owns the Express application (CORS, origin checks, OAuth discovery
|
|
27
|
+
* routes, health, documentation page, legacy-SSE lifecycle) but delegates the
|
|
28
|
+
* actual MCP protocol handling on `/mcp` to the official
|
|
29
|
+
* `@modelcontextprotocol/sdk` `StreamableHTTPServerTransport`. That transport
|
|
30
|
+
* returns the JSON-RPC result on the POST response (or an SSE stream on the same
|
|
31
|
+
* request), which is what modern MCP clients such as Cursor expect.
|
|
24
32
|
*/
|
|
25
33
|
export class StreamableHttpTransport {
|
|
26
34
|
app;
|
|
27
35
|
server = null;
|
|
28
|
-
sessions = new Map();
|
|
29
|
-
activeStreams = new Map(); // For sessionless mode
|
|
30
|
-
messageHandler;
|
|
31
|
-
closeHandler;
|
|
32
|
-
errorHandler;
|
|
33
36
|
options;
|
|
34
|
-
sessionCleanupInterval;
|
|
35
37
|
getToolsCallback;
|
|
36
38
|
serverConfig;
|
|
37
39
|
logoBase64;
|
|
40
|
+
_routesRegistered = false;
|
|
41
|
+
mcpServerFactory;
|
|
42
|
+
legacySseHandler;
|
|
43
|
+
mcpSessions = new Map();
|
|
44
|
+
// Sessions that have been created but have not yet completed `initialize`
|
|
45
|
+
// (no session id assigned yet). Tracked separately so they count against the
|
|
46
|
+
// concurrency cap and get reaped if initialization never completes.
|
|
47
|
+
pendingSessions = new Set();
|
|
48
|
+
sessionCleanupInterval;
|
|
49
|
+
/** Grace period for a created session to finish `initialize` before it is reaped. */
|
|
50
|
+
static PENDING_SESSION_TIMEOUT_MS = 30_000;
|
|
38
51
|
constructor(options = {}) {
|
|
39
52
|
this.options = {
|
|
40
53
|
port: options.port || 3000,
|
|
@@ -42,6 +55,7 @@ export class StreamableHttpTransport {
|
|
|
42
55
|
endpoint: options.endpoint || '/mcp',
|
|
43
56
|
enableSessions: options.enableSessions === true, // Default to false for simpler clients
|
|
44
57
|
sessionTimeout: options.sessionTimeout || 30 * 60 * 1000, // 30 minutes
|
|
58
|
+
maxSessions: options.maxSessions || 1000, // Cap concurrent sessions to bound memory
|
|
45
59
|
enableCors: options.enableCors !== false, // Default to true
|
|
46
60
|
};
|
|
47
61
|
this.app = options.app || express();
|
|
@@ -53,8 +67,20 @@ export class StreamableHttpTransport {
|
|
|
53
67
|
// Load logo for documentation page
|
|
54
68
|
this.loadLogo();
|
|
55
69
|
this.setupMiddleware();
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Provide the factory used to build a configured MCP server per session.
|
|
73
|
+
* Must be called before `start()`.
|
|
74
|
+
*/
|
|
75
|
+
setMcpServerFactory(factory) {
|
|
76
|
+
this.mcpServerFactory = factory;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Fallback for clients that speak legacy HTTP+SSE on GET /mcp (no mcp-session-id).
|
|
80
|
+
* Streamable HTTP clients always begin with POST initialize instead.
|
|
81
|
+
*/
|
|
82
|
+
setLegacySseHandler(handler) {
|
|
83
|
+
this.legacySseHandler = handler;
|
|
58
84
|
}
|
|
59
85
|
/**
|
|
60
86
|
* Load logo image as base64 for embedding in documentation page
|
|
@@ -68,10 +94,14 @@ export class StreamableHttpTransport {
|
|
|
68
94
|
// 2. From dist/core/transports/streamable-http.js -> ../../../../src/assets/nitrocloud.png (if in nitrostack package)
|
|
69
95
|
// 3. From project root (user's project) -> src/assets/nitrocloud.png
|
|
70
96
|
const possiblePaths = [
|
|
71
|
-
join(__dirname, '../../../src/assets/
|
|
72
|
-
join(__dirname, '
|
|
73
|
-
join(
|
|
74
|
-
join(
|
|
97
|
+
join(__dirname, '../../../src/assets/logo.png'),
|
|
98
|
+
join(__dirname, '../../../src/assets/nitrocloud.png'),
|
|
99
|
+
join(__dirname, '../../../../src/assets/logo.png'),
|
|
100
|
+
join(__dirname, '../../../../src/assets/nitrocloud.png'),
|
|
101
|
+
join(process.cwd(), 'src/assets/logo.png'),
|
|
102
|
+
join(process.cwd(), 'src/assets/nitrocloud.png'),
|
|
103
|
+
join(process.cwd(), 'node_modules/nitrostack/src/assets/logo.png'),
|
|
104
|
+
join(process.cwd(), 'node_modules/nitrostack/src/assets/nitrocloud.png'),
|
|
75
105
|
];
|
|
76
106
|
let logoPath = null;
|
|
77
107
|
for (const path of possiblePaths) {
|
|
@@ -141,93 +171,25 @@ export class StreamableHttpTransport {
|
|
|
141
171
|
*/
|
|
142
172
|
setupRoutes() {
|
|
143
173
|
const endpoint = this.options.endpoint;
|
|
144
|
-
// IMPORTANT: Add OPTIONS
|
|
174
|
+
// IMPORTANT: Add OPTIONS handler FIRST to override Express's auto-OPTIONS
|
|
145
175
|
if (this.options.enableCors) {
|
|
146
|
-
// Main endpoint OPTIONS
|
|
147
176
|
this.app.options(endpoint, (req, res) => {
|
|
148
177
|
res.sendStatus(200);
|
|
149
178
|
});
|
|
150
|
-
// SSE endpoint OPTIONS
|
|
151
|
-
this.app.options(`${endpoint}/sse`, (req, res) => {
|
|
152
|
-
res.sendStatus(200);
|
|
153
|
-
});
|
|
154
|
-
// Message endpoint OPTIONS
|
|
155
|
-
this.app.options(`${endpoint}/message`, (req, res) => {
|
|
156
|
-
res.sendStatus(200);
|
|
157
|
-
});
|
|
158
179
|
}
|
|
159
|
-
// MCP
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.app.post(`${endpoint}/message`, async (req, res) => {
|
|
166
|
-
await this.handlePost(req, res);
|
|
167
|
-
});
|
|
168
|
-
// MCP Endpoint - GET for SSE streams (main endpoint)
|
|
169
|
-
this.app.get(endpoint, (req, res) => {
|
|
170
|
-
this.handleGet(req, res);
|
|
171
|
-
});
|
|
172
|
-
// Legacy SSE endpoint for backward compatibility with old HTTP transport clients
|
|
173
|
-
// Some clients may connect to /mcp/sse instead of /mcp
|
|
174
|
-
this.app.get(`${endpoint}/sse`, (req, res) => {
|
|
175
|
-
this.handleGet(req, res);
|
|
176
|
-
});
|
|
177
|
-
// MCP Endpoint - DELETE for session termination
|
|
178
|
-
this.app.delete(endpoint, (req, res) => {
|
|
179
|
-
this.handleDelete(req, res);
|
|
180
|
-
});
|
|
181
|
-
// Backward compatibility: /sse endpoint (alias for GET /mcp)
|
|
182
|
-
this.app.get(`${endpoint}/sse`, (req, res) => {
|
|
183
|
-
this.handleGet(req, res);
|
|
184
|
-
});
|
|
185
|
-
// Backward compatibility: /message endpoint (alias for POST /mcp)
|
|
186
|
-
this.app.post(`${endpoint}/message`, async (req, res) => {
|
|
187
|
-
// Simple message handler that doesn't require all the session/SSE logic
|
|
188
|
-
try {
|
|
189
|
-
const message = req.body;
|
|
190
|
-
if (!message || !message.jsonrpc) {
|
|
191
|
-
res.status(400).json({ error: 'Invalid JSON-RPC message' });
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
// Pass to message handler
|
|
195
|
-
if (this.messageHandler) {
|
|
196
|
-
await this.messageHandler(message);
|
|
197
|
-
}
|
|
198
|
-
res.json({ status: 'received' });
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
console.error('Error handling message:', error);
|
|
202
|
-
res.status(500).json({ error: error instanceof Error ? error.message : String(error) });
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
// Info endpoint for GET on /message
|
|
206
|
-
this.app.get(`${endpoint}/message`, (req, res) => {
|
|
207
|
-
res.json({
|
|
208
|
-
endpoint: `${endpoint}/message`,
|
|
209
|
-
method: 'POST',
|
|
210
|
-
description: 'Send JSON-RPC messages to the MCP server',
|
|
211
|
-
usage: 'POST with Content-Type: application/json',
|
|
212
|
-
example: {
|
|
213
|
-
jsonrpc: '2.0',
|
|
214
|
-
method: 'initialize',
|
|
215
|
-
params: {
|
|
216
|
-
protocolVersion: '2024-11-05',
|
|
217
|
-
capabilities: {},
|
|
218
|
-
clientInfo: { name: 'test-client', version: '1.0.0' }
|
|
219
|
-
},
|
|
220
|
-
id: 1
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
});
|
|
180
|
+
// MCP endpoint - POST (client->server messages), GET (server->client SSE
|
|
181
|
+
// stream) and DELETE (session termination) are all delegated to the official
|
|
182
|
+
// SDK Streamable HTTP transport, which owns the protocol semantics.
|
|
183
|
+
this.app.post(endpoint, (req, res) => this.handleMcpRequest(req, res));
|
|
184
|
+
this.app.get(endpoint, (req, res) => this.handleMcpRequest(req, res));
|
|
185
|
+
this.app.delete(endpoint, (req, res) => this.handleMcpRequest(req, res));
|
|
224
186
|
// Health check
|
|
225
187
|
this.app.get(`${endpoint}/health`, (req, res) => {
|
|
226
188
|
res.json({
|
|
227
189
|
status: 'ok',
|
|
228
190
|
transport: 'streamable-http',
|
|
229
191
|
version: '2025-06-18',
|
|
230
|
-
sessions: this.
|
|
192
|
+
sessions: this.mcpSessions.size,
|
|
231
193
|
uptime: process.uptime(),
|
|
232
194
|
});
|
|
233
195
|
});
|
|
@@ -260,385 +222,184 @@ export class StreamableHttpTransport {
|
|
|
260
222
|
}
|
|
261
223
|
}
|
|
262
224
|
/**
|
|
263
|
-
*
|
|
225
|
+
* Delegate an `/mcp` request (POST/GET/DELETE) to the official SDK
|
|
226
|
+
* Streamable HTTP transport. A new session (and its own MCP server instance)
|
|
227
|
+
* is created on an `initialize` POST; subsequent requests are routed by the
|
|
228
|
+
* `mcp-session-id` header.
|
|
264
229
|
*/
|
|
265
|
-
async
|
|
230
|
+
async handleMcpRequest(req, res) {
|
|
231
|
+
let createdSession;
|
|
266
232
|
try {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
});
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
session.lastActivity = Date.now();
|
|
289
|
-
}
|
|
290
|
-
// Handle different message types
|
|
291
|
-
const messageType = this.getMessageType(message);
|
|
292
|
-
if (messageType === 'notification' || messageType === 'response') {
|
|
293
|
-
// Notification or Response: Return 202 Accepted
|
|
294
|
-
if (this.messageHandler) {
|
|
295
|
-
await this.messageHandler(message);
|
|
296
|
-
}
|
|
297
|
-
res.status(202).send();
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
if (messageType === 'request') {
|
|
301
|
-
// Request: Accept header check (be lenient - if not specified, assume they want SSE)
|
|
302
|
-
const supportsSSE = !accept || accept.includes('text/event-stream') || accept.includes('*/*');
|
|
303
|
-
const supportsJSON = accept.includes('application/json');
|
|
304
|
-
// Pass to message handler
|
|
305
|
-
if (this.messageHandler) {
|
|
306
|
-
await this.messageHandler(message);
|
|
307
|
-
}
|
|
308
|
-
// For InitializeRequest, create session if enabled
|
|
309
|
-
if (this.isInitializeRequest(message)) {
|
|
310
|
-
if (this.options.enableSessions && !sessionId) {
|
|
311
|
-
const newSessionId = this.generateSessionId();
|
|
312
|
-
const session = {
|
|
313
|
-
id: newSessionId,
|
|
314
|
-
streams: new Map(),
|
|
315
|
-
lastActivity: Date.now(),
|
|
316
|
-
messageQueue: [],
|
|
317
|
-
eventIdCounter: 0,
|
|
318
|
-
};
|
|
319
|
-
this.sessions.set(newSessionId, session);
|
|
320
|
-
res.setHeader('Mcp-Session-Id', newSessionId);
|
|
233
|
+
const sessionId = req.get('mcp-session-id');
|
|
234
|
+
let session = sessionId ? this.mcpSessions.get(sessionId) : undefined;
|
|
235
|
+
if (!session) {
|
|
236
|
+
if (req.method === 'POST' && this.isInitializeRequest(req.body)) {
|
|
237
|
+
// Bound memory: reject new sessions once at capacity. This defends
|
|
238
|
+
// against unauthenticated `initialize` floods exhausting memory.
|
|
239
|
+
// Count both live and pending (not-yet-initialized) sessions so a
|
|
240
|
+
// burst of concurrent `initialize` requests cannot overshoot the cap.
|
|
241
|
+
if (this.mcpSessions.size + this.pendingSessions.size >= this.options.maxSessions) {
|
|
242
|
+
res.status(429).json({
|
|
243
|
+
jsonrpc: '2.0',
|
|
244
|
+
error: {
|
|
245
|
+
code: -32000,
|
|
246
|
+
message: 'Too many sessions: server at capacity, retry later',
|
|
247
|
+
},
|
|
248
|
+
id: null,
|
|
249
|
+
});
|
|
250
|
+
return;
|
|
321
251
|
}
|
|
252
|
+
session = await this.createSession();
|
|
253
|
+
createdSession = session;
|
|
322
254
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
|
|
255
|
+
else if (req.method === 'GET' && this.legacySseHandler) {
|
|
256
|
+
// Cursor and other legacy SSE clients open GET first; Streamable HTTP
|
|
257
|
+
// always starts with POST initialize. Delegate when a handler is wired.
|
|
258
|
+
await this.legacySseHandler(req, res);
|
|
259
|
+
return;
|
|
328
260
|
}
|
|
329
261
|
else {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
262
|
+
res.status(400).json({
|
|
263
|
+
jsonrpc: '2.0',
|
|
264
|
+
error: {
|
|
265
|
+
code: -32000,
|
|
266
|
+
message: 'Bad Request: no valid session ID provided',
|
|
267
|
+
},
|
|
268
|
+
id: null,
|
|
269
|
+
});
|
|
270
|
+
return;
|
|
335
271
|
}
|
|
336
272
|
}
|
|
273
|
+
// Refresh activity so the idle sweeper only reaps genuinely stale sessions.
|
|
274
|
+
session.lastActivity = Date.now();
|
|
275
|
+
// Cast around the SDK's expected node req/res types: Express augments
|
|
276
|
+
// Request with nitrostack's own `auth` shape which differs from the SDK's.
|
|
277
|
+
await session.transport.handleRequest(req, res, req.body);
|
|
337
278
|
}
|
|
338
279
|
catch (error) {
|
|
339
|
-
console.error('
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
280
|
+
console.error('MCP request error:', error);
|
|
281
|
+
// If we created a session for this request but handling it failed (e.g. a
|
|
282
|
+
// malformed initialize), tear it down immediately so it does not linger as
|
|
283
|
+
// an untracked/pending session until the sweeper reaps it.
|
|
284
|
+
if (createdSession && this.pendingSessions.has(createdSession)) {
|
|
285
|
+
this.destroySession(createdSession);
|
|
286
|
+
}
|
|
287
|
+
if (!res.headersSent) {
|
|
288
|
+
res.status(500).json({
|
|
289
|
+
jsonrpc: '2.0',
|
|
290
|
+
error: { code: -32603, message: 'Internal error' },
|
|
291
|
+
id: null,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
344
294
|
}
|
|
345
295
|
}
|
|
346
296
|
/**
|
|
347
|
-
*
|
|
297
|
+
* Create a new MCP session: a fresh configured MCP server connected to a new
|
|
298
|
+
* official Streamable HTTP transport. The transport registers itself in the
|
|
299
|
+
* session map once it has negotiated a session id, and removes itself on close.
|
|
348
300
|
*/
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const accept = req.get('Accept') || '';
|
|
353
|
-
// Check if client explicitly doesn't want SSE (e.g., asking for JSON only)
|
|
354
|
-
const rejectsSSE = accept && !accept.includes('*/*') && !accept.includes('text/event-stream') && accept.length > 0;
|
|
355
|
-
if (rejectsSSE) {
|
|
356
|
-
res.status(405).send('Method Not Allowed - This endpoint provides Server-Sent Events');
|
|
357
|
-
return;
|
|
301
|
+
async createSession() {
|
|
302
|
+
if (!this.mcpServerFactory) {
|
|
303
|
+
throw new Error('StreamableHttpTransport: MCP server factory not set');
|
|
358
304
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
305
|
+
const server = this.mcpServerFactory();
|
|
306
|
+
// Build the session object first so `lastActivity` is a shared, mutable
|
|
307
|
+
// reference visible to both the session map and the idle sweeper.
|
|
308
|
+
const now = Date.now();
|
|
309
|
+
const session = { server, transport: undefined, lastActivity: now, createdAt: now };
|
|
310
|
+
// Register as pending until `initialize` completes; this bounds unfinished
|
|
311
|
+
// sessions against the cap and lets the sweeper reap ones that never finish.
|
|
312
|
+
this.pendingSessions.add(session);
|
|
313
|
+
const transport = new StreamableHTTPServerTransport({
|
|
314
|
+
sessionIdGenerator: () => uuidv4(),
|
|
315
|
+
onsessioninitialized: (sid) => {
|
|
316
|
+
// Session is now live: promote from pending to the tracked map.
|
|
317
|
+
this.pendingSessions.delete(session);
|
|
318
|
+
this.mcpSessions.set(sid, session);
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
session.transport = transport;
|
|
322
|
+
transport.onclose = () => {
|
|
323
|
+
const sid = transport.sessionId;
|
|
324
|
+
if (sid) {
|
|
325
|
+
this.mcpSessions.delete(sid);
|
|
370
326
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (this.options.enableCors) {
|
|
377
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
378
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
379
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, Mcp-Session-Id, MCP-Protocol-Version, Last-Event-ID');
|
|
380
|
-
res.setHeader('Access-Control-Expose-Headers', 'Mcp-Session-Id');
|
|
381
|
-
}
|
|
382
|
-
res.setHeader('Content-Type', 'text/event-stream');
|
|
383
|
-
res.setHeader('Cache-Control', 'no-cache');
|
|
384
|
-
res.setHeader('Connection', 'keep-alive');
|
|
385
|
-
res.flushHeaders();
|
|
386
|
-
// Create stream
|
|
387
|
-
const streamId = uuidv4();
|
|
388
|
-
const stream = {
|
|
389
|
-
id: streamId,
|
|
390
|
-
response: res,
|
|
391
|
-
eventIdCounter: 0,
|
|
392
|
-
closed: false,
|
|
327
|
+
this.pendingSessions.delete(session);
|
|
328
|
+
transport.onclose = undefined;
|
|
329
|
+
server.close().catch(() => {
|
|
330
|
+
// ignore close errors
|
|
331
|
+
});
|
|
393
332
|
};
|
|
394
|
-
// Send endpoint event immediately (required by MCP SDK)
|
|
395
|
-
// This tells the client where to POST messages
|
|
396
|
-
// Support X-Forwarded-Proto for reverse proxies (production deployments)
|
|
397
|
-
// This ensures the endpoint URL matches the client's connection protocol (HTTPS)
|
|
398
|
-
const protocol = req.get('x-forwarded-proto') || req.protocol || 'http';
|
|
399
|
-
// Detect client format based on request URL:
|
|
400
|
-
// - If client connects to /mcp/sse (old format) → return /mcp/message as endpoint
|
|
401
|
-
// - If client connects to /mcp (new format) → return /mcp as endpoint
|
|
402
|
-
// Use originalUrl or url to get the full path including /sse
|
|
403
|
-
const requestPath = req.originalUrl || req.url || req.path;
|
|
404
|
-
const isOldFormat = requestPath.includes(`${this.options.endpoint}/sse`) ||
|
|
405
|
-
requestPath.endsWith('/sse') ||
|
|
406
|
-
req.path === `${this.options.endpoint}/sse`;
|
|
407
|
-
const messageEndpoint = isOldFormat
|
|
408
|
-
? `${this.options.endpoint}/message` // Old format: POST to /mcp/message
|
|
409
|
-
: this.options.endpoint; // New format: POST to /mcp
|
|
410
|
-
const endpointUrl = `${protocol}://${req.get('host')}${messageEndpoint}`;
|
|
411
333
|
try {
|
|
412
|
-
|
|
413
|
-
res.write(`data: ${endpointUrl}\n\n`);
|
|
334
|
+
await server.connect(transport);
|
|
414
335
|
}
|
|
415
336
|
catch (error) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
// Add to session or activeStreams
|
|
421
|
-
if (session) {
|
|
422
|
-
session.streams.set(streamId, stream);
|
|
423
|
-
// Resume support: replay messages after lastEventId
|
|
424
|
-
if (lastEventId) {
|
|
425
|
-
this.replayMessages(session, stream, lastEventId);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
// Sessionless mode: track in activeStreams
|
|
430
|
-
this.activeStreams.set(streamId, stream);
|
|
431
|
-
}
|
|
432
|
-
// Handle client disconnect
|
|
433
|
-
req.on('close', () => {
|
|
434
|
-
stream.closed = true;
|
|
435
|
-
if (session) {
|
|
436
|
-
session.streams.delete(streamId);
|
|
437
|
-
}
|
|
438
|
-
else {
|
|
439
|
-
this.activeStreams.delete(streamId);
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
// Send ping every 30 seconds to keep connection alive
|
|
443
|
-
const pingInterval = setInterval(() => {
|
|
444
|
-
if (stream.closed) {
|
|
445
|
-
clearInterval(pingInterval);
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
try {
|
|
449
|
-
res.write(': ping\n\n');
|
|
450
|
-
}
|
|
451
|
-
catch (error) {
|
|
452
|
-
clearInterval(pingInterval);
|
|
453
|
-
stream.closed = true;
|
|
454
|
-
}
|
|
455
|
-
}, 30000);
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Handle DELETE requests (session termination)
|
|
459
|
-
*/
|
|
460
|
-
handleDelete(req, res) {
|
|
461
|
-
const sessionId = req.get('Mcp-Session-Id');
|
|
462
|
-
if (!sessionId) {
|
|
463
|
-
res.status(400).json({ error: 'Mcp-Session-Id required' });
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
const session = this.sessions.get(sessionId);
|
|
467
|
-
if (!session) {
|
|
468
|
-
res.status(404).json({ error: 'Session not found' });
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
// Close all streams
|
|
472
|
-
for (const stream of session.streams.values()) {
|
|
473
|
-
try {
|
|
474
|
-
stream.response.end();
|
|
475
|
-
stream.closed = true;
|
|
476
|
-
}
|
|
477
|
-
catch (error) {
|
|
478
|
-
// Ignore
|
|
479
|
-
}
|
|
337
|
+
// Connect failed before the session could initialize: don't leak it.
|
|
338
|
+
this.destroySession(session);
|
|
339
|
+
throw error;
|
|
480
340
|
}
|
|
481
|
-
|
|
482
|
-
this.sessions.delete(sessionId);
|
|
483
|
-
res.status(200).json({ status: 'session terminated' });
|
|
341
|
+
return session;
|
|
484
342
|
}
|
|
485
343
|
/**
|
|
486
|
-
*
|
|
344
|
+
* Tear down a session, removing it from both the live and pending collections
|
|
345
|
+
* and closing its transport and server. Safe to call from the sweeper, request
|
|
346
|
+
* error paths, and shutdown.
|
|
487
347
|
*/
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
res.setHeader('Connection', 'keep-alive');
|
|
493
|
-
res.flushHeaders();
|
|
494
|
-
// Create stream
|
|
495
|
-
const streamId = uuidv4();
|
|
496
|
-
const stream = {
|
|
497
|
-
id: streamId,
|
|
498
|
-
response: res,
|
|
499
|
-
eventIdCounter: 0,
|
|
500
|
-
closed: false,
|
|
501
|
-
};
|
|
502
|
-
// Store stream reference for this request
|
|
503
|
-
req._mcpStreamId = streamId;
|
|
504
|
-
req._mcpStream = stream;
|
|
505
|
-
// Add to session or activeStreams
|
|
506
|
-
if (sessionId) {
|
|
507
|
-
const session = this.sessions.get(sessionId);
|
|
508
|
-
if (session) {
|
|
509
|
-
session.streams.set(streamId, stream);
|
|
510
|
-
}
|
|
348
|
+
destroySession(session) {
|
|
349
|
+
const sid = session.transport?.sessionId;
|
|
350
|
+
if (sid) {
|
|
351
|
+
this.mcpSessions.delete(sid);
|
|
511
352
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
353
|
+
this.pendingSessions.delete(session);
|
|
354
|
+
if (session.transport) {
|
|
355
|
+
session.transport.onclose = undefined;
|
|
356
|
+
session.transport.close().catch(() => {
|
|
357
|
+
// ignore close errors
|
|
358
|
+
});
|
|
515
359
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
stream.closed = true;
|
|
519
|
-
if (sessionId) {
|
|
520
|
-
const session = this.sessions.get(sessionId);
|
|
521
|
-
if (session) {
|
|
522
|
-
session.streams.delete(streamId);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
else {
|
|
526
|
-
this.activeStreams.delete(streamId);
|
|
527
|
-
}
|
|
360
|
+
session.server.close().catch(() => {
|
|
361
|
+
// ignore close errors
|
|
528
362
|
});
|
|
529
363
|
}
|
|
530
364
|
/**
|
|
531
|
-
*
|
|
365
|
+
* Periodically tear down sessions that have been idle longer than
|
|
366
|
+
* `sessionTimeout`. Prevents unbounded memory growth from clients that
|
|
367
|
+
* initialize but never disconnect or send DELETE.
|
|
532
368
|
*/
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
// For responses, send to the stream that made the request
|
|
536
|
-
if (this.isResponse(message)) {
|
|
537
|
-
const response = message;
|
|
538
|
-
await this.sendToRequestStream(response);
|
|
369
|
+
startSessionCleanup() {
|
|
370
|
+
if (this.sessionCleanupInterval) {
|
|
539
371
|
return;
|
|
540
372
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
for (const
|
|
545
|
-
if (
|
|
546
|
-
|
|
373
|
+
this.sessionCleanupInterval = setInterval(() => {
|
|
374
|
+
const now = Date.now();
|
|
375
|
+
// Reap live sessions that have been idle past the configured timeout.
|
|
376
|
+
for (const [, session] of this.mcpSessions.entries()) {
|
|
377
|
+
if (now - session.lastActivity > this.options.sessionTimeout) {
|
|
378
|
+
this.destroySession(session);
|
|
547
379
|
}
|
|
548
380
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
await this.sendToStreamSessionless(stream, message);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
/**
|
|
558
|
-
* Send message to a specific stream
|
|
559
|
-
*/
|
|
560
|
-
async sendToStream(stream, message, session) {
|
|
561
|
-
try {
|
|
562
|
-
const eventId = `${session.id}-${++stream.eventIdCounter}`;
|
|
563
|
-
const data = JSON.stringify(message);
|
|
564
|
-
stream.response.write(`id: ${eventId}\n`);
|
|
565
|
-
stream.response.write(`data: ${data}\n\n`);
|
|
566
|
-
// Store in queue for resumability
|
|
567
|
-
session.messageQueue.push({
|
|
568
|
-
message,
|
|
569
|
-
streamId: stream.id,
|
|
570
|
-
eventId,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
catch (error) {
|
|
574
|
-
console.error('Error sending to stream:', error);
|
|
575
|
-
stream.closed = true;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Send response to the stream that made the request
|
|
580
|
-
*/
|
|
581
|
-
async sendToRequestStream(response) {
|
|
582
|
-
// Find the stream associated with this request
|
|
583
|
-
// For session-based streams
|
|
584
|
-
for (const session of this.sessions.values()) {
|
|
585
|
-
for (const stream of session.streams.values()) {
|
|
586
|
-
if (!stream.closed) {
|
|
587
|
-
await this.sendToStream(stream, response, session);
|
|
588
|
-
// Keep stream open for multiple requests - stream will close when client disconnects
|
|
381
|
+
// Reap sessions that were created but never finished `initialize`.
|
|
382
|
+
for (const session of this.pendingSessions) {
|
|
383
|
+
if (now - session.createdAt > StreamableHttpTransport.PENDING_SESSION_TIMEOUT_MS) {
|
|
384
|
+
this.destroySession(session);
|
|
589
385
|
}
|
|
590
386
|
}
|
|
591
|
-
}
|
|
592
|
-
//
|
|
593
|
-
|
|
594
|
-
// Closing it after the first response breaks subsequent requests
|
|
595
|
-
for (const stream of this.activeStreams.values()) {
|
|
596
|
-
if (!stream.closed) {
|
|
597
|
-
await this.sendToStreamSessionless(stream, response);
|
|
598
|
-
// Keep stream open - it will be closed when the client disconnects naturally
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Send message to a sessionless stream
|
|
604
|
-
*/
|
|
605
|
-
async sendToStreamSessionless(stream, message) {
|
|
606
|
-
try {
|
|
607
|
-
const eventId = `${stream.id}-${++stream.eventIdCounter}`;
|
|
608
|
-
const data = JSON.stringify(message);
|
|
609
|
-
stream.response.write(`id: ${eventId}\n`);
|
|
610
|
-
stream.response.write(`data: ${data}\n\n`);
|
|
611
|
-
}
|
|
612
|
-
catch (error) {
|
|
613
|
-
console.error('Error sending to sessionless stream:', error);
|
|
614
|
-
stream.closed = true;
|
|
615
|
-
this.activeStreams.delete(stream.id);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Replay messages for resumability
|
|
620
|
-
*/
|
|
621
|
-
replayMessages(session, stream, lastEventId) {
|
|
622
|
-
const messages = session.messageQueue.filter((msg) => msg.streamId === stream.id && msg.eventId > lastEventId);
|
|
623
|
-
for (const { message, eventId } of messages) {
|
|
624
|
-
try {
|
|
625
|
-
const data = JSON.stringify(message);
|
|
626
|
-
stream.response.write(`id: ${eventId}\n`);
|
|
627
|
-
stream.response.write(`data: ${data}\n\n`);
|
|
628
|
-
}
|
|
629
|
-
catch (error) {
|
|
630
|
-
console.error('Error replaying message:', error);
|
|
631
|
-
break;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
387
|
+
}, 60_000); // sweep once a minute
|
|
388
|
+
// Do not keep the event loop (and process) alive just for the sweeper.
|
|
389
|
+
this.sessionCleanupInterval.unref?.();
|
|
634
390
|
}
|
|
635
391
|
/**
|
|
636
392
|
* Start the HTTP server
|
|
637
393
|
*/
|
|
638
394
|
async start() {
|
|
639
395
|
if (this.server) {
|
|
640
|
-
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (!this._routesRegistered) {
|
|
399
|
+
this.setupRoutes();
|
|
400
|
+
this._routesRegistered = true;
|
|
641
401
|
}
|
|
402
|
+
this.startSessionCleanup();
|
|
642
403
|
return new Promise((resolve, reject) => {
|
|
643
404
|
const errorHandler = (error) => {
|
|
644
405
|
console.error(`Failed to start Streamable HTTP transport: ${error.message}`);
|
|
@@ -651,9 +412,7 @@ export class StreamableHttpTransport {
|
|
|
651
412
|
server.once('listening', () => {
|
|
652
413
|
server.removeListener('error', errorHandler);
|
|
653
414
|
server.on('error', (error) => {
|
|
654
|
-
|
|
655
|
-
this.errorHandler(error);
|
|
656
|
-
}
|
|
415
|
+
console.error('Streamable HTTP server error:', error.message);
|
|
657
416
|
});
|
|
658
417
|
this.server = server;
|
|
659
418
|
console.error(`🌐 MCP Streamable HTTP transport listening on http://${this.options.host}:${this.options.port}${this.options.endpoint}`);
|
|
@@ -673,28 +432,41 @@ export class StreamableHttpTransport {
|
|
|
673
432
|
*/
|
|
674
433
|
on(path, handler) {
|
|
675
434
|
this.app.get(path, handler);
|
|
435
|
+
this.app.post(path, handler);
|
|
436
|
+
this.app.options(path, handler);
|
|
676
437
|
}
|
|
677
438
|
/**
|
|
678
|
-
* Close the transport
|
|
439
|
+
* Close the transport: tear down all live MCP sessions and the HTTP server.
|
|
679
440
|
*/
|
|
680
441
|
async close() {
|
|
681
|
-
//
|
|
442
|
+
// Stop the idle sweeper first so it can't race with teardown.
|
|
682
443
|
if (this.sessionCleanupInterval) {
|
|
683
444
|
clearInterval(this.sessionCleanupInterval);
|
|
445
|
+
this.sessionCleanupInterval = undefined;
|
|
684
446
|
}
|
|
685
|
-
// Close all sessions
|
|
686
|
-
|
|
687
|
-
|
|
447
|
+
// Close all MCP sessions (live + pending), including their SDK transports
|
|
448
|
+
// and per-session servers. Use a Set to avoid double-closing a session that
|
|
449
|
+
// appears in both collections.
|
|
450
|
+
const sessions = new Set([...this.mcpSessions.values(), ...this.pendingSessions]);
|
|
451
|
+
this.mcpSessions.clear();
|
|
452
|
+
this.pendingSessions.clear();
|
|
453
|
+
for (const { server, transport } of sessions) {
|
|
454
|
+
if (transport) {
|
|
455
|
+
transport.onclose = undefined;
|
|
688
456
|
try {
|
|
689
|
-
|
|
690
|
-
stream.closed = true;
|
|
457
|
+
await transport.close();
|
|
691
458
|
}
|
|
692
|
-
catch
|
|
693
|
-
//
|
|
459
|
+
catch {
|
|
460
|
+
// ignore
|
|
694
461
|
}
|
|
695
462
|
}
|
|
463
|
+
try {
|
|
464
|
+
await server.close();
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
// ignore
|
|
468
|
+
}
|
|
696
469
|
}
|
|
697
|
-
this.sessions.clear();
|
|
698
470
|
// Close HTTP server
|
|
699
471
|
if (this.server) {
|
|
700
472
|
return new Promise((resolve) => {
|
|
@@ -705,77 +477,18 @@ export class StreamableHttpTransport {
|
|
|
705
477
|
if (err) {
|
|
706
478
|
console.error('HTTP server close error:', err.message);
|
|
707
479
|
}
|
|
708
|
-
if (this.closeHandler) {
|
|
709
|
-
this.closeHandler();
|
|
710
|
-
}
|
|
711
480
|
resolve();
|
|
712
481
|
});
|
|
713
482
|
});
|
|
714
483
|
}
|
|
715
|
-
if (this.closeHandler) {
|
|
716
|
-
this.closeHandler();
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Set message handler
|
|
721
|
-
*/
|
|
722
|
-
set onmessage(handler) {
|
|
723
|
-
this.messageHandler = handler;
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
* Set close handler
|
|
727
|
-
*/
|
|
728
|
-
set onclose(handler) {
|
|
729
|
-
this.closeHandler = handler;
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Set error handler
|
|
733
|
-
*/
|
|
734
|
-
set onerror(handler) {
|
|
735
|
-
this.errorHandler = handler;
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Start session cleanup interval
|
|
739
|
-
*/
|
|
740
|
-
startSessionCleanup() {
|
|
741
|
-
this.sessionCleanupInterval = setInterval(() => {
|
|
742
|
-
const now = Date.now();
|
|
743
|
-
for (const [sessionId, session] of this.sessions.entries()) {
|
|
744
|
-
if (now - session.lastActivity > this.options.sessionTimeout) {
|
|
745
|
-
// Cleanup expired session
|
|
746
|
-
for (const stream of session.streams.values()) {
|
|
747
|
-
try {
|
|
748
|
-
stream.response.end();
|
|
749
|
-
stream.closed = true;
|
|
750
|
-
}
|
|
751
|
-
catch (error) {
|
|
752
|
-
// Ignore
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
this.sessions.delete(sessionId);
|
|
756
|
-
console.error(`Session ${sessionId} expired and cleaned up`);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}, 60000); // Check every minute
|
|
760
484
|
}
|
|
761
485
|
/**
|
|
762
|
-
*
|
|
486
|
+
* Whether a parsed JSON-RPC body is an `initialize` request.
|
|
763
487
|
*/
|
|
764
|
-
generateSessionId() {
|
|
765
|
-
return uuidv4();
|
|
766
|
-
}
|
|
767
|
-
getMessageType(message) {
|
|
768
|
-
if ('method' in message && 'id' in message)
|
|
769
|
-
return 'request';
|
|
770
|
-
if ('result' in message || 'error' in message)
|
|
771
|
-
return 'response';
|
|
772
|
-
return 'notification';
|
|
773
|
-
}
|
|
774
|
-
isResponse(message) {
|
|
775
|
-
return 'result' in message || 'error' in message;
|
|
776
|
-
}
|
|
777
488
|
isInitializeRequest(message) {
|
|
778
|
-
return
|
|
489
|
+
return (!!message &&
|
|
490
|
+
typeof message === 'object' &&
|
|
491
|
+
message.method === 'initialize');
|
|
779
492
|
}
|
|
780
493
|
isLocalhost(host) {
|
|
781
494
|
// Extract hostname without port (handles both IPv4 and IPv6 formats)
|
|
@@ -816,455 +529,1510 @@ export class StreamableHttpTransport {
|
|
|
816
529
|
* Generate HTML documentation page
|
|
817
530
|
*/
|
|
818
531
|
generateDocumentationPage(tools, mcpEndpoint) {
|
|
819
|
-
const
|
|
532
|
+
const rawServerName = this.serverConfig?.name || 'NitroStack MCP Server';
|
|
533
|
+
const formatTitle = (name) => {
|
|
534
|
+
if (name.includes('/') || name.includes('\\'))
|
|
535
|
+
return name;
|
|
536
|
+
return name
|
|
537
|
+
.split(/[-_]+/)
|
|
538
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
539
|
+
.join(' ');
|
|
540
|
+
};
|
|
541
|
+
const serverName = formatTitle(rawServerName);
|
|
820
542
|
const serverVersion = this.serverConfig?.version || '1.0.0';
|
|
821
543
|
const serverDescription = this.serverConfig?.description || 'A powerful MCP server built with NitroStack';
|
|
822
544
|
return `<!DOCTYPE html>
|
|
823
|
-
<html lang="en">
|
|
545
|
+
<html lang="en" class="dark">
|
|
824
546
|
<head>
|
|
825
547
|
<meta charset="UTF-8">
|
|
826
548
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
827
549
|
<title>${serverName} - MCP Server Documentation</title>
|
|
828
550
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
829
551
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
830
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
552
|
+
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700;800&family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
831
553
|
<style>
|
|
554
|
+
/* Premium Dark & Light Themes */
|
|
832
555
|
:root {
|
|
833
|
-
--
|
|
834
|
-
--
|
|
835
|
-
--
|
|
836
|
-
--
|
|
837
|
-
--
|
|
838
|
-
--
|
|
839
|
-
--
|
|
840
|
-
--primary
|
|
841
|
-
--
|
|
842
|
-
--
|
|
843
|
-
--
|
|
844
|
-
--
|
|
845
|
-
--
|
|
556
|
+
--bg-gradient: radial-gradient(circle at 10% 20%, #0f172a 0%, #020617 90%);
|
|
557
|
+
--bg-card: rgba(30, 41, 59, 0.45);
|
|
558
|
+
--bg-card-hover: rgba(30, 41, 59, 0.65);
|
|
559
|
+
--border-color: rgba(255, 255, 255, 0.08);
|
|
560
|
+
--border-color-hover: rgba(99, 102, 241, 0.4);
|
|
561
|
+
--text-main: #f8fafc;
|
|
562
|
+
--text-muted: #94a3b8;
|
|
563
|
+
--primary: #6366f1;
|
|
564
|
+
--primary-hover: #4f46e5;
|
|
565
|
+
--primary-rgb: 99, 102, 241;
|
|
566
|
+
--accent: #a855f7;
|
|
567
|
+
--success: #10b981;
|
|
568
|
+
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
569
|
+
--font-display: 'Space Grotesk', sans-serif;
|
|
570
|
+
--font-mono: 'JetBrains Mono', monospace;
|
|
571
|
+
--card-shadow: 0 4px 30px rgba(0, 0, 0, 0.15);
|
|
572
|
+
--card-shadow-hover: 0 12px 30px rgba(99, 102, 241, 0.12);
|
|
573
|
+
--codex-badge-bg: #ffffff;
|
|
574
|
+
--logo-bg: rgba(255, 255, 255, 0.04);
|
|
846
575
|
}
|
|
576
|
+
|
|
577
|
+
.light {
|
|
578
|
+
--bg-gradient: radial-gradient(circle at 10% 20%, #f8fafc 0%, #e2e8f0 90%);
|
|
579
|
+
--bg-card: rgba(255, 255, 255, 0.65);
|
|
580
|
+
--bg-card-hover: rgba(255, 255, 255, 0.85);
|
|
581
|
+
--border-color: rgba(15, 23, 42, 0.08);
|
|
582
|
+
--border-color-hover: rgba(79, 70, 229, 0.4);
|
|
583
|
+
--text-main: #0f172a;
|
|
584
|
+
--text-muted: #475569;
|
|
585
|
+
--primary: #4f46e5;
|
|
586
|
+
--primary-hover: #3730a3;
|
|
587
|
+
--primary-rgb: 79, 70, 229;
|
|
588
|
+
--accent: #7e22ce;
|
|
589
|
+
--success: #059669;
|
|
590
|
+
--font-display: 'Space Grotesk', sans-serif;
|
|
591
|
+
--card-shadow: 0 8px 30px rgba(15, 23, 42, 0.04);
|
|
592
|
+
--card-shadow-hover: 0 20px 40px rgba(79, 70, 229, 0.12);
|
|
593
|
+
--codex-badge-bg: #1e1e1e;
|
|
594
|
+
--logo-bg: rgba(15, 23, 42, 0.04);
|
|
595
|
+
}
|
|
596
|
+
|
|
847
597
|
* {
|
|
598
|
+
box-sizing: border-box;
|
|
848
599
|
margin: 0;
|
|
849
600
|
padding: 0;
|
|
850
|
-
box-sizing: border-box;
|
|
851
601
|
}
|
|
852
602
|
|
|
853
603
|
body {
|
|
854
|
-
font-family:
|
|
855
|
-
background:
|
|
604
|
+
font-family: var(--font-sans);
|
|
605
|
+
background: var(--bg-gradient);
|
|
606
|
+
color: var(--text-main);
|
|
856
607
|
min-height: 100vh;
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
608
|
+
display: flex;
|
|
609
|
+
flex-direction: column;
|
|
610
|
+
align-items: center;
|
|
611
|
+
padding: 3rem 1.5rem;
|
|
612
|
+
transition: background 0.3s, color 0.3s;
|
|
862
613
|
}
|
|
863
614
|
|
|
864
|
-
.
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
background: var(--background);
|
|
868
|
-
border-radius: 24px;
|
|
869
|
-
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
870
|
-
overflow: hidden;
|
|
615
|
+
.wrapper {
|
|
616
|
+
width: 100%;
|
|
617
|
+
max-width: 960px;
|
|
871
618
|
}
|
|
872
619
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
620
|
+
/* Top Controls */
|
|
621
|
+
.controls {
|
|
622
|
+
display: flex;
|
|
623
|
+
justify-content: flex-end;
|
|
624
|
+
margin-bottom: 1.5rem;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.btn-toggle {
|
|
628
|
+
background: var(--bg-card);
|
|
629
|
+
border: 1px solid var(--border-color);
|
|
630
|
+
color: var(--text-main);
|
|
631
|
+
padding: 0.5rem 1rem;
|
|
632
|
+
border-radius: 9999px;
|
|
633
|
+
font-size: 0.8rem;
|
|
634
|
+
font-weight: 600;
|
|
635
|
+
cursor: pointer;
|
|
636
|
+
display: flex;
|
|
637
|
+
align-items: center;
|
|
638
|
+
gap: 0.5rem;
|
|
639
|
+
backdrop-filter: blur(12px);
|
|
640
|
+
transition: all 0.2s;
|
|
641
|
+
}
|
|
642
|
+
.btn-toggle:hover {
|
|
643
|
+
border-color: var(--primary);
|
|
644
|
+
box-shadow: var(--card-shadow-hover);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.icon-sun {
|
|
648
|
+
display: inline-block;
|
|
649
|
+
}
|
|
650
|
+
.icon-moon {
|
|
651
|
+
display: none;
|
|
652
|
+
}
|
|
653
|
+
.light .icon-sun {
|
|
654
|
+
display: none;
|
|
655
|
+
}
|
|
656
|
+
.light .icon-moon {
|
|
657
|
+
display: inline-block;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/* Premium Header */
|
|
661
|
+
header {
|
|
662
|
+
background: var(--bg-card);
|
|
663
|
+
border: 1px solid var(--border-color);
|
|
664
|
+
border-radius: 24px;
|
|
665
|
+
padding: 3rem 2rem;
|
|
666
|
+
margin-bottom: 2rem;
|
|
667
|
+
backdrop-filter: blur(16px);
|
|
668
|
+
display: flex;
|
|
669
|
+
flex-direction: column;
|
|
670
|
+
align-items: center;
|
|
877
671
|
text-align: center;
|
|
878
672
|
position: relative;
|
|
879
673
|
overflow: hidden;
|
|
674
|
+
box-shadow: var(--card-shadow);
|
|
880
675
|
}
|
|
881
676
|
|
|
882
|
-
|
|
677
|
+
header::before {
|
|
883
678
|
content: '';
|
|
884
679
|
position: absolute;
|
|
885
680
|
top: 0;
|
|
886
681
|
left: 0;
|
|
887
682
|
right: 0;
|
|
888
|
-
|
|
889
|
-
background: linear-gradient(
|
|
890
|
-
pointer-events: none;
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
.header > * {
|
|
894
|
-
position: relative;
|
|
895
|
-
z-index: 1;
|
|
683
|
+
height: 4px;
|
|
684
|
+
background: linear-gradient(90deg, var(--primary), var(--accent));
|
|
896
685
|
}
|
|
897
686
|
|
|
898
687
|
.logo-container {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
688
|
+
background: var(--logo-bg);
|
|
689
|
+
border-radius: 20px;
|
|
690
|
+
padding: 1rem;
|
|
691
|
+
margin-bottom: 1.5rem;
|
|
692
|
+
border: 1px solid var(--border-color);
|
|
693
|
+
display: inline-flex;
|
|
694
|
+
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.1);
|
|
903
695
|
}
|
|
904
696
|
|
|
905
697
|
.logo {
|
|
906
|
-
height:
|
|
698
|
+
height: 56px;
|
|
907
699
|
width: auto;
|
|
908
|
-
max-width: 200px;
|
|
909
700
|
object-fit: contain;
|
|
910
|
-
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.3));
|
|
911
|
-
transition: transform 0.3s ease;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
.logo:hover {
|
|
915
|
-
transform: scale(1.05);
|
|
916
701
|
}
|
|
917
702
|
|
|
918
|
-
.
|
|
919
|
-
font-
|
|
920
|
-
font-
|
|
703
|
+
.title {
|
|
704
|
+
font-family: var(--font-display);
|
|
705
|
+
font-size: 2.5rem;
|
|
706
|
+
font-weight: 800;
|
|
707
|
+
letter-spacing: -0.03em;
|
|
921
708
|
margin-bottom: 0.5rem;
|
|
922
|
-
|
|
923
|
-
letter-spacing: -0.025em;
|
|
709
|
+
line-height: 1.2;
|
|
924
710
|
}
|
|
925
711
|
|
|
926
|
-
.
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
font-
|
|
930
|
-
|
|
931
|
-
|
|
712
|
+
.version-badge {
|
|
713
|
+
display: inline-block;
|
|
714
|
+
font-family: var(--font-mono);
|
|
715
|
+
font-size: 0.75rem;
|
|
716
|
+
font-weight: 600;
|
|
717
|
+
background: rgba(var(--primary-rgb), 0.1);
|
|
718
|
+
color: var(--primary);
|
|
719
|
+
padding: 0.25rem 0.75rem;
|
|
720
|
+
border-radius: 9999px;
|
|
721
|
+
border: 1px solid rgba(var(--primary-rgb), 0.2);
|
|
722
|
+
margin-bottom: 1.25rem;
|
|
932
723
|
}
|
|
933
724
|
|
|
934
|
-
.
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
opacity: 0.95;
|
|
938
|
-
font-weight: 400;
|
|
725
|
+
.description {
|
|
726
|
+
font-size: 1.05rem;
|
|
727
|
+
color: var(--text-muted);
|
|
939
728
|
max-width: 600px;
|
|
940
|
-
|
|
941
|
-
margin-right: auto;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
.content {
|
|
945
|
-
padding: 3rem 2rem;
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
.section {
|
|
949
|
-
margin-bottom: 4rem;
|
|
729
|
+
line-height: 1.6;
|
|
950
730
|
}
|
|
951
731
|
|
|
952
|
-
|
|
953
|
-
|
|
732
|
+
/* Connection Panel with Tabs */
|
|
733
|
+
.connection-panel {
|
|
734
|
+
background: var(--bg-card);
|
|
735
|
+
border: 1px solid var(--border-color);
|
|
736
|
+
border-radius: 24px;
|
|
737
|
+
padding: 2.25rem;
|
|
738
|
+
margin-bottom: 2rem;
|
|
739
|
+
backdrop-filter: blur(16px);
|
|
740
|
+
box-shadow: var(--card-shadow);
|
|
954
741
|
}
|
|
955
742
|
|
|
956
|
-
.section
|
|
957
|
-
font-size:
|
|
743
|
+
.section-title {
|
|
744
|
+
font-size: 1.25rem;
|
|
958
745
|
font-weight: 700;
|
|
959
|
-
color: var(--foreground);
|
|
960
|
-
margin-bottom: 1.5rem;
|
|
961
|
-
padding-bottom: 0.75rem;
|
|
962
|
-
border-bottom: 3px solid var(--nitrocloud-primary);
|
|
963
746
|
letter-spacing: -0.02em;
|
|
747
|
+
margin-bottom: 1.25rem;
|
|
748
|
+
display: flex;
|
|
749
|
+
align-items: center;
|
|
750
|
+
gap: 0.5rem;
|
|
964
751
|
}
|
|
965
752
|
|
|
966
|
-
.
|
|
967
|
-
|
|
968
|
-
border-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
margin-bottom: 2rem;
|
|
972
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
|
753
|
+
.tab-header {
|
|
754
|
+
display: flex;
|
|
755
|
+
border-bottom: 1px solid var(--border-color);
|
|
756
|
+
gap: 1.25rem;
|
|
757
|
+
margin-bottom: 1.5rem;
|
|
973
758
|
}
|
|
974
759
|
|
|
975
|
-
.
|
|
760
|
+
.tab-btn {
|
|
761
|
+
background: none;
|
|
762
|
+
border: none;
|
|
763
|
+
color: var(--text-muted);
|
|
764
|
+
padding: 0.75rem 0.25rem;
|
|
765
|
+
font-family: var(--font-sans);
|
|
766
|
+
font-size: 0.875rem;
|
|
976
767
|
font-weight: 600;
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
768
|
+
cursor: pointer;
|
|
769
|
+
position: relative;
|
|
770
|
+
transition: color 0.2s;
|
|
771
|
+
display: inline-flex;
|
|
772
|
+
align-items: center;
|
|
773
|
+
gap: 0.35rem;
|
|
980
774
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
background: hsl(222.2, 84%, 4.9%);
|
|
984
|
-
color: hsl(142, 76%, 36%);
|
|
985
|
-
padding: 1rem 1.25rem;
|
|
986
|
-
border-radius: 8px;
|
|
987
|
-
font-family: 'Monaco', 'Courier New', 'Menlo', monospace;
|
|
988
|
-
display: block;
|
|
989
|
-
margin-top: 0.75rem;
|
|
990
|
-
word-break: break-all;
|
|
991
|
-
font-size: 0.875rem;
|
|
992
|
-
line-height: 1.6;
|
|
993
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
775
|
+
.tab-btn:hover {
|
|
776
|
+
color: var(--text-main);
|
|
994
777
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
778
|
+
.tab-btn.active {
|
|
779
|
+
color: var(--primary);
|
|
780
|
+
}
|
|
781
|
+
.tab-btn.active::after {
|
|
782
|
+
content: '';
|
|
783
|
+
position: absolute;
|
|
784
|
+
bottom: -1px;
|
|
785
|
+
left: 0;
|
|
786
|
+
right: 0;
|
|
787
|
+
height: 2px;
|
|
788
|
+
background: var(--primary);
|
|
1001
789
|
}
|
|
1002
790
|
|
|
1003
|
-
.
|
|
1004
|
-
display:
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
791
|
+
.tab-content {
|
|
792
|
+
display: none;
|
|
793
|
+
}
|
|
794
|
+
.tab-content.active {
|
|
795
|
+
display: block;
|
|
1008
796
|
}
|
|
1009
797
|
|
|
1010
|
-
.
|
|
1011
|
-
background:
|
|
1012
|
-
border:
|
|
1013
|
-
border-radius:
|
|
1014
|
-
padding: 1.
|
|
1015
|
-
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
798
|
+
.code-container {
|
|
799
|
+
background: #020617;
|
|
800
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
801
|
+
border-radius: 12px;
|
|
802
|
+
padding: 1.25rem;
|
|
1016
803
|
position: relative;
|
|
1017
|
-
overflow:
|
|
1018
|
-
|
|
804
|
+
overflow-x: auto;
|
|
805
|
+
margin-top: 0.75rem;
|
|
806
|
+
}
|
|
807
|
+
.code-container pre {
|
|
808
|
+
font-family: var(--font-mono);
|
|
809
|
+
font-size: 0.825rem;
|
|
810
|
+
color: #93c5fd;
|
|
811
|
+
line-height: 1.5;
|
|
1019
812
|
}
|
|
1020
813
|
|
|
1021
|
-
.
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
814
|
+
.btn-copy {
|
|
815
|
+
position: absolute;
|
|
816
|
+
top: 0.75rem;
|
|
817
|
+
right: 0.75rem;
|
|
818
|
+
background: rgba(255, 255, 255, 0.07);
|
|
819
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
820
|
+
color: #e2e8f0;
|
|
821
|
+
padding: 0.35rem 0.7rem;
|
|
822
|
+
font-size: 0.75rem;
|
|
823
|
+
font-weight: 600;
|
|
824
|
+
border-radius: 6px;
|
|
825
|
+
cursor: pointer;
|
|
826
|
+
display: flex;
|
|
827
|
+
align-items: center;
|
|
828
|
+
gap: 0.25rem;
|
|
829
|
+
transition: all 0.2s;
|
|
830
|
+
}
|
|
831
|
+
.btn-copy:hover {
|
|
832
|
+
background: rgba(255, 255, 255, 0.15);
|
|
833
|
+
color: white;
|
|
1025
834
|
}
|
|
1026
835
|
|
|
1027
|
-
|
|
1028
|
-
|
|
836
|
+
/* Search Box */
|
|
837
|
+
.search-container {
|
|
838
|
+
position: relative;
|
|
839
|
+
margin-bottom: 1.5rem;
|
|
840
|
+
}
|
|
841
|
+
.search-input {
|
|
842
|
+
width: 100%;
|
|
843
|
+
background: var(--bg-card);
|
|
844
|
+
border: 1px solid var(--border-color);
|
|
845
|
+
border-radius: 16px;
|
|
846
|
+
padding: 1rem 1.25rem 1rem 3.25rem;
|
|
847
|
+
color: var(--text-main);
|
|
848
|
+
font-family: var(--font-sans);
|
|
849
|
+
font-size: 0.95rem;
|
|
850
|
+
transition: all 0.2s;
|
|
851
|
+
outline: none;
|
|
852
|
+
}
|
|
853
|
+
.search-input:focus {
|
|
854
|
+
border-color: var(--primary);
|
|
855
|
+
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.15);
|
|
856
|
+
}
|
|
857
|
+
.search-icon {
|
|
1029
858
|
position: absolute;
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
859
|
+
left: 1.25rem;
|
|
860
|
+
top: 50%;
|
|
861
|
+
transform: translateY(-50%);
|
|
862
|
+
color: var(--text-muted);
|
|
863
|
+
pointer-events: none;
|
|
864
|
+
width: 1.25rem;
|
|
865
|
+
height: 1.25rem;
|
|
1035
866
|
}
|
|
1036
867
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
868
|
+
/* Tools Grid */
|
|
869
|
+
.tools-grid {
|
|
870
|
+
display: grid;
|
|
871
|
+
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
|
|
872
|
+
gap: 1.25rem;
|
|
873
|
+
margin-bottom: 4rem;
|
|
874
|
+
}
|
|
875
|
+
.tool-card {
|
|
876
|
+
background: var(--bg-card);
|
|
877
|
+
border: 1px solid var(--border-color);
|
|
878
|
+
border-radius: 20px;
|
|
879
|
+
padding: 1.5rem;
|
|
880
|
+
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
881
|
+
display: flex;
|
|
882
|
+
flex-direction: column;
|
|
883
|
+
backdrop-filter: blur(12px);
|
|
884
|
+
box-shadow: var(--card-shadow);
|
|
885
|
+
}
|
|
886
|
+
.tool-card:hover {
|
|
887
|
+
border-color: var(--border-color-hover);
|
|
888
|
+
box-shadow: var(--card-shadow-hover);
|
|
889
|
+
transform: translateY(-4px);
|
|
890
|
+
}
|
|
891
|
+
.tool-header {
|
|
892
|
+
display: flex;
|
|
893
|
+
justify-content: space-between;
|
|
894
|
+
align-items: flex-start;
|
|
1041
895
|
margin-bottom: 0.75rem;
|
|
896
|
+
gap: 0.5rem;
|
|
897
|
+
}
|
|
898
|
+
.tool-name {
|
|
899
|
+
font-weight: 700;
|
|
900
|
+
font-size: 1.1rem;
|
|
901
|
+
letter-spacing: -0.02em;
|
|
1042
902
|
display: flex;
|
|
1043
903
|
align-items: center;
|
|
1044
904
|
gap: 0.5rem;
|
|
1045
|
-
letter-spacing: -0.01em;
|
|
1046
905
|
}
|
|
1047
|
-
|
|
1048
|
-
.tool-name::before {
|
|
1049
|
-
content: '⚡';
|
|
1050
|
-
font-size: 1.25rem;
|
|
1051
|
-
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
906
|
.tool-description {
|
|
1055
|
-
color: var(--muted-foreground);
|
|
1056
|
-
margin-bottom: 1rem;
|
|
1057
|
-
line-height: 1.625;
|
|
1058
|
-
font-size: 0.9375rem;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
.tool-schema {
|
|
1062
|
-
background: var(--secondary);
|
|
1063
|
-
border-radius: 8px;
|
|
1064
|
-
padding: 1rem;
|
|
1065
|
-
margin-top: 1rem;
|
|
1066
907
|
font-size: 0.875rem;
|
|
1067
|
-
|
|
908
|
+
color: var(--text-muted);
|
|
909
|
+
line-height: 1.6;
|
|
910
|
+
flex-grow: 1;
|
|
911
|
+
margin-bottom: 1.5rem;
|
|
1068
912
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
913
|
+
.schema-toggle {
|
|
914
|
+
background: rgba(var(--primary-rgb), 0.05);
|
|
915
|
+
border: 1px solid rgba(var(--primary-rgb), 0.1);
|
|
916
|
+
color: var(--primary);
|
|
917
|
+
padding: 0.55rem 1rem;
|
|
918
|
+
font-family: var(--font-sans);
|
|
919
|
+
font-size: 0.8rem;
|
|
1072
920
|
font-weight: 600;
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
921
|
+
border-radius: 8px;
|
|
922
|
+
cursor: pointer;
|
|
923
|
+
display: flex;
|
|
924
|
+
align-items: center;
|
|
925
|
+
justify-content: center;
|
|
926
|
+
gap: 0.35rem;
|
|
927
|
+
transition: all 0.2s;
|
|
928
|
+
}
|
|
929
|
+
.schema-toggle:hover {
|
|
930
|
+
background: rgba(var(--primary-rgb), 0.1);
|
|
931
|
+
border-color: var(--primary);
|
|
1077
932
|
}
|
|
1078
933
|
|
|
1079
|
-
.
|
|
1080
|
-
|
|
934
|
+
.schema-content {
|
|
935
|
+
display: none;
|
|
936
|
+
margin-top: 1rem;
|
|
937
|
+
border-top: 1px solid var(--border-color);
|
|
938
|
+
padding-top: 1rem;
|
|
939
|
+
}
|
|
940
|
+
.schema-content.active {
|
|
941
|
+
display: block;
|
|
942
|
+
animation: slideDown 0.2s ease-out;
|
|
1081
943
|
}
|
|
1082
944
|
|
|
1083
|
-
.
|
|
1084
|
-
background:
|
|
1085
|
-
|
|
945
|
+
.schema-content pre {
|
|
946
|
+
background: #020617;
|
|
947
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
1086
948
|
padding: 1rem;
|
|
1087
|
-
border-radius:
|
|
949
|
+
border-radius: 8px;
|
|
1088
950
|
overflow-x: auto;
|
|
1089
|
-
|
|
1090
|
-
font-size: 0.
|
|
1091
|
-
|
|
1092
|
-
|
|
951
|
+
font-family: var(--font-mono);
|
|
952
|
+
font-size: 0.775rem;
|
|
953
|
+
color: #38bdf8;
|
|
954
|
+
line-height: 1.5;
|
|
1093
955
|
}
|
|
1094
956
|
|
|
1095
|
-
|
|
1096
|
-
|
|
957
|
+
@keyframes slideDown {
|
|
958
|
+
from { opacity: 0; transform: translateY(-4px); }
|
|
959
|
+
to { opacity: 1; transform: translateY(0); }
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/* Modal Styles */
|
|
963
|
+
.modal-overlay {
|
|
964
|
+
position: fixed;
|
|
965
|
+
top: 0;
|
|
966
|
+
left: 0;
|
|
967
|
+
right: 0;
|
|
968
|
+
bottom: 0;
|
|
969
|
+
background: rgba(15, 23, 42, 0.6);
|
|
970
|
+
backdrop-filter: blur(8px);
|
|
971
|
+
display: none;
|
|
1097
972
|
align-items: center;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
973
|
+
justify-content: center;
|
|
974
|
+
z-index: 1000;
|
|
975
|
+
opacity: 0;
|
|
976
|
+
transition: opacity 0.2s ease-out;
|
|
977
|
+
}
|
|
978
|
+
.modal-overlay.active {
|
|
979
|
+
opacity: 1;
|
|
1104
980
|
}
|
|
1105
981
|
|
|
1106
|
-
.
|
|
1107
|
-
background:
|
|
1108
|
-
|
|
1109
|
-
|
|
982
|
+
.modal-content {
|
|
983
|
+
background: var(--bg-card);
|
|
984
|
+
border: 1px solid var(--border-color);
|
|
985
|
+
border-radius: 24px;
|
|
986
|
+
width: 90%;
|
|
987
|
+
max-width: 640px;
|
|
988
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
|
|
989
|
+
backdrop-filter: blur(20px);
|
|
990
|
+
transform: scale(0.95);
|
|
991
|
+
transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
992
|
+
display: flex;
|
|
993
|
+
flex-direction: column;
|
|
994
|
+
max-height: 85vh;
|
|
995
|
+
overflow: hidden;
|
|
996
|
+
}
|
|
997
|
+
.modal-overlay.active .modal-content {
|
|
998
|
+
transform: scale(1);
|
|
1110
999
|
}
|
|
1111
1000
|
|
|
1112
|
-
.
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1001
|
+
.modal-header {
|
|
1002
|
+
padding: 1.5rem 2rem;
|
|
1003
|
+
border-bottom: 1px solid var(--border-color);
|
|
1004
|
+
display: flex;
|
|
1005
|
+
justify-content: space-between;
|
|
1006
|
+
align-items: center;
|
|
1116
1007
|
}
|
|
1117
1008
|
|
|
1118
|
-
.
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1009
|
+
.modal-title {
|
|
1010
|
+
font-family: var(--font-display);
|
|
1011
|
+
font-size: 1.35rem;
|
|
1012
|
+
font-weight: 700;
|
|
1013
|
+
color: var(--text-main);
|
|
1014
|
+
letter-spacing: -0.02em;
|
|
1124
1015
|
}
|
|
1125
1016
|
|
|
1126
|
-
.
|
|
1127
|
-
|
|
1128
|
-
|
|
1017
|
+
.modal-close-btn {
|
|
1018
|
+
background: none;
|
|
1019
|
+
border: none;
|
|
1020
|
+
color: var(--text-muted);
|
|
1021
|
+
cursor: pointer;
|
|
1022
|
+
display: flex;
|
|
1023
|
+
align-items: center;
|
|
1024
|
+
justify-content: center;
|
|
1025
|
+
width: 32px;
|
|
1026
|
+
height: 32px;
|
|
1027
|
+
border-radius: 8px;
|
|
1028
|
+
transition: all 0.2s;
|
|
1029
|
+
}
|
|
1030
|
+
.modal-close-btn:hover {
|
|
1031
|
+
background: rgba(var(--primary-rgb), 0.1);
|
|
1032
|
+
color: var(--text-main);
|
|
1129
1033
|
}
|
|
1130
1034
|
|
|
1131
|
-
.
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
color: var(--muted-foreground);
|
|
1136
|
-
border-top: 1px solid var(--border);
|
|
1035
|
+
.modal-body {
|
|
1036
|
+
padding: 2rem;
|
|
1037
|
+
overflow-y: auto;
|
|
1038
|
+
flex: 1;
|
|
1137
1039
|
}
|
|
1138
1040
|
|
|
1139
|
-
.
|
|
1140
|
-
font-size: 0.
|
|
1041
|
+
.modal-tool-description {
|
|
1042
|
+
font-size: 0.95rem;
|
|
1043
|
+
color: var(--text-muted);
|
|
1141
1044
|
line-height: 1.6;
|
|
1045
|
+
margin-bottom: 1.5rem;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.modal-section-title {
|
|
1049
|
+
font-size: 0.9rem;
|
|
1050
|
+
font-weight: 700;
|
|
1051
|
+
text-transform: uppercase;
|
|
1052
|
+
letter-spacing: 0.05em;
|
|
1053
|
+
color: var(--primary);
|
|
1142
1054
|
}
|
|
1143
1055
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1056
|
+
/* Footer */
|
|
1057
|
+
footer {
|
|
1058
|
+
text-align: center;
|
|
1059
|
+
color: var(--text-muted);
|
|
1060
|
+
font-size: 0.85rem;
|
|
1061
|
+
margin-top: auto;
|
|
1062
|
+
padding: 2.5rem 0;
|
|
1063
|
+
border-top: 1px solid var(--border-color);
|
|
1064
|
+
width: 100%;
|
|
1065
|
+
}
|
|
1066
|
+
footer a {
|
|
1067
|
+
color: var(--primary);
|
|
1146
1068
|
text-decoration: none;
|
|
1147
1069
|
font-weight: 600;
|
|
1070
|
+
}
|
|
1071
|
+
footer a:hover {
|
|
1072
|
+
text-decoration: underline;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/* ChatGPT New App Dialog Mockup Styles */
|
|
1076
|
+
.chatgpt-dialog-container {
|
|
1077
|
+
background-color: #171717;
|
|
1078
|
+
border: 1px solid #2f2f2f;
|
|
1079
|
+
border-radius: 16px;
|
|
1080
|
+
padding: 24px;
|
|
1081
|
+
width: 100%;
|
|
1082
|
+
max-width: 520px;
|
|
1083
|
+
color: #ececec;
|
|
1084
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
1085
|
+
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.6);
|
|
1086
|
+
margin: 1.5rem auto;
|
|
1087
|
+
position: relative;
|
|
1088
|
+
text-align: left;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
.chatgpt-dialog-header {
|
|
1092
|
+
display: flex;
|
|
1093
|
+
justify-content: space-between;
|
|
1094
|
+
align-items: center;
|
|
1095
|
+
margin-bottom: 20px;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
.chatgpt-dialog-title {
|
|
1099
|
+
font-size: 18px;
|
|
1100
|
+
font-weight: 600;
|
|
1101
|
+
color: #ececec;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
.chatgpt-close-btn {
|
|
1105
|
+
color: #b4b4b4;
|
|
1106
|
+
cursor: pointer;
|
|
1107
|
+
display: flex;
|
|
1108
|
+
align-items: center;
|
|
1109
|
+
justify-content: center;
|
|
1110
|
+
width: 28px;
|
|
1111
|
+
height: 28px;
|
|
1112
|
+
border-radius: 6px;
|
|
1113
|
+
transition: background-color 0.2s;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
.chatgpt-close-btn:hover {
|
|
1117
|
+
background-color: #2f2f2f;
|
|
1118
|
+
color: #ececec;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
.chatgpt-section-label {
|
|
1122
|
+
font-size: 14px;
|
|
1123
|
+
font-weight: 600;
|
|
1124
|
+
margin-bottom: 8px;
|
|
1125
|
+
color: #ececec;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.chatgpt-icon-picker {
|
|
1129
|
+
display: flex;
|
|
1130
|
+
align-items: center;
|
|
1131
|
+
gap: 16px;
|
|
1132
|
+
margin-bottom: 20px;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
.chatgpt-icon-box {
|
|
1136
|
+
width: 56px;
|
|
1137
|
+
height: 56px;
|
|
1138
|
+
border: 1px dashed #424242;
|
|
1139
|
+
border-radius: 12px;
|
|
1140
|
+
display: flex;
|
|
1141
|
+
align-items: center;
|
|
1142
|
+
justify-content: center;
|
|
1143
|
+
color: #b4b4b4;
|
|
1144
|
+
transition: border-color 0.2s;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.chatgpt-icon-desc {
|
|
1148
|
+
font-size: 12.5px;
|
|
1149
|
+
color: #b4b4b4;
|
|
1150
|
+
line-height: 1.4;
|
|
1151
|
+
flex: 1;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
.chatgpt-input-group {
|
|
1155
|
+
display: flex;
|
|
1156
|
+
flex-direction: column;
|
|
1157
|
+
gap: 16px;
|
|
1158
|
+
margin-bottom: 20px;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
.chatgpt-field {
|
|
1162
|
+
display: flex;
|
|
1163
|
+
flex-direction: column;
|
|
1164
|
+
gap: 6px;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
.chatgpt-input-wrapper {
|
|
1168
|
+
position: relative;
|
|
1169
|
+
width: 100%;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.chatgpt-input {
|
|
1173
|
+
width: 100%;
|
|
1174
|
+
background-color: #212121;
|
|
1175
|
+
border: 1px solid #424242;
|
|
1176
|
+
border-radius: 10px;
|
|
1177
|
+
padding: 10px 14px;
|
|
1178
|
+
color: #ececec;
|
|
1179
|
+
font-size: 14.5px;
|
|
1180
|
+
outline: none;
|
|
1181
|
+
transition: border-color 0.2s;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.chatgpt-input::placeholder {
|
|
1185
|
+
color: #676767;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.chatgpt-input.active-input {
|
|
1189
|
+
border-color: #10a37f;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
.chatgpt-input.active-input {
|
|
1193
|
+
padding-right: 75px;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
.chatgpt-input-wrapper .btn-copy-input {
|
|
1197
|
+
position: absolute;
|
|
1198
|
+
right: 10px;
|
|
1199
|
+
top: 50%;
|
|
1200
|
+
transform: translateY(-50%);
|
|
1201
|
+
background: rgba(255, 255, 255, 0.05);
|
|
1202
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
1203
|
+
color: #ececec;
|
|
1204
|
+
padding: 4px 8px;
|
|
1205
|
+
font-size: 11px;
|
|
1206
|
+
border-radius: 4px;
|
|
1207
|
+
cursor: pointer;
|
|
1208
|
+
transition: all 0.2s;
|
|
1209
|
+
z-index: 2;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
.chatgpt-input-wrapper .btn-copy-input:hover {
|
|
1213
|
+
background: rgba(255, 255, 255, 0.15);
|
|
1214
|
+
border-color: rgba(255, 255, 255, 0.25);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
.chatgpt-connection-header {
|
|
1218
|
+
display: flex;
|
|
1219
|
+
justify-content: space-between;
|
|
1220
|
+
align-items: center;
|
|
1221
|
+
margin-bottom: 8px;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
.chatgpt-toggle-switch {
|
|
1225
|
+
background-color: #212121;
|
|
1226
|
+
border: 1px solid #424242;
|
|
1227
|
+
border-radius: 9999px;
|
|
1228
|
+
display: flex;
|
|
1229
|
+
padding: 2px;
|
|
1230
|
+
gap: 2px;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
.chatgpt-toggle-btn {
|
|
1234
|
+
padding: 4px 12px;
|
|
1235
|
+
font-size: 12px;
|
|
1236
|
+
font-weight: 500;
|
|
1237
|
+
border-radius: 9999px;
|
|
1238
|
+
border: none;
|
|
1239
|
+
color: #ececec;
|
|
1240
|
+
background-color: transparent;
|
|
1241
|
+
display: flex;
|
|
1242
|
+
align-items: center;
|
|
1243
|
+
gap: 4px;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
.chatgpt-toggle-btn.active {
|
|
1247
|
+
background-color: #2f2f2f;
|
|
1248
|
+
color: #ffffff;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
.chatgpt-dropdown {
|
|
1252
|
+
width: 100%;
|
|
1253
|
+
background-color: #212121;
|
|
1254
|
+
border: 1px solid #424242;
|
|
1255
|
+
border-radius: 10px;
|
|
1256
|
+
padding: 10px 14px;
|
|
1257
|
+
color: #ececec;
|
|
1258
|
+
font-size: 14.5px;
|
|
1259
|
+
appearance: none;
|
|
1260
|
+
outline: none;
|
|
1261
|
+
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b4b4b4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
|
|
1262
|
+
background-repeat: no-repeat;
|
|
1263
|
+
background-position: right 14px center;
|
|
1264
|
+
background-size: 16px;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
.chatgpt-risk-alert {
|
|
1268
|
+
background-color: #2c1e16;
|
|
1269
|
+
border: 1px solid #573a21;
|
|
1270
|
+
border-radius: 12px;
|
|
1271
|
+
padding: 16px;
|
|
1272
|
+
margin-bottom: 24px;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
.chatgpt-risk-header {
|
|
1276
|
+
display: flex;
|
|
1277
|
+
align-items: flex-start;
|
|
1278
|
+
gap: 10px;
|
|
1279
|
+
font-size: 14px;
|
|
1280
|
+
font-weight: 500;
|
|
1281
|
+
color: #f5c096;
|
|
1282
|
+
margin-bottom: 12px;
|
|
1283
|
+
line-height: 1.4;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
.chatgpt-risk-header a {
|
|
1287
|
+
color: #f5c096;
|
|
1288
|
+
text-decoration: underline;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
.chatgpt-risk-checkbox-wrapper {
|
|
1292
|
+
background-color: #171717;
|
|
1293
|
+
border: 1px solid #2f2f2f;
|
|
1294
|
+
border-radius: 8px;
|
|
1295
|
+
padding: 14px;
|
|
1296
|
+
display: flex;
|
|
1297
|
+
align-items: flex-start;
|
|
1298
|
+
gap: 12px;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
.chatgpt-checkbox {
|
|
1302
|
+
width: 16px;
|
|
1303
|
+
height: 16px;
|
|
1304
|
+
accent-color: #10a37f;
|
|
1305
|
+
margin-top: 3px;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
.chatgpt-risk-checkbox-text {
|
|
1309
|
+
display: flex;
|
|
1310
|
+
flex-direction: column;
|
|
1311
|
+
gap: 4px;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
.chatgpt-checkbox-label {
|
|
1315
|
+
font-size: 13.5px;
|
|
1316
|
+
font-weight: 600;
|
|
1317
|
+
color: #ececec;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
.chatgpt-checkbox-desc {
|
|
1321
|
+
font-size: 12.5px;
|
|
1322
|
+
color: #b4b4b4;
|
|
1323
|
+
line-height: 1.4;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
.chatgpt-dialog-footer {
|
|
1327
|
+
display: flex;
|
|
1328
|
+
justify-content: space-between;
|
|
1329
|
+
align-items: center;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
.chatgpt-guide-link {
|
|
1333
|
+
font-size: 13.5px;
|
|
1334
|
+
color: #b4b4b4;
|
|
1335
|
+
text-decoration: none;
|
|
1336
|
+
display: flex;
|
|
1337
|
+
align-items: center;
|
|
1338
|
+
gap: 6px;
|
|
1148
1339
|
transition: color 0.2s;
|
|
1149
1340
|
}
|
|
1150
|
-
|
|
1151
|
-
.
|
|
1152
|
-
color:
|
|
1341
|
+
|
|
1342
|
+
.chatgpt-guide-link:hover {
|
|
1343
|
+
color: #ececec;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
.chatgpt-btn-create {
|
|
1347
|
+
background-color: #ffffff;
|
|
1348
|
+
color: #000000;
|
|
1349
|
+
padding: 8px 20px;
|
|
1350
|
+
font-size: 13.5px;
|
|
1351
|
+
font-weight: 600;
|
|
1352
|
+
border-radius: 9999px;
|
|
1353
|
+
border: none;
|
|
1354
|
+
transition: background-color 0.2s;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/* Claude Custom Connector Mockup Styles */
|
|
1358
|
+
.claude-dialog-container {
|
|
1359
|
+
background-color: #201f1d;
|
|
1360
|
+
border: 1px solid #2d2c29;
|
|
1361
|
+
border-radius: 12px;
|
|
1362
|
+
padding: 24px;
|
|
1363
|
+
width: 100%;
|
|
1364
|
+
max-width: 500px;
|
|
1365
|
+
color: #e3e2e0;
|
|
1366
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
1367
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
|
|
1368
|
+
margin: 1.5rem auto;
|
|
1369
|
+
position: relative;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
.claude-dialog-header {
|
|
1373
|
+
display: flex;
|
|
1374
|
+
justify-content: space-between;
|
|
1375
|
+
align-items: center;
|
|
1376
|
+
margin-bottom: 16px;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
.claude-dialog-title-container {
|
|
1380
|
+
display: flex;
|
|
1381
|
+
align-items: center;
|
|
1382
|
+
gap: 8px;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
.claude-dialog-title {
|
|
1386
|
+
font-size: 20px;
|
|
1387
|
+
font-weight: 600;
|
|
1388
|
+
color: #f5f4f2;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
.claude-beta-badge {
|
|
1392
|
+
background-color: #383733;
|
|
1393
|
+
color: #8c8a84;
|
|
1394
|
+
font-size: 11px;
|
|
1395
|
+
font-weight: 700;
|
|
1396
|
+
padding: 2px 6px;
|
|
1397
|
+
border-radius: 4px;
|
|
1398
|
+
letter-spacing: 0.5px;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
.claude-close-btn {
|
|
1402
|
+
color: #8c8a84;
|
|
1403
|
+
cursor: pointer;
|
|
1404
|
+
display: flex;
|
|
1405
|
+
align-items: center;
|
|
1406
|
+
justify-content: center;
|
|
1407
|
+
width: 24px;
|
|
1408
|
+
height: 24px;
|
|
1409
|
+
border-radius: 4px;
|
|
1410
|
+
transition: background-color 0.2s;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
.claude-close-btn:hover {
|
|
1414
|
+
background-color: #2d2c29;
|
|
1415
|
+
color: #f5f4f2;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
.claude-dialog-desc {
|
|
1419
|
+
font-size: 13.5px;
|
|
1420
|
+
line-height: 1.5;
|
|
1421
|
+
color: #9b9993;
|
|
1422
|
+
margin-bottom: 20px;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
.claude-dialog-desc a {
|
|
1426
|
+
color: #58a6ff;
|
|
1153
1427
|
text-decoration: underline;
|
|
1154
1428
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
.header {
|
|
1162
|
-
padding: 3rem 1.5rem;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
.header h1 {
|
|
1166
|
-
font-size: 2.25rem;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
.content {
|
|
1170
|
-
padding: 2rem 1.5rem;
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
.section h2 {
|
|
1174
|
-
font-size: 1.75rem;
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
.tools-grid {
|
|
1178
|
-
grid-template-columns: 1fr;
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
.connection-info {
|
|
1182
|
-
padding: 1.5rem;
|
|
1183
|
-
}
|
|
1429
|
+
|
|
1430
|
+
.claude-input-group {
|
|
1431
|
+
display: flex;
|
|
1432
|
+
flex-direction: column;
|
|
1433
|
+
gap: 12px;
|
|
1434
|
+
margin-bottom: 20px;
|
|
1184
1435
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
:
|
|
1188
|
-
|
|
1189
|
-
--foreground: hsl(210, 40%, 98%);
|
|
1190
|
-
--primary: hsl(217, 91%, 60%);
|
|
1191
|
-
--secondary: hsl(217.2, 32.6%, 17.5%);
|
|
1192
|
-
--muted: hsl(217.2, 32.6%, 17.5%);
|
|
1193
|
-
--muted-foreground: hsl(215, 20.2%, 65.1%);
|
|
1194
|
-
--border: hsl(217.2, 32.6%, 17.5%);
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
.connection-info code {
|
|
1198
|
-
background: hsl(217.2, 32.6%, 17.5%);
|
|
1199
|
-
color: hsl(142, 76%, 56%);
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
.tool-schema pre {
|
|
1203
|
-
background: hsl(217.2, 32.6%, 17.5%);
|
|
1204
|
-
color: hsl(142, 76%, 56%);
|
|
1205
|
-
}
|
|
1436
|
+
|
|
1437
|
+
.claude-input-wrapper {
|
|
1438
|
+
position: relative;
|
|
1439
|
+
width: 100%;
|
|
1206
1440
|
}
|
|
1441
|
+
|
|
1442
|
+
.claude-input {
|
|
1443
|
+
width: 100%;
|
|
1444
|
+
background-color: #2c2b27;
|
|
1445
|
+
border: 1px solid #3c3b37;
|
|
1446
|
+
border-radius: 8px;
|
|
1447
|
+
padding: 12px 14px;
|
|
1448
|
+
color: #f5f4f2;
|
|
1449
|
+
font-size: 14px;
|
|
1450
|
+
outline: none;
|
|
1451
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
.claude-input::placeholder {
|
|
1455
|
+
color: #706e67;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.claude-input.active-input {
|
|
1459
|
+
border-color: #3890ff;
|
|
1460
|
+
box-shadow: 0 0 0 1px #3890ff;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
.claude-input.active-input {
|
|
1464
|
+
padding-right: 75px;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
.claude-input-wrapper .btn-copy-input {
|
|
1468
|
+
position: absolute;
|
|
1469
|
+
right: 10px;
|
|
1470
|
+
top: 50%;
|
|
1471
|
+
transform: translateY(-50%);
|
|
1472
|
+
background: rgba(255, 255, 255, 0.05);
|
|
1473
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
1474
|
+
color: #e3e2e0;
|
|
1475
|
+
padding: 4px 8px;
|
|
1476
|
+
font-size: 11px;
|
|
1477
|
+
border-radius: 4px;
|
|
1478
|
+
cursor: pointer;
|
|
1479
|
+
transition: all 0.2s;
|
|
1480
|
+
z-index: 2;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
.claude-input-wrapper .btn-copy-input:hover {
|
|
1484
|
+
background: rgba(255, 255, 255, 0.15);
|
|
1485
|
+
border-color: rgba(255, 255, 255, 0.25);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
.claude-advanced-toggle {
|
|
1489
|
+
display: flex;
|
|
1490
|
+
align-items: center;
|
|
1491
|
+
gap: 6px;
|
|
1492
|
+
font-size: 13.5px;
|
|
1493
|
+
font-weight: 500;
|
|
1494
|
+
color: #e3e2e0;
|
|
1495
|
+
margin-bottom: 24px;
|
|
1496
|
+
user-select: none;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
.claude-dialog-caution {
|
|
1500
|
+
font-size: 12px;
|
|
1501
|
+
line-height: 1.5;
|
|
1502
|
+
color: #8c8a84;
|
|
1503
|
+
margin-bottom: 20px;
|
|
1504
|
+
padding-top: 4px;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
.claude-dialog-footer-text {
|
|
1508
|
+
font-size: 12px;
|
|
1509
|
+
color: #8c8a84;
|
|
1510
|
+
margin-bottom: 24px;
|
|
1511
|
+
border-top: 1px solid #2d2c29;
|
|
1512
|
+
padding-top: 16px;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
.claude-dialog-footer-text a {
|
|
1516
|
+
color: #58a6ff;
|
|
1517
|
+
text-decoration: underline;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
.claude-dialog-actions {
|
|
1521
|
+
display: flex;
|
|
1522
|
+
justify-content: flex-end;
|
|
1523
|
+
gap: 12px;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
.claude-btn {
|
|
1527
|
+
padding: 8px 16px;
|
|
1528
|
+
font-size: 13.5px;
|
|
1529
|
+
font-weight: 500;
|
|
1530
|
+
border-radius: 8px;
|
|
1531
|
+
cursor: pointer;
|
|
1532
|
+
border: none;
|
|
1533
|
+
transition: all 0.2s;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
.claude-btn-cancel {
|
|
1537
|
+
background-color: #2c2b27;
|
|
1538
|
+
color: #e3e2e0;
|
|
1539
|
+
border: 1px solid #3c3b37;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
.claude-btn-cancel:hover {
|
|
1543
|
+
background-color: #383733;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
.claude-btn-add {
|
|
1547
|
+
background-color: #e3e2e0;
|
|
1548
|
+
color: #161513;
|
|
1549
|
+
cursor: default;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1207
1552
|
</style>
|
|
1208
1553
|
</head>
|
|
1209
1554
|
<body>
|
|
1210
|
-
<div class="
|
|
1211
|
-
<div class="
|
|
1212
|
-
|
|
1555
|
+
<div class="wrapper">
|
|
1556
|
+
<div class="controls">
|
|
1557
|
+
<button class="btn-toggle" onclick="toggleTheme()" id="theme-btn">
|
|
1558
|
+
<!-- Sun icon (shown in dark theme) -->
|
|
1559
|
+
<svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:1.15rem;height:1.15rem;">
|
|
1560
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
|
|
1561
|
+
</svg>
|
|
1562
|
+
<!-- Moon icon (shown in light theme) -->
|
|
1563
|
+
<svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:1.15rem;height:1.15rem;">
|
|
1564
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
|
|
1565
|
+
</svg>
|
|
1566
|
+
<span>Toggle Theme</span>
|
|
1567
|
+
</button>
|
|
1568
|
+
</div>
|
|
1569
|
+
|
|
1570
|
+
<header>
|
|
1213
1571
|
<div class="logo-container">
|
|
1214
|
-
<img src="data:image/png;base64,${this.logoBase64}" alt="
|
|
1572
|
+
<img src="data:image/png;base64,${this.logoBase64 || DEFAULT_LOGO_BASE64}" alt="Logo" class="logo">
|
|
1215
1573
|
</div>
|
|
1216
|
-
|
|
1217
|
-
<
|
|
1218
|
-
<
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1574
|
+
<h1 class="title">${serverName}</h1>
|
|
1575
|
+
<span class="version-badge">v${serverVersion}</span>
|
|
1576
|
+
<p class="description">${serverDescription}</p>
|
|
1577
|
+
</header>
|
|
1578
|
+
|
|
1579
|
+
<div class="connection-panel">
|
|
1580
|
+
<div class="section-title">
|
|
1581
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:1.25rem;height:1.25rem;color:var(--primary);">
|
|
1582
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21m-9-1.5h10.5a2.25 2.25 0 0 0 2.25-2.25V6.75a2.25 2.25 0 0 0-2.25-2.25H6.75A2.25 2.25 0 0 0 4.5 6.75v10.5a2.25 2.25 0 0 0 2.25 2.25Zm.75-12h9v9h-9v-9Z" />
|
|
1583
|
+
</svg>
|
|
1584
|
+
<span>Connection Setup</span>
|
|
1585
|
+
</div>
|
|
1586
|
+
|
|
1587
|
+
<div class="tab-header">
|
|
1588
|
+
<button class="tab-btn active" onclick="switchTab('cursor')">
|
|
1589
|
+
<svg fill="none" height="14" viewBox="0 0 545 545" width="14" xmlns="http://www.w3.org/2000/svg" style="color: currentColor;"><g fill="currentColor"><path d="m466.383 137.073-206.469-119.2034c-6.63-3.8287-14.811-3.8287-21.441 0l-206.4586 119.2034c-5.5734 3.218-9.0144 9.169-9.0144 15.615v240.375c0 6.436 3.441 12.397 9.0144 15.615l206.4686 119.203c6.63 3.829 14.811 3.829 21.441 0l206.468-119.203c5.574-3.218 9.015-9.17 9.015-15.615v-240.375c0-6.436-3.441-12.397-9.015-15.615zm-12.969 25.25-199.316 345.223c-1.347 2.326-4.904 1.376-4.904-1.319v-226.048c0-4.517-2.414-8.695-6.33-10.963l-195.7577-113.019c-2.3263-1.347-1.3764-4.905 1.3182-4.905h398.6305c5.661 0 9.199 6.136 6.368 11.041h-.009z"></path></g></svg>
|
|
1590
|
+
<span>Cursor</span>
|
|
1591
|
+
</button>
|
|
1592
|
+
<button class="tab-btn" onclick="switchTab('claude')">
|
|
1593
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="currentColor" role="img" aria-label="Claude Logo"><path d="M11.376 24L10.776 23.544L10.44 22.8L10.776 21.312L11.16 19.392L11.472 17.856L11.76 15.96L11.928 15.336L11.904 15.288L11.784 15.312L10.344 17.28L8.16 20.232L6.432 22.056L6.024 22.224L5.304 21.864L5.376 21.192L5.784 20.616L8.16 17.568L9.6 15.672L10.536 14.592L10.512 14.448H10.464L4.128 18.576L3 18.72L2.496 18.264L2.568 17.52L2.808 17.28L4.704 15.96L9.432 13.32L9.504 13.08L9.432 12.96H9.192L8.4 12.912L5.712 12.84L3.384 12.744L1.104 12.624L0.528 12.504L0 11.784L0.048 11.424L0.528 11.112L1.224 11.16L2.736 11.28L5.016 11.424L6.672 11.52L9.12 11.784H9.504L9.552 11.616L9.432 11.52L9.336 11.424L6.96 9.84L4.416 8.16L3.072 7.176L2.352 6.672L1.992 6.216L1.848 5.208L2.496 4.488L3.384 4.56L3.6 4.608L4.488 5.304L6.384 6.768L8.88 8.616L9.24 8.904L9.408 8.808V8.736L9.24 8.472L7.896 6.024L6.456 3.528L5.808 2.496L5.64 1.872C5.576 1.656 5.544 1.416 5.544 1.152L6.288 0.144001L6.696 0L7.704 0.144001L8.112 0.504001L8.736 1.92L9.72 4.152L11.28 7.176L11.736 8.088L11.976 8.904L12.072 9.168H12.24V9.024L12.36 7.296L12.6 5.208L12.84 2.52L12.912 1.752L13.296 0.840001L14.04 0.360001L14.616 0.624001L15.096 1.32L15.024 1.752L14.76 3.6L14.184 6.504L13.824 8.472H14.04L14.28 8.208L15.264 6.912L16.92 4.848L17.64 4.032L18.504 3.12L19.056 2.688H20.088L20.832 3.816L20.496 4.992L19.44 6.336L18.552 7.464L17.28 9.168L16.512 10.536L16.584 10.632H16.752L19.608 10.008L21.168 9.744L22.992 9.432L23.832 9.816L23.928 10.2L23.592 11.016L21.624 11.496L19.32 11.952L15.888 12.768L15.84 12.792L15.888 12.864L17.424 13.008L18.096 13.056H19.728L22.752 13.272L23.544 13.8L24 14.424L23.928 14.928L22.704 15.528L21.072 15.144L17.232 14.232L15.936 13.92H15.744V14.016L16.848 15.096L18.84 16.896L21.36 19.224L21.48 19.8L21.168 20.28L20.832 20.232L18.624 18.552L17.76 17.808L15.84 16.2H15.72V16.368L16.152 17.016L18.504 20.544L18.624 21.624L18.456 21.96L17.832 22.176L17.184 22.056L15.792 20.136L14.376 17.952L13.224 16.008L13.104 16.104L12.408 23.352L12.096 23.712L11.376 24Z" fill="var(--cds-clay, #d97757)"/></svg>
|
|
1594
|
+
<span>Claude</span>
|
|
1595
|
+
</button>
|
|
1596
|
+
<button class="tab-btn" onclick="switchTab('chatgpt')">
|
|
1597
|
+
<svg height="14" style="flex:none;line-height:1;" viewBox="56.632 381.702 264.715 264.715" width="14" xmlns="http://www.w3.org/2000/svg">
|
|
1598
|
+
<path d="m56.692 529c.002-31.163-.027-61.826.016-92.489.044-30.7 24.229-54.79 54.984-54.797 51.994-.012 103.987.007 155.981.01 32.903.002 56.654 23.087 56.888 56.08.352 49.488.21 98.98.327 148.47.037 15.998-3.376 30.764-14.775 42.775-10.442 11.003-22.98 17.351-38.432 17.344-53.993-.026-107.987.024-161.98-.013-28.704-.02-52.881-24.156-52.989-52.888-.08-21.33-.018-42.661-.02-64.492m36.914-50.872c-7.633 18.562-5.244 35.834 6.913 51.7 1.914 2.498 1.663 4.727 1.072 7.443-7.58 34.81 20.365 66.036 55.857 62.182 3.99-.433 6.435.593 9.239 3.098 26.543 23.72 68.247 14.479 82.183-18.214 1.349-3.165 3.428-4.465 6.471-5.449 34.93-11.295 47.479-50.421 25.601-79.873-1.785-2.404-2.227-4.494-1.388-7.337 1.97-6.67 1.973-13.618.775-20.32-4.99-27.924-30.653-45.673-57.108-42.222-3.144.41-5.646-.188-8.159-2.485-26.77-24.472-68.24-15.636-82.938 17.639-1.18 2.672-2.706 4.202-5.573 5.04-15.09 4.416-25.921 13.898-32.945 28.798" fill="#000000"></path>
|
|
1599
|
+
<path d="m245.218 509.808c-15.135-8.685-29.953-17.184-46.113-26.452 6.742-3.74 12.165-6.834 17.681-9.75 1.475-.78 2.876.338 4.176 1.08 13.457 7.68 27.148 14.98 40.32 23.12 25.06 15.487 23.505 52.57-2.541 66.43-1.434.763-2.837 1.784-4.692 1.4-1.756-1.571-1.185-3.696-1.193-5.608-.053-12.5-.352-25.01.107-37.494.229-6.212-1.728-10.264-7.745-12.726zm-128.085 56.862c-3.736-7.812-5.599-15.525-3.8-23.69 2.342-.773 3.61.582 4.99 1.362 11.595 6.56 23.268 12.994 34.68 19.86 4.433 2.667 8.064 2.664 12.471.073 13.78-8.102 27.733-15.913 41.643-23.793 1.67-.946 3.174-2.519 6.083-1.853 0 5.986.083 12.084-.049 18.177-.04 1.868-1.785 2.654-3.245 3.49-12.716 7.278-25.349 14.707-38.156 21.821-19.901 11.054-42.145 4.788-54.617-15.446z" fill="#ffffff"></path>
|
|
1600
|
+
<path d="m117.717 529.358c-13.198-10.171-18.667-26.341-14.275-41.551 3.646-12.626 14.622-23.998 24.016-24.838 1.291 1.587.763 3.495.77 5.261.053 13.164.202 26.332-.05 39.491-.093 4.79 1.623 7.69 5.78 9.986 13.851 7.65 27.562 15.557 41.287 23.433 1.824 1.046 3.995 1.722 5.547 4.432-5.261 3.649-10.826 6.757-16.63 9.448-1.315.61-2.609-.302-3.75-.96a13870.218 13870.218 0 0 1 -42.695-24.702zm72.803-50.784a58896.5 58896.5 0 0 1 -22.557 12.779c0-7.475-.073-13.685.056-19.891.03-1.408 1.452-2.147 2.625-2.812 13.91-7.89 27.554-16.302 41.791-23.548 26.078-13.273 57.24 7.383 55.845 36.599-.062 1.313.021 2.664-.89 3.822-2.293.758-3.803-.92-5.44-1.844-11.319-6.386-22.644-12.764-33.828-19.379-4.35-2.573-8.163-2.735-12.567-.06-8.11 4.928-16.465 9.455-25.035 14.334zm35.846 115.859c-16.363 11.937-39.942 11.684-49.18-.522 2.317-2.674 5.63-3.979 8.58-5.7 10.215-5.96 20.483-11.834 30.835-17.552 3.635-2.008 5.192-4.683 5.16-8.84-.123-16.33-.06-32.66-.008-48.99.006-1.749-.563-3.658 1.184-5.707 5.742 2.282 10.879 5.914 16.22 9.127 1.457.876 1.21 2.636 1.209 4.127-.008 15.663.262 31.333-.145 46.986-.284 10.874-5.38 19.75-13.855 27.071z" fill="#ffffff"></path>
|
|
1601
|
+
<path d="m146.524 443.67c14.8-23.755 46.36-21.857 57.2-9.16-2.357 2.921-5.88 4.134-8.975 5.937-9.918 5.778-19.777 11.67-29.86 17.148-4.062 2.207-5.672 5.044-5.633 9.55.136 15.976.067 31.953.022 47.93-.006 1.947.48 3.992-1.07 6.573-5.68-2.855-11.26-5.933-16.504-9.609-1.373-.962-.998-2.737-.998-4.208-.006-15.31-.067-30.622.068-45.932.056-6.466 2.349-12.362 5.75-18.23z" fill="#ffffff"></path>
|
|
1602
|
+
<path d="m191.565 539.596c-8.515-2.437-15.28-7.635-22.575-11.831-1.463-.842-1.265-2.609-1.269-4.102-.014-6.155.096-12.312-.052-18.463-.07-2.874 1.065-4.61 3.542-5.951a450.21 450.21 0 0 0 16.035-9.14c2.255-1.344 4.233-1.398 6.502-.06 5.442 3.21 10.924 6.357 16.482 9.361 2.397 1.296 3.133 3.114 3.093 5.688-.095 6.153-.15 12.312.035 18.461.088 2.946-1.214 4.563-3.632 5.882-5.982 3.264-11.884 6.676-18.16 10.155z" fill="#ffffff"></path>
|
|
1603
|
+
</svg>
|
|
1604
|
+
<span>ChatGPT</span>
|
|
1605
|
+
</button>
|
|
1606
|
+
<button class="tab-btn" onclick="switchTab('antigravity')">
|
|
1607
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="14" viewBox="0 0 24 24" width="14" style="flex:none;line-height:1;color:currentColor;"><title>Antigravity</title><mask height="23" id="lobe-icons-antigravity-0-_R_0_" maskUnits="userSpaceOnUse" width="24" x="0" y="1"><path d="M21.751 22.607c1.34 1.005 3.35.335 1.508-1.508C17.73 15.74 18.904 1 12.037 1 5.17 1 6.342 15.74.815 21.1c-2.01 2.009.167 2.511 1.507 1.506 5.192-3.517 4.857-9.714 9.715-9.714 4.857 0 4.522 6.197 9.714 9.715z" fill="#fff"/></mask><g mask="url(#lobe-icons-antigravity-0-_R_0_)"><g filter="url(#lobe-icons-antigravity-1-_R_0_)"><path d="M-1.018-3.992c-.408 3.591 2.686 6.89 6.91 7.37 4.225.48 7.98-2.043 8.387-5.633.408-3.59-2.686-6.89-6.91-7.37-4.225-.479-7.98 2.043-8.387 5.633z" fill="#FFE432"/></g><g filter="url(#lobe-icons-antigravity-2-_R_0_)"><path d="M15.269 7.747c1.058 4.557 5.691 7.374 10.348 6.293 4.657-1.082 7.575-5.653 6.516-10.21-1.058-4.556-5.691-7.374-10.348-6.292-4.657 1.082-7.575 5.653-6.516 10.21z" fill="#FC413D"/></g><g filter="url(#lobe-icons-antigravity-3-_R_0_)"><path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"/></g><g filter="url(#lobe-icons-antigravity-4-_R_0_)"><path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"/></g><g filter="url(#lobe-icons-antigravity-5-_R_0_)"><path d="M-7.608 14.703c3.352 3.424 9.126 3.208 12.896-.483 3.77-3.69 4.108-9.459.756-12.883C2.69-2.087-3.083-1.871-6.853 1.82c-3.77 3.69-4.108 9.458-.755 12.883z" fill="#00B95C"/></g><g filter="url(#lobe-icons-antigravity-6-_R_0_)"><path d="M9.932 27.617c1.04 4.482 5.384 7.303 9.7 6.3 4.316-1.002 6.971-5.448 5.93-9.93-1.04-4.483-5.384-7.304-9.7-6.301-4.316 1.002-6.971 5.448-5.93 9.93z" fill="#3186FF"/></g><g filter="url(#lobe-icons-antigravity-7-_R_0_)"><path d="M2.572-8.185C.392-3.329 2.778 2.472 7.9 4.771c5.122 2.3 11.042.227 13.222-4.63 2.18-4.855-.205-10.656-5.327-12.955-5.122-2.3-11.042-.227-13.222 4.63z" fill="#FBBC04"/></g><g filter="url(#lobe-icons-antigravity-8-_R_0_)"><path d="M-3.267 38.686c-5.277-2.072 3.742-19.117 5.984-24.83 2.243-5.712 8.34-8.664 13.616-6.592 5.278 2.071 11.533 13.482 9.29 19.195-2.242 5.713-23.613 14.298-28.89 12.227z" fill="#3186FF"/></g><g filter="url(#lobe-icons-antigravity-9-_R_0_)"><path d="M28.71 17.471c-1.413 1.649-5.1.808-8.236-1.878-3.135-2.687-4.531-6.201-3.118-7.85 1.412-1.649 5.1-.808 8.235 1.878s4.532 6.2 3.119 7.85z" fill="#749BFF"/></g><g filter="url(#lobe-icons-antigravity-10-_R_0_)"><path d="M18.163 9.077c5.81 3.93 12.502 4.19 14.946.577 2.443-3.612-.287-9.727-6.098-13.658-5.81-3.931-12.502-4.19-14.946-.577-2.443 3.612.287 9.727 6.098 13.658z" fill="#FC413D"/></g><g filter="url(#lobe-icons-antigravity-11-_R_0_)"><path d="M-.915 2.684c-1.44 3.473-.97 6.967 1.05 7.804 2.02.837 4.824-1.3 6.264-4.772 1.44-3.473.97-6.967-1.05-7.804-2.02-.837-4.824 1.3-6.264 4.772z" fill="#FFEE48"/></g></g><defs><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="17.587" id="lobe-icons-antigravity-1-_R_0_" width="19.838" x="-3.288" y="-11.917"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="1.117"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="38.565" id="lobe-icons-antigravity-2-_R_0_" width="38.9" x="4.251" y="-13.493"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="5.4"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="lobe-icons-antigravity-3-_R_0_" width="40.955" x="-21.889" y="-10.592"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="lobe-icons-antigravity-4-_R_0_" width="40.955" x="-21.889" y="-10.592"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.595" id="lobe-icons-antigravity-5-_R_0_" width="36.632" x="-19.099" y="-10.278"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="34.087" id="lobe-icons-antigravity-6-_R_0_" width="33.533" x=".981" y="8.758"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.363"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="35.276" id="lobe-icons-antigravity-7-_R_0_" width="35.978" x="-6.143" y="-21.659"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.954"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="46.523" id="lobe-icons-antigravity-8-_R_0_" width="45.114" x="-11.96" y="-.46"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.531"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="24.054" id="lobe-icons-antigravity-9-_R_0_" width="25.094" x="10.485" y=".58"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.159"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="30.007" id="lobe-icons-antigravity-10-_R_0_" width="33.508" x="5.833" y="-12.467"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="2.669"/></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="26.151" id="lobe-icons-antigravity-11-_R_0_" width="22.194" x="-8.355" y="-8.876"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.303"/></filter></defs></svg>
|
|
1608
|
+
<span>Antigravity</span>
|
|
1609
|
+
</button>
|
|
1610
|
+
<button class="tab-btn" onclick="switchTab('codex')">
|
|
1611
|
+
<svg height="14" style="flex:none;line-height:1" viewBox="0 0 24 24" width="14" xmlns="http://www.w3.org/2000/svg"><title>Codex</title><path d="M19.503 0H4.496A4.496 4.496 0 000 4.496v15.007A4.496 4.496 0 004.496 24h15.007A4.496 4.496 0 0024 19.503V4.496A4.496 4.496 0 0019.503 0z" fill="var(--codex-badge-bg)"></path><path d="M9.064 3.344a4.578 4.578 0 012.285-.312c1 .115 1.891.54 2.673 1.275.01.01.024.017.037.021a.09.09 0 00.043 0 4.55 4.55 0 013.046.275l.047.022.116.057a4.581 4.581 0 012.188 2.399c.209.51.313 1.041.315 1.595a4.24 4.24 0 01-.134 1.223.123.123 0 00.03.115c.594.607.988 1.33 1.183 2.17.289 1.425-.007 2.71-.887 3.854l-.136.166a4.548 4.548 0 01-2.201 1.388.123.123 0 00-.081.076c-.191.551-.383 1.023-.74 1.494-.9 1.187-2.222 1.846-3.711 1.838-1.187-.006-2.239-.44-3.157-1.302a.107.107 0 00-.105-.024c-.388.125-.78.143-1.204.138a4.441 4.441 0 01-1.945-.466 4.544 4.544 0 01-1.61-1.335c-.152-.202-.303-.392-.414-.617a5.81 5.81 0 01-.37-.961 4.582 4.582 0 01-.014-2.298.124.124 0 00.006-.056.085.085 0 00-.027-.048 4.467 4.467 0 01-1.034-1.651 3.896 3.896 0 01-.251-1.192 5.189 5.189 0 01.141-1.6c.337-1.112.982-1.985 1.933-2.618.212-.141.413-.251.601-.33.215-.089.43-.164.646-.227a.098.098 0 00.065-.066 4.51 4.51 0 01.829-1.615 4.535 4.535 0 011.837-1.388zm3.482 10.565a.637.637 0 000 1.272h3.636a.637.637 0 100-1.272h-3.636zM8.462 9.23a.637.637 0 00-1.106.631l1.272 2.224-1.266 2.136a.636.636 0 101.095.649l1.454-2.455a.636.636 0 00.005-.64L8.462 9.23z" fill="url(#lobe-icons-codex-_R_0_)"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-codex-_R_0_" x1="12" x2="12" y1="3" y2="21"><stop stop-color="#B1A7FF"></stop><stop offset=".5" stop-color="#7A9DFF"></stop><stop offset="1" stop-color="#3941FF"></stop></linearGradient></defs></svg>
|
|
1612
|
+
<span>Codex</span>
|
|
1613
|
+
</button>
|
|
1614
|
+
<button class="tab-btn" onclick="switchTab('sse')">Raw SSE</button>
|
|
1615
|
+
</div>
|
|
1616
|
+
|
|
1617
|
+
<!-- Cursor Connection Tab -->
|
|
1618
|
+
<div class="tab-content active" id="tab-cursor">
|
|
1619
|
+
<p style="font-size: 0.9rem; margin-bottom: 0.75rem; color: var(--text-muted);">
|
|
1620
|
+
Add via Cursor Settings UI (<strong>Settings > Features > MCP > Add New MCP Server</strong>):
|
|
1621
|
+
</p>
|
|
1622
|
+
<div class="code-container">
|
|
1623
|
+
<button class="btn-copy" onclick="copyText('cursor-config')">Copy JSON</button>
|
|
1624
|
+
<pre id="cursor-config">{
|
|
1625
|
+
"mcpServers": {
|
|
1626
|
+
// your other mcp servers
|
|
1627
|
+
"${serverName.toLowerCase().replace(/\s+/g, '-')}": {
|
|
1628
|
+
"url": "${mcpEndpoint}"
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}</pre>
|
|
1231
1632
|
</div>
|
|
1232
1633
|
</div>
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
<details class="tool-schema">
|
|
1247
|
-
<summary>Input Schema</summary>
|
|
1248
|
-
<pre>${this.escapeHtml(JSON.stringify(tool.inputSchema, null, 2))}</pre>
|
|
1249
|
-
</details>
|
|
1250
|
-
` : ''}
|
|
1251
|
-
</div>
|
|
1252
|
-
`).join('')}
|
|
1634
|
+
|
|
1635
|
+
<!-- Claude Connection Tab -->
|
|
1636
|
+
<div class="tab-content" id="tab-claude">
|
|
1637
|
+
<p style="font-size: 0.9rem; margin-bottom: 1rem; color: var(--text-muted);">
|
|
1638
|
+
Connect remote tools directly via Claude's Web UI:
|
|
1639
|
+
</p>
|
|
1640
|
+
|
|
1641
|
+
<div class="claude-dialog-container">
|
|
1642
|
+
<div class="claude-dialog-header">
|
|
1643
|
+
<div class="claude-dialog-title-container">
|
|
1644
|
+
<span class="claude-dialog-title">Add custom connector</span>
|
|
1645
|
+
<span class="claude-beta-badge">BETA</span>
|
|
1646
|
+
</div>
|
|
1253
1647
|
</div>
|
|
1254
|
-
|
|
1255
|
-
<div class="
|
|
1256
|
-
<
|
|
1257
|
-
|
|
1648
|
+
|
|
1649
|
+
<div class="claude-dialog-desc">
|
|
1650
|
+
Connect Claude to your data and tools. <a href="https://support.anthropic.com" target="_blank">Learn more about connectors</a> or get started with <a href="https://support.anthropic.com" target="_blank">pre-built ones</a>.
|
|
1651
|
+
</div>
|
|
1652
|
+
|
|
1653
|
+
<div class="claude-input-group">
|
|
1654
|
+
<div class="claude-input-wrapper">
|
|
1655
|
+
<input type="text" class="claude-input" readonly value="${serverName.toLowerCase().replace(/\s+/g, '-')}">
|
|
1656
|
+
</div>
|
|
1657
|
+
<div class="claude-input-wrapper">
|
|
1658
|
+
<input type="text" class="claude-input active-input" id="claude-connector-url" readonly value="${mcpEndpoint}">
|
|
1659
|
+
<button class="btn-copy-input" onclick="copyText('claude-connector-url')">Copy</button>
|
|
1660
|
+
</div>
|
|
1661
|
+
</div>
|
|
1662
|
+
|
|
1663
|
+
<div class="claude-advanced-toggle">
|
|
1664
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:12px;height:12px;">
|
|
1665
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
1258
1666
|
</svg>
|
|
1259
|
-
<
|
|
1667
|
+
<span>Advanced settings</span>
|
|
1668
|
+
</div>
|
|
1669
|
+
|
|
1670
|
+
<div class="claude-dialog-caution">
|
|
1671
|
+
Only use connectors from developers you trust. Anthropic does not control which tools developers make available and cannot verify that they will work as intended or that they won't change.
|
|
1672
|
+
</div>
|
|
1673
|
+
|
|
1674
|
+
<div class="claude-dialog-footer-text">
|
|
1675
|
+
Building an MCP server? <a href="https://github.com/modelcontextprotocol" target="_blank">Report issues and subscribe to updates here</a>
|
|
1676
|
+
</div>
|
|
1677
|
+
|
|
1678
|
+
<div class="claude-dialog-actions">
|
|
1679
|
+
<button class="claude-btn claude-btn-add">Add</button>
|
|
1260
1680
|
</div>
|
|
1261
|
-
|
|
1681
|
+
</div>
|
|
1262
1682
|
</div>
|
|
1683
|
+
|
|
1684
|
+
<!-- ChatGPT Connection Tab -->
|
|
1685
|
+
<div class="tab-content" id="tab-chatgpt">
|
|
1686
|
+
<p style="font-size: 0.9rem; margin-bottom: 1rem; color: var(--text-muted);">
|
|
1687
|
+
Configure custom tools directly via ChatGPT's Web UI:
|
|
1688
|
+
</p>
|
|
1689
|
+
|
|
1690
|
+
<div class="chatgpt-dialog-container">
|
|
1691
|
+
<div class="chatgpt-dialog-header">
|
|
1692
|
+
<span class="chatgpt-dialog-title">New App</span>
|
|
1693
|
+
</div>
|
|
1694
|
+
|
|
1695
|
+
<div class="chatgpt-section-label">Icon <span style="font-weight: normal; color: #b4b4b4;">(optional)</span></div>
|
|
1696
|
+
<div class="chatgpt-icon-picker">
|
|
1697
|
+
<div class="chatgpt-icon-box">
|
|
1698
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:20px;height:20px;">
|
|
1699
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
|
1700
|
+
</svg>
|
|
1701
|
+
</div>
|
|
1702
|
+
<div class="chatgpt-icon-desc">
|
|
1703
|
+
PNG only. Best results at 256 x 256 px or larger. Max file size: 10 KB
|
|
1704
|
+
</div>
|
|
1705
|
+
</div>
|
|
1706
|
+
|
|
1707
|
+
<div class="chatgpt-input-group">
|
|
1708
|
+
<div class="chatgpt-field">
|
|
1709
|
+
<div class="chatgpt-section-label">Name</div>
|
|
1710
|
+
<input type="text" class="chatgpt-input" readonly value="${serverName.toLowerCase().replace(/\s+/g, '-')}">
|
|
1711
|
+
</div>
|
|
1712
|
+
|
|
1713
|
+
<div class="chatgpt-field">
|
|
1714
|
+
<div class="chatgpt-section-label">Description <span style="font-weight: normal; color: #b4b4b4;">(optional)</span></div>
|
|
1715
|
+
<input type="text" class="chatgpt-input" readonly placeholder="Explain what it does in a few words">
|
|
1716
|
+
</div>
|
|
1717
|
+
|
|
1718
|
+
<div class="chatgpt-field">
|
|
1719
|
+
<div class="chatgpt-connection-header">
|
|
1720
|
+
<div class="chatgpt-section-label" style="margin-bottom: 0;">Connection</div>
|
|
1721
|
+
<div class="chatgpt-toggle-switch">
|
|
1722
|
+
<button class="chatgpt-toggle-btn active">Server URL</button>
|
|
1723
|
+
<button class="chatgpt-toggle-btn">
|
|
1724
|
+
<span>Tunnel</span>
|
|
1725
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:12px;height:12px;color:#b4b4b4;">
|
|
1726
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z" />
|
|
1727
|
+
</svg>
|
|
1728
|
+
</button>
|
|
1729
|
+
</div>
|
|
1730
|
+
</div>
|
|
1731
|
+
<div class="chatgpt-input-wrapper">
|
|
1732
|
+
<input type="text" class="chatgpt-input active-input" id="chatgpt-connector-url" readonly value="${mcpEndpoint}">
|
|
1733
|
+
<button class="btn-copy-input" onclick="copyText('chatgpt-connector-url')">Copy</button>
|
|
1734
|
+
</div>
|
|
1735
|
+
</div>
|
|
1736
|
+
|
|
1737
|
+
<div class="chatgpt-field">
|
|
1738
|
+
<div class="chatgpt-section-label">Authentication</div>
|
|
1739
|
+
<select class="chatgpt-dropdown" disabled>
|
|
1740
|
+
<option>No Auth</option>
|
|
1741
|
+
</select>
|
|
1742
|
+
</div>
|
|
1743
|
+
</div>
|
|
1744
|
+
|
|
1745
|
+
<div class="chatgpt-risk-alert">
|
|
1746
|
+
<div class="chatgpt-risk-header">
|
|
1747
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:20px;height:20px;color:#f59e0b;flex:none;margin-top:1px;">
|
|
1748
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
|
|
1749
|
+
</svg>
|
|
1750
|
+
<span>Custom MCP servers introduce risk. <a href="https://openai.com" target="_blank">Learn more</a></span>
|
|
1751
|
+
</div>
|
|
1752
|
+
|
|
1753
|
+
<div class="chatgpt-risk-checkbox-wrapper">
|
|
1754
|
+
<input type="checkbox" class="chatgpt-checkbox" id="chatgpt-confirm-risk" checked disabled>
|
|
1755
|
+
<div class="chatgpt-risk-checkbox-text">
|
|
1756
|
+
<label class="chatgpt-checkbox-label" for="chatgpt-confirm-risk">I understand and want to continue</label>
|
|
1757
|
+
<span class="chatgpt-checkbox-desc">OpenAI hasn't reviewed this MCP server. Attackers may attempt to steal your data or trick the model into taking unintended actions, including destroying data.</span>
|
|
1758
|
+
</div>
|
|
1759
|
+
</div>
|
|
1760
|
+
</div>
|
|
1761
|
+
|
|
1762
|
+
<div class="chatgpt-dialog-footer">
|
|
1763
|
+
<a class="chatgpt-guide-link" href="https://platform.openai.com/docs" target="_blank">
|
|
1764
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:16px;height:16px;">
|
|
1765
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
|
|
1766
|
+
</svg>
|
|
1767
|
+
<span>Read the guide</span>
|
|
1768
|
+
</a>
|
|
1769
|
+
<button class="chatgpt-btn-create">Create</button>
|
|
1770
|
+
</div>
|
|
1771
|
+
</div>
|
|
1772
|
+
</div>
|
|
1773
|
+
|
|
1774
|
+
<!-- Antigravity Connection Tab -->
|
|
1775
|
+
<div class="tab-content" id="tab-antigravity">
|
|
1776
|
+
<p style="font-size: 0.9rem; margin-bottom: 0.75rem; color: var(--text-muted);">
|
|
1777
|
+
Add the following configuration block under <code>mcpServers</code> in your Antigravity configuration file (<code>~/.gemini/config/mcp_config.json</code>):
|
|
1778
|
+
</p>
|
|
1779
|
+
<div class="code-container">
|
|
1780
|
+
<button class="btn-copy" onclick="copyText('antigravity-config')">Copy JSON</button>
|
|
1781
|
+
<pre id="antigravity-config">{
|
|
1782
|
+
"mcpServers": {
|
|
1783
|
+
// your other mcp servers
|
|
1784
|
+
"${serverName.toLowerCase().replace(/\s+/g, '-')}": {
|
|
1785
|
+
"serverUrl": "${mcpEndpoint}"
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}</pre>
|
|
1789
|
+
</div>
|
|
1790
|
+
</div>
|
|
1791
|
+
|
|
1792
|
+
<!-- Codex Connection Tab -->
|
|
1793
|
+
<div class="tab-content" id="tab-codex">
|
|
1794
|
+
<p style="font-size: 0.9rem; margin-bottom: 0.75rem; color: var(--text-muted);">
|
|
1795
|
+
Add the following configuration block to your Codex configuration file (<code>~/.codex/config.toml</code>):
|
|
1796
|
+
</p>
|
|
1797
|
+
<div class="code-container">
|
|
1798
|
+
<button class="btn-copy" onclick="copyText('codex-config')">Copy TOML</button>
|
|
1799
|
+
<pre id="codex-config">[mcp_servers.${serverName.toLowerCase().replace(/\s+/g, '-')}]
|
|
1800
|
+
url = "${mcpEndpoint}"</pre>
|
|
1801
|
+
</div>
|
|
1802
|
+
</div>
|
|
1803
|
+
|
|
1804
|
+
<!-- Raw SSE Tab -->
|
|
1805
|
+
<div class="tab-content" id="tab-sse">
|
|
1806
|
+
<p style="font-size: 0.9rem; margin-bottom: 0.75rem; color: var(--text-muted);">
|
|
1807
|
+
Connect directly using the Server-Sent Events endpoint:
|
|
1808
|
+
</p>
|
|
1809
|
+
<div class="code-container">
|
|
1810
|
+
<button class="btn-copy" onclick="copyText('sse-endpoint')">Copy Endpoint</button>
|
|
1811
|
+
<pre id="sse-endpoint">${mcpEndpoint}</pre>
|
|
1812
|
+
</div>
|
|
1813
|
+
</div>
|
|
1814
|
+
</div>
|
|
1815
|
+
|
|
1816
|
+
<div class="section-title">
|
|
1817
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:1.25rem;height:1.25rem;color:var(--primary);">
|
|
1818
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M11.42 15.17 17.25 21A2.67 2.67 0 1 1 13.5 17.25l-5.83-5.83m0 0a2.67 2.67 0 1 1-3.75-3.75 2.67 2.67 0 0 1 3.75 3.75Zm5.83 5.83V12m0 0h5.25m-5.25 0V6.75" />
|
|
1819
|
+
</svg>
|
|
1820
|
+
<span>Available Tools</span>
|
|
1821
|
+
</div>
|
|
1822
|
+
|
|
1823
|
+
<div class="search-container">
|
|
1824
|
+
<svg class="search-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
1825
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
1826
|
+
</svg>
|
|
1827
|
+
<input type="text" class="search-input" id="search" placeholder="Search tools by name or description..." oninput="filterTools()">
|
|
1263
1828
|
</div>
|
|
1829
|
+
|
|
1830
|
+
${tools.length > 0 ? `
|
|
1831
|
+
<div class="tools-grid" id="tools-container">
|
|
1832
|
+
${tools.map((tool, idx) => {
|
|
1833
|
+
return `
|
|
1834
|
+
<div class="tool-card" data-name="${this.escapeHtml(tool.name).toLowerCase()}" data-desc="${this.escapeHtml(tool.description || '').toLowerCase()}">
|
|
1835
|
+
<div class="tool-header">
|
|
1836
|
+
<div class="tool-name-container">
|
|
1837
|
+
<span class="tool-name">${this.escapeHtml(tool.name)}</span>
|
|
1838
|
+
</div>
|
|
1839
|
+
</div>
|
|
1840
|
+
<p class="tool-description">${this.escapeHtml(tool.description || 'No description available')}</p>
|
|
1841
|
+
${tool.inputSchema ? `
|
|
1842
|
+
<button class="schema-toggle" onclick="openToolModal(${idx})">
|
|
1843
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:0.9rem;height:0.9rem;">
|
|
1844
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" />
|
|
1845
|
+
</svg>
|
|
1846
|
+
<span>View Input Schema</span>
|
|
1847
|
+
</button>
|
|
1848
|
+
` : ''}
|
|
1849
|
+
</div>
|
|
1850
|
+
`;
|
|
1851
|
+
}).join('')}
|
|
1852
|
+
</div>
|
|
1853
|
+
` : `
|
|
1854
|
+
<div class="empty-state">
|
|
1855
|
+
<p>No tools are currently registered on this server.</p>
|
|
1856
|
+
</div>
|
|
1857
|
+
`}
|
|
1858
|
+
|
|
1859
|
+
<footer>
|
|
1860
|
+
<p>Powered by <a href="https://nitrostack.ai" target="_blank" rel="noopener noreferrer">NitroStack</a> - The TypeScript MCP Framework</p>
|
|
1861
|
+
</footer>
|
|
1862
|
+
</div>
|
|
1863
|
+
|
|
1864
|
+
<script>
|
|
1865
|
+
// Theme Toggle State
|
|
1866
|
+
function toggleTheme() {
|
|
1867
|
+
const html = document.documentElement;
|
|
1868
|
+
if (html.classList.contains('light')) {
|
|
1869
|
+
html.classList.remove('light');
|
|
1870
|
+
html.classList.add('dark');
|
|
1871
|
+
localStorage.setItem('theme', 'dark');
|
|
1872
|
+
} else {
|
|
1873
|
+
html.classList.remove('dark');
|
|
1874
|
+
html.classList.add('light');
|
|
1875
|
+
localStorage.setItem('theme', 'light');
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1264
1878
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1879
|
+
// Set Initial Theme
|
|
1880
|
+
(function() {
|
|
1881
|
+
const savedTheme = localStorage.getItem('theme') || 'dark';
|
|
1882
|
+
document.documentElement.className = savedTheme;
|
|
1883
|
+
})();
|
|
1884
|
+
|
|
1885
|
+
// Dynamically update localhost to current origin if served over HTTP/HTTPS
|
|
1886
|
+
(function() {
|
|
1887
|
+
if (window.location.protocol.startsWith('http')) {
|
|
1888
|
+
const currentOrigin = window.location.origin;
|
|
1889
|
+
const sseEl = document.getElementById('sse-endpoint');
|
|
1890
|
+
if (!sseEl) return;
|
|
1891
|
+
|
|
1892
|
+
let endpointPath = '/mcp';
|
|
1893
|
+
try {
|
|
1894
|
+
const urlObj = new URL(sseEl.innerText.trim());
|
|
1895
|
+
endpointPath = urlObj.pathname;
|
|
1896
|
+
} catch (e) {}
|
|
1897
|
+
|
|
1898
|
+
const dynamicUrl = currentOrigin + endpointPath;
|
|
1899
|
+
|
|
1900
|
+
const updateElementUrl = (id, targetUrl) => {
|
|
1901
|
+
const el = document.getElementById(id);
|
|
1902
|
+
if (el) {
|
|
1903
|
+
if (el.tagName === 'INPUT') {
|
|
1904
|
+
el.value = el.value.replace(/https?:\\/\\/[^\\s"]+/g, targetUrl);
|
|
1905
|
+
} else {
|
|
1906
|
+
el.innerHTML = el.innerHTML.replace(/https?:\\/\\/[^\\s"]+/g, targetUrl);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
|
|
1911
|
+
updateElementUrl('cursor-config', dynamicUrl);
|
|
1912
|
+
updateElementUrl('claude-connector-url', dynamicUrl);
|
|
1913
|
+
updateElementUrl('chatgpt-connector-url', dynamicUrl);
|
|
1914
|
+
updateElementUrl('antigravity-config', dynamicUrl);
|
|
1915
|
+
updateElementUrl('codex-config', dynamicUrl);
|
|
1916
|
+
updateElementUrl('sse-endpoint', dynamicUrl);
|
|
1917
|
+
}
|
|
1918
|
+
})();
|
|
1919
|
+
|
|
1920
|
+
// Tab Switching
|
|
1921
|
+
function switchTab(tabId) {
|
|
1922
|
+
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
|
|
1923
|
+
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
|
|
1924
|
+
|
|
1925
|
+
const activeBtn = Array.from(document.querySelectorAll('.tab-btn')).find(btn => btn.textContent.toLowerCase().includes(tabId));
|
|
1926
|
+
if (activeBtn) activeBtn.classList.add('active');
|
|
1927
|
+
|
|
1928
|
+
const activeContent = document.getElementById('tab-' + tabId);
|
|
1929
|
+
if (activeContent) activeContent.classList.add('active');
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// Copy to Clipboard
|
|
1933
|
+
function copyText(elementId) {
|
|
1934
|
+
const el = document.getElementById(elementId);
|
|
1935
|
+
const text = el.tagName === 'INPUT' ? el.value : el.innerText;
|
|
1936
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
1937
|
+
const btn = el.parentNode.querySelector('.btn-copy') || el.parentNode.querySelector('.btn-copy-input');
|
|
1938
|
+
const originalText = btn.innerText;
|
|
1939
|
+
btn.innerText = 'Copied!';
|
|
1940
|
+
btn.style.background = 'rgba(16, 185, 129, 0.2)';
|
|
1941
|
+
btn.style.borderColor = '#10b981';
|
|
1942
|
+
setTimeout(() => {
|
|
1943
|
+
btn.innerText = originalText;
|
|
1944
|
+
btn.style.background = '';
|
|
1945
|
+
btn.style.borderColor = '';
|
|
1946
|
+
}, 1500);
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
// Tools data for modal display
|
|
1951
|
+
const toolsData = ${JSON.stringify(tools)};
|
|
1952
|
+
|
|
1953
|
+
function openToolModal(index) {
|
|
1954
|
+
const tool = toolsData[index];
|
|
1955
|
+
if (!tool) return;
|
|
1956
|
+
|
|
1957
|
+
document.getElementById('modal-tool-name').innerText = tool.name;
|
|
1958
|
+
document.getElementById('modal-tool-description').innerText = tool.description || 'No description available.';
|
|
1959
|
+
|
|
1960
|
+
const schemaPre = document.getElementById('modal-tool-schema');
|
|
1961
|
+
schemaPre.innerText = JSON.stringify(tool.inputSchema || {}, null, 2);
|
|
1962
|
+
|
|
1963
|
+
const modal = document.getElementById('tool-modal');
|
|
1964
|
+
modal.style.display = 'flex';
|
|
1965
|
+
modal.offsetHeight; // force reflow
|
|
1966
|
+
modal.classList.add('active');
|
|
1967
|
+
document.body.style.overflow = 'hidden';
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
function closeToolModal(event) {
|
|
1971
|
+
if (event && event.target !== document.getElementById('tool-modal') && event.target.closest('.modal-close-btn') === null) return;
|
|
1972
|
+
|
|
1973
|
+
const modal = document.getElementById('tool-modal');
|
|
1974
|
+
modal.classList.remove('active');
|
|
1975
|
+
document.body.style.overflow = '';
|
|
1976
|
+
|
|
1977
|
+
setTimeout(() => {
|
|
1978
|
+
if (!modal.classList.contains('active')) {
|
|
1979
|
+
modal.style.display = 'none';
|
|
1980
|
+
}
|
|
1981
|
+
}, 200);
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
function copyModalSchema() {
|
|
1985
|
+
const el = document.getElementById('modal-tool-schema');
|
|
1986
|
+
navigator.clipboard.writeText(el.innerText).then(() => {
|
|
1987
|
+
const btn = el.parentNode.querySelector('.btn-copy');
|
|
1988
|
+
const originalText = btn.innerText;
|
|
1989
|
+
btn.innerText = 'Copied!';
|
|
1990
|
+
btn.style.background = 'rgba(16, 185, 129, 0.2)';
|
|
1991
|
+
btn.style.borderColor = '#10b981';
|
|
1992
|
+
setTimeout(() => {
|
|
1993
|
+
btn.innerText = originalText;
|
|
1994
|
+
btn.style.background = '';
|
|
1995
|
+
btn.style.borderColor = '';
|
|
1996
|
+
}, 1500);
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// Client-side filtering of tools
|
|
2001
|
+
function filterTools() {
|
|
2002
|
+
const query = document.getElementById('search').value.toLowerCase();
|
|
2003
|
+
const cards = document.querySelectorAll('.tool-card');
|
|
2004
|
+
|
|
2005
|
+
cards.forEach(card => {
|
|
2006
|
+
const name = card.getAttribute('data-name');
|
|
2007
|
+
const desc = card.getAttribute('data-desc');
|
|
2008
|
+
if (name.includes(query) || desc.includes(query)) {
|
|
2009
|
+
card.style.display = 'flex';
|
|
2010
|
+
} else {
|
|
2011
|
+
card.style.display = 'none';
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
</script>
|
|
2016
|
+
|
|
2017
|
+
<!-- Tool Details Modal -->
|
|
2018
|
+
<div class="modal-overlay" id="tool-modal" onclick="closeToolModal(event)">
|
|
2019
|
+
<div class="modal-content" onclick="event.stopPropagation()">
|
|
2020
|
+
<div class="modal-header">
|
|
2021
|
+
<h3 class="modal-title" id="modal-tool-name">tool_name</h3>
|
|
2022
|
+
<button class="modal-close-btn" onclick="closeToolModal(event)">
|
|
2023
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:20px;height:20px;">
|
|
2024
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
|
2025
|
+
</svg>
|
|
2026
|
+
</button>
|
|
2027
|
+
</div>
|
|
2028
|
+
<div class="modal-body">
|
|
2029
|
+
<p class="modal-tool-description" id="modal-tool-description">Description here...</p>
|
|
2030
|
+
<div class="modal-section-title">Input Schema</div>
|
|
2031
|
+
<div class="code-container" style="margin-top: 0.5rem; max-height: 400px; overflow-y: auto;">
|
|
2032
|
+
<button class="btn-copy" onclick="copyModalSchema()">Copy Schema</button>
|
|
2033
|
+
<pre id="modal-tool-schema" style="color: #38bdf8;"></pre>
|
|
2034
|
+
</div>
|
|
2035
|
+
</div>
|
|
1268
2036
|
</div>
|
|
1269
2037
|
</div>
|
|
1270
2038
|
</body>
|