convex-mcp-visual 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +844 -0
- package/dist/apps/apps/realtime-dashboard/index.html +15 -0
- package/dist/apps/apps/schema-browser/index.html +15 -0
- package/dist/apps/assets/modulepreload-polyfill-B5Qt9EMX.js +1 -0
- package/dist/apps/assets/realtime-dashboard-BPA99DZn.js +140 -0
- package/dist/apps/assets/schema-browser-BEcF8hRP.js +499 -0
- package/dist/apps/assets/style-BTxSpbLq.css +1 -0
- package/dist/convex-client.d.ts +56 -0
- package/dist/convex-client.d.ts.map +1 -0
- package/dist/convex-client.js +206 -0
- package/dist/convex-client.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/dashboard.d.ts +7 -0
- package/dist/resources/dashboard.d.ts.map +1 -0
- package/dist/resources/dashboard.js +255 -0
- package/dist/resources/dashboard.js.map +1 -0
- package/dist/resources/schema-browser.d.ts +7 -0
- package/dist/resources/schema-browser.d.ts.map +1 -0
- package/dist/resources/schema-browser.js +654 -0
- package/dist/resources/schema-browser.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +142 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/dashboard.d.ts +19 -0
- package/dist/tools/dashboard.d.ts.map +1 -0
- package/dist/tools/dashboard.js +309 -0
- package/dist/tools/dashboard.js.map +1 -0
- package/dist/tools/schema-browser.d.ts +19 -0
- package/dist/tools/schema-browser.d.ts.map +1 -0
- package/dist/tools/schema-browser.js +260 -0
- package/dist/tools/schema-browser.js.map +1 -0
- package/dist/ui-server.d.ts +26 -0
- package/dist/ui-server.d.ts.map +1 -0
- package/dist/ui-server.js +202 -0
- package/dist/ui-server.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Browser Tool
|
|
3
|
+
*
|
|
4
|
+
* MCP tool that displays database schema in terminal AND
|
|
5
|
+
* opens an interactive schema browser UI in the browser.
|
|
6
|
+
*/
|
|
7
|
+
import { launchUIApp } from '../ui-server.js';
|
|
8
|
+
export const schemaBrowserTool = {
|
|
9
|
+
name: 'schema_browser',
|
|
10
|
+
description: `Opens an interactive Schema Browser for exploring your Convex database.
|
|
11
|
+
|
|
12
|
+
Features:
|
|
13
|
+
- Browse all tables with document counts
|
|
14
|
+
- View declared vs inferred schemas side-by-side
|
|
15
|
+
- Paginate through documents
|
|
16
|
+
- Build and run read-only queries
|
|
17
|
+
|
|
18
|
+
The Schema Browser renders as an interactive UI panel where you can click through tables,
|
|
19
|
+
inspect field types, and explore your data visually.`,
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
deployment: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'Deployment selector (from status tool). If not provided, uses the default deployment.',
|
|
26
|
+
},
|
|
27
|
+
table: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'Pre-select a specific table to view',
|
|
30
|
+
},
|
|
31
|
+
showInferred: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
description: 'Show inferred schemas alongside declared schemas (default: true)',
|
|
34
|
+
default: true,
|
|
35
|
+
},
|
|
36
|
+
pageSize: {
|
|
37
|
+
type: 'number',
|
|
38
|
+
description: 'Number of documents per page (default: 50)',
|
|
39
|
+
default: 50,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: [],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
export async function handleSchemaBrowser(client, args = {}) {
|
|
46
|
+
const { table, showInferred = true, pageSize = 50 } = args;
|
|
47
|
+
// Check if client is connected
|
|
48
|
+
if (!client.isConnected()) {
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: 'text',
|
|
53
|
+
text: `## Schema Browser
|
|
54
|
+
|
|
55
|
+
**Connection Error**: No Convex deployment configured.
|
|
56
|
+
|
|
57
|
+
To connect:
|
|
58
|
+
1. Run \`npx convex login\` to authenticate
|
|
59
|
+
2. Or set \`CONVEX_URL\` and \`CONVEX_DEPLOY_KEY\` environment variables
|
|
60
|
+
|
|
61
|
+
Once connected, the Schema Browser will display your tables and schemas.`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
isError: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
// Get table list and document counts
|
|
69
|
+
const tables = await client.listTables();
|
|
70
|
+
// Get all documents for schema inference
|
|
71
|
+
const allDocuments = await client.getAllDocuments();
|
|
72
|
+
// Build table info with schema data
|
|
73
|
+
const tableInfos = tables.map((t) => {
|
|
74
|
+
const docs = allDocuments[t.name] || [];
|
|
75
|
+
const inferredFields = inferSchemaFromDocuments(docs);
|
|
76
|
+
return {
|
|
77
|
+
name: t.name,
|
|
78
|
+
documentCount: docs.length || t.documentCount,
|
|
79
|
+
hasIndexes: t.indexes.length > 0,
|
|
80
|
+
indexes: t.indexes,
|
|
81
|
+
documents: docs.slice(0, pageSize),
|
|
82
|
+
inferredFields,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
// Get schema for selected table if specified
|
|
86
|
+
let selectedTableInfo = null;
|
|
87
|
+
if (table) {
|
|
88
|
+
selectedTableInfo = tableInfos.find((t) => t.name === table);
|
|
89
|
+
}
|
|
90
|
+
// Build config for UI app
|
|
91
|
+
const config = {
|
|
92
|
+
deploymentUrl: client.getDeploymentUrl(),
|
|
93
|
+
selectedTable: table || null,
|
|
94
|
+
showInferred,
|
|
95
|
+
pageSize,
|
|
96
|
+
tables: tableInfos,
|
|
97
|
+
selectedSchema: selectedTableInfo
|
|
98
|
+
? {
|
|
99
|
+
tableName: selectedTableInfo.name,
|
|
100
|
+
declaredFields: [], // Would come from schema.ts if defined
|
|
101
|
+
inferredFields: selectedTableInfo.inferredFields,
|
|
102
|
+
indexes: selectedTableInfo.indexes,
|
|
103
|
+
}
|
|
104
|
+
: null,
|
|
105
|
+
allDocuments,
|
|
106
|
+
};
|
|
107
|
+
// Launch the interactive UI in browser
|
|
108
|
+
let uiUrl = '';
|
|
109
|
+
try {
|
|
110
|
+
const uiServer = await launchUIApp({
|
|
111
|
+
appName: 'schema-browser',
|
|
112
|
+
config,
|
|
113
|
+
port: 3456,
|
|
114
|
+
autoClose: 30 * 60 * 1000, // Auto-close after 30 minutes
|
|
115
|
+
});
|
|
116
|
+
uiUrl = uiServer.url;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error('Failed to launch UI:', error);
|
|
120
|
+
}
|
|
121
|
+
// Build terminal output (markdown tables)
|
|
122
|
+
const terminalOutput = buildTerminalOutput(tableInfos, table, client.getDeploymentUrl(), uiUrl);
|
|
123
|
+
return {
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: 'text',
|
|
127
|
+
text: terminalOutput,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
return {
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: 'text',
|
|
137
|
+
text: `## Schema Browser
|
|
138
|
+
|
|
139
|
+
**Error**: ${error instanceof Error ? error.message : String(error)}
|
|
140
|
+
|
|
141
|
+
Please check:
|
|
142
|
+
1. Your Convex credentials are valid
|
|
143
|
+
2. You have access to this deployment
|
|
144
|
+
3. The deployment URL is correct`,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
isError: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Infer schema from document samples
|
|
153
|
+
*/
|
|
154
|
+
function inferSchemaFromDocuments(documents) {
|
|
155
|
+
if (documents.length === 0)
|
|
156
|
+
return [];
|
|
157
|
+
const fieldStats = new Map();
|
|
158
|
+
const totalDocs = documents.length;
|
|
159
|
+
for (const doc of documents) {
|
|
160
|
+
for (const [key, value] of Object.entries(doc)) {
|
|
161
|
+
const stats = fieldStats.get(key) || { types: new Set(), count: 0 };
|
|
162
|
+
stats.types.add(getValueType(value));
|
|
163
|
+
stats.count++;
|
|
164
|
+
fieldStats.set(key, stats);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return Array.from(fieldStats.entries())
|
|
168
|
+
.map(([name, stats]) => ({
|
|
169
|
+
name,
|
|
170
|
+
type: Array.from(stats.types).join(' | '),
|
|
171
|
+
optional: stats.count < totalDocs,
|
|
172
|
+
}))
|
|
173
|
+
.sort((a, b) => {
|
|
174
|
+
// Sort system fields first
|
|
175
|
+
const aIsSystem = a.name.startsWith('_');
|
|
176
|
+
const bIsSystem = b.name.startsWith('_');
|
|
177
|
+
if (aIsSystem && !bIsSystem)
|
|
178
|
+
return -1;
|
|
179
|
+
if (!aIsSystem && bIsSystem)
|
|
180
|
+
return 1;
|
|
181
|
+
return a.name.localeCompare(b.name);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get the type of a value for schema inference
|
|
186
|
+
*/
|
|
187
|
+
function getValueType(value) {
|
|
188
|
+
if (value === null)
|
|
189
|
+
return 'null';
|
|
190
|
+
if (value === undefined)
|
|
191
|
+
return 'undefined';
|
|
192
|
+
if (Array.isArray(value))
|
|
193
|
+
return 'array';
|
|
194
|
+
if (typeof value === 'object')
|
|
195
|
+
return 'object';
|
|
196
|
+
return typeof value;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Build terminal-friendly markdown output
|
|
200
|
+
*/
|
|
201
|
+
function buildTerminalOutput(tables, selectedTable, deploymentUrl, uiUrl) {
|
|
202
|
+
const lines = [];
|
|
203
|
+
lines.push('## Schema Browser');
|
|
204
|
+
lines.push('');
|
|
205
|
+
if (uiUrl) {
|
|
206
|
+
lines.push(`**Interactive UI**: ${uiUrl}`);
|
|
207
|
+
lines.push('');
|
|
208
|
+
}
|
|
209
|
+
lines.push(`Connected to: \`${deploymentUrl}\``);
|
|
210
|
+
lines.push('');
|
|
211
|
+
if (tables.length === 0) {
|
|
212
|
+
lines.push('*No tables found in this deployment.*');
|
|
213
|
+
return lines.join('\n');
|
|
214
|
+
}
|
|
215
|
+
// If a specific table is selected, show detailed view
|
|
216
|
+
if (selectedTable) {
|
|
217
|
+
const tableInfo = tables.find((t) => t.name === selectedTable);
|
|
218
|
+
if (tableInfo) {
|
|
219
|
+
lines.push(`### ${selectedTable} (${tableInfo.documentCount} documents)`);
|
|
220
|
+
lines.push('');
|
|
221
|
+
lines.push('**Schema:**');
|
|
222
|
+
lines.push('');
|
|
223
|
+
lines.push('| Field | Type | Required |');
|
|
224
|
+
lines.push('|-------|------|----------|');
|
|
225
|
+
for (const field of tableInfo.inferredFields) {
|
|
226
|
+
lines.push(`| ${field.name} | ${field.type} | ${field.optional ? 'No' : 'Yes'} |`);
|
|
227
|
+
}
|
|
228
|
+
lines.push('');
|
|
229
|
+
if (tableInfo.documents.length > 0) {
|
|
230
|
+
lines.push('**Sample Documents:**');
|
|
231
|
+
lines.push('');
|
|
232
|
+
lines.push('```json');
|
|
233
|
+
lines.push(JSON.stringify(tableInfo.documents.slice(0, 3), null, 2));
|
|
234
|
+
lines.push('```');
|
|
235
|
+
}
|
|
236
|
+
return lines.join('\n');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Show all tables overview
|
|
240
|
+
lines.push(`Here's your complete database schema:`);
|
|
241
|
+
lines.push('');
|
|
242
|
+
for (const table of tables) {
|
|
243
|
+
lines.push('---');
|
|
244
|
+
lines.push(`${table.name} (${table.documentCount} documents)`);
|
|
245
|
+
lines.push('');
|
|
246
|
+
lines.push('| Field | Type | Required |');
|
|
247
|
+
lines.push('|-------|------|----------|');
|
|
248
|
+
if (table.inferredFields.length === 0) {
|
|
249
|
+
lines.push('| *(empty table)* | - | - |');
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
for (const field of table.inferredFields) {
|
|
253
|
+
lines.push(`| ${field.name} | ${field.type} | ${field.optional ? 'No' : 'Yes'} |`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
lines.push('');
|
|
257
|
+
}
|
|
258
|
+
return lines.join('\n');
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=schema-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-browser.js","sourceRoot":"","sources":["../../src/tools/schema-browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Server
|
|
3
|
+
*
|
|
4
|
+
* Starts a local HTTP server to serve interactive UI apps
|
|
5
|
+
* and opens them in the user's default browser.
|
|
6
|
+
*/
|
|
7
|
+
export interface UIServerConfig {
|
|
8
|
+
appName: 'schema-browser' | 'realtime-dashboard';
|
|
9
|
+
config: Record<string, unknown>;
|
|
10
|
+
port?: number;
|
|
11
|
+
autoClose?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface UIServerResult {
|
|
14
|
+
url: string;
|
|
15
|
+
port: number;
|
|
16
|
+
close: () => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Start a local server for a UI app and open it in the browser
|
|
20
|
+
*/
|
|
21
|
+
export declare function launchUIApp(options: UIServerConfig): Promise<UIServerResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Close all active UI servers
|
|
24
|
+
*/
|
|
25
|
+
export declare function closeAllUIServers(): void;
|
|
26
|
+
//# sourceMappingURL=ui-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-server.d.ts","sourceRoot":"","sources":["../src/ui-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkFH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,GAAG,oBAAoB,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAiIlF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Server
|
|
3
|
+
*
|
|
4
|
+
* Starts a local HTTP server to serve interactive UI apps
|
|
5
|
+
* and opens them in the user's default browser.
|
|
6
|
+
*/
|
|
7
|
+
import { createServer } from 'http';
|
|
8
|
+
import { readFileSync, existsSync } from 'fs';
|
|
9
|
+
import { join, dirname, extname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import { exec } from 'child_process';
|
|
12
|
+
import { platform } from 'os';
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
// Track active servers to avoid port conflicts
|
|
15
|
+
const activeServers = new Map();
|
|
16
|
+
// MIME types for serving static files
|
|
17
|
+
const MIME_TYPES = {
|
|
18
|
+
'.html': 'text/html',
|
|
19
|
+
'.js': 'application/javascript',
|
|
20
|
+
'.css': 'text/css',
|
|
21
|
+
'.json': 'application/json',
|
|
22
|
+
'.png': 'image/png',
|
|
23
|
+
'.jpg': 'image/jpeg',
|
|
24
|
+
'.svg': 'image/svg+xml',
|
|
25
|
+
'.woff': 'font/woff',
|
|
26
|
+
'.woff2': 'font/woff2',
|
|
27
|
+
};
|
|
28
|
+
// Find an available port starting from the base
|
|
29
|
+
async function findAvailablePort(basePort) {
|
|
30
|
+
let port = basePort;
|
|
31
|
+
while (activeServers.has(port)) {
|
|
32
|
+
port++;
|
|
33
|
+
}
|
|
34
|
+
return port;
|
|
35
|
+
}
|
|
36
|
+
// Open URL in default browser (cross-platform)
|
|
37
|
+
function openBrowser(url) {
|
|
38
|
+
const cmd = platform() === 'darwin'
|
|
39
|
+
? 'open'
|
|
40
|
+
: platform() === 'win32'
|
|
41
|
+
? 'start'
|
|
42
|
+
: 'xdg-open';
|
|
43
|
+
exec(`${cmd} "${url}"`, (error) => {
|
|
44
|
+
if (error) {
|
|
45
|
+
console.error(`Failed to open browser: ${error.message}`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// Get the base path for built apps
|
|
50
|
+
function getDistAppsPath() {
|
|
51
|
+
return join(__dirname, '..', 'dist', 'apps');
|
|
52
|
+
}
|
|
53
|
+
// Get the path to an app's index.html
|
|
54
|
+
function getAppHtmlPath(appName) {
|
|
55
|
+
const basePath = getDistAppsPath();
|
|
56
|
+
// Try Vite's nested output: dist/apps/apps/{appName}/index.html
|
|
57
|
+
const nestedPath = join(basePath, 'apps', appName, 'index.html');
|
|
58
|
+
if (existsSync(nestedPath)) {
|
|
59
|
+
return nestedPath;
|
|
60
|
+
}
|
|
61
|
+
// Try flat structure: dist/apps/{appName}/index.html
|
|
62
|
+
const flatPath = join(basePath, appName, 'index.html');
|
|
63
|
+
if (existsSync(flatPath)) {
|
|
64
|
+
return flatPath;
|
|
65
|
+
}
|
|
66
|
+
// Try source: apps/{appName}/index.html
|
|
67
|
+
const srcPath = join(__dirname, '..', 'apps', appName, 'index.html');
|
|
68
|
+
if (existsSync(srcPath)) {
|
|
69
|
+
return srcPath;
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`App not found: ${appName}`);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Start a local server for a UI app and open it in the browser
|
|
75
|
+
*/
|
|
76
|
+
export async function launchUIApp(options) {
|
|
77
|
+
const { appName, config, port: preferredPort = 3456, autoClose = 0 } = options;
|
|
78
|
+
const port = await findAvailablePort(preferredPort);
|
|
79
|
+
const configJson = JSON.stringify(config);
|
|
80
|
+
const distAppsPath = getDistAppsPath();
|
|
81
|
+
// Read and modify the HTML with injected config
|
|
82
|
+
let indexHtml;
|
|
83
|
+
try {
|
|
84
|
+
const appHtmlPath = getAppHtmlPath(appName);
|
|
85
|
+
indexHtml = readFileSync(appHtmlPath, 'utf-8');
|
|
86
|
+
// Inject the config into the HTML
|
|
87
|
+
const configScript = `
|
|
88
|
+
<script>
|
|
89
|
+
window.__CONVEX_CONFIG__ = ${configJson};
|
|
90
|
+
</script>
|
|
91
|
+
`;
|
|
92
|
+
indexHtml = indexHtml.replace('<head>', `<head>\n${configScript}`);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// If app HTML not found, serve an error page
|
|
96
|
+
indexHtml = `
|
|
97
|
+
<!DOCTYPE html>
|
|
98
|
+
<html>
|
|
99
|
+
<head>
|
|
100
|
+
<title>Error - ${appName}</title>
|
|
101
|
+
<style>
|
|
102
|
+
body { font-family: system-ui; background: #1a1a2e; color: #eee; padding: 40px; }
|
|
103
|
+
h1 { color: #e94560; }
|
|
104
|
+
pre { background: #16213e; padding: 20px; border-radius: 8px; overflow-x: auto; }
|
|
105
|
+
</style>
|
|
106
|
+
</head>
|
|
107
|
+
<body>
|
|
108
|
+
<h1>UI App Not Found</h1>
|
|
109
|
+
<p>The ${appName} UI could not be loaded. Make sure to build the project first:</p>
|
|
110
|
+
<pre>npm run build</pre>
|
|
111
|
+
<p>Error: ${error instanceof Error ? error.message : String(error)}</p>
|
|
112
|
+
<h2>Config received:</h2>
|
|
113
|
+
<pre>${JSON.stringify(config, null, 2)}</pre>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const server = createServer((req, res) => {
|
|
120
|
+
const url = req.url || '/';
|
|
121
|
+
// Serve index.html for root
|
|
122
|
+
if (url === '/' || url === '/index.html') {
|
|
123
|
+
res.writeHead(200, {
|
|
124
|
+
'Content-Type': 'text/html',
|
|
125
|
+
'Cache-Control': 'no-cache',
|
|
126
|
+
});
|
|
127
|
+
res.end(indexHtml);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Serve static assets from dist/apps/assets/
|
|
131
|
+
if (url.startsWith('/assets/') || url.includes('/assets/')) {
|
|
132
|
+
const assetPath = url.replace(/^.*\/assets\//, 'assets/');
|
|
133
|
+
const filePath = join(distAppsPath, assetPath);
|
|
134
|
+
if (existsSync(filePath)) {
|
|
135
|
+
const ext = extname(filePath);
|
|
136
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
137
|
+
try {
|
|
138
|
+
const content = readFileSync(filePath);
|
|
139
|
+
res.writeHead(200, {
|
|
140
|
+
'Content-Type': contentType,
|
|
141
|
+
'Cache-Control': 'public, max-age=31536000',
|
|
142
|
+
});
|
|
143
|
+
res.end(content);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Fall through to 404
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// 404 for everything else
|
|
152
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
153
|
+
res.end('Not found');
|
|
154
|
+
});
|
|
155
|
+
server.on('error', (error) => {
|
|
156
|
+
if (error.code === 'EADDRINUSE') {
|
|
157
|
+
// Port in use, try next
|
|
158
|
+
launchUIApp({ ...options, port: port + 1 })
|
|
159
|
+
.then(resolve)
|
|
160
|
+
.catch(reject);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
reject(error);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
server.listen(port, '127.0.0.1', () => {
|
|
167
|
+
activeServers.set(port, server);
|
|
168
|
+
const url = `http://127.0.0.1:${port}`;
|
|
169
|
+
// Open browser
|
|
170
|
+
openBrowser(url);
|
|
171
|
+
// Set up auto-close timer if requested
|
|
172
|
+
let closeTimer = null;
|
|
173
|
+
if (autoClose > 0) {
|
|
174
|
+
closeTimer = setTimeout(() => {
|
|
175
|
+
close();
|
|
176
|
+
}, autoClose);
|
|
177
|
+
}
|
|
178
|
+
const close = () => {
|
|
179
|
+
if (closeTimer) {
|
|
180
|
+
clearTimeout(closeTimer);
|
|
181
|
+
}
|
|
182
|
+
server.close();
|
|
183
|
+
activeServers.delete(port);
|
|
184
|
+
};
|
|
185
|
+
resolve({
|
|
186
|
+
url,
|
|
187
|
+
port,
|
|
188
|
+
close,
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Close all active UI servers
|
|
195
|
+
*/
|
|
196
|
+
export function closeAllUIServers() {
|
|
197
|
+
for (const [port, server] of activeServers) {
|
|
198
|
+
server.close();
|
|
199
|
+
activeServers.delete(port);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=ui-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-server.js","sourceRoot":"","sources":["../src/ui-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE9B,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,+CAA+C;AAC/C,MAAM,aAAa,GAAG,IAAI,GAAG,EAA2C,CAAC;AAEzE,sCAAsC;AACtC,MAAM,UAAU,GAA2B;IACzC,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;CACvB,CAAC;AAEF,gDAAgD;AAChD,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IAC/C,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,IAAI,EAAE,CAAC;IACT,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+CAA+C;AAC/C,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,GAAG,GACP,QAAQ,EAAE,KAAK,QAAQ;QACrB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,QAAQ,EAAE,KAAK,OAAO;YACtB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,UAAU,CAAC;IAEnB,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;QAChC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,mCAAmC;AACnC,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,sCAAsC;AACtC,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IAEnC,gEAAgE;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IACjE,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,qDAAqD;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,wCAAwC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IACrE,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;AAC/C,CAAC;AAeD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAuB;IACvD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;IAE/E,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,gDAAgD;IAChD,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAC5C,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE/C,kCAAkC;QAClC,MAAM,YAAY,GAAG;;mCAEU,UAAU;;KAExC,CAAC;QACF,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,WAAW,YAAY,EAAE,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6CAA6C;QAC7C,SAAS,GAAG;;;;mBAIG,OAAO;;;;;;;;;WASf,OAAO;;cAEJ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;;SAE3D,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;;;KAGnC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;YACxE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;YAE3B,4BAA4B;YAC5B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;gBACzC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBACjB,cAAc,EAAE,WAAW;oBAC3B,eAAe,EAAE,UAAU;iBAC5B,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,6CAA6C;YAC7C,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;gBAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;gBAE/C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzB,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC9B,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;oBAElE,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;wBACvC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;4BACjB,cAAc,EAAE,WAAW;4BAC3B,eAAe,EAAE,0BAA0B;yBAC5C,CAAC,CAAC;wBACH,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACjB,OAAO;oBACT,CAAC;oBAAC,MAAM,CAAC;wBACP,sBAAsB;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,0BAA0B;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAgC,EAAE,EAAE;YACtD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,wBAAwB;gBACxB,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;qBACxC,IAAI,CAAC,OAAO,CAAC;qBACb,KAAK,CAAC,MAAM,CAAC,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YACpC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEhC,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;YAEvC,eAAe;YACf,WAAW,CAAC,GAAG,CAAC,CAAC;YAEjB,uCAAuC;YACvC,IAAI,UAAU,GAA0B,IAAI,CAAC;YAC7C,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC3B,KAAK,EAAE,CAAC;gBACV,CAAC,EAAE,SAAS,CAAC,CAAC;YAChB,CAAC;YAED,MAAM,KAAK,GAAG,GAAG,EAAE;gBACjB,IAAI,UAAU,EAAE,CAAC;oBACf,YAAY,CAAC,UAAU,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC,CAAC;YAEF,OAAO,CAAC;gBACN,GAAG;gBACH,IAAI;gBACJ,KAAK;aACN,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "convex-mcp-visual",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Visual MCP tools for exploring Convex databases - graph view, schema browser, and dashboards",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"convex-mcp-visual": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "npm run build:server && npm run build:apps",
|
|
15
|
+
"build:server": "tsc -p tsconfig.server.json",
|
|
16
|
+
"build:apps": "vite build",
|
|
17
|
+
"dev": "tsc -p tsconfig.server.json --watch",
|
|
18
|
+
"start": "node dist/index.js --stdio",
|
|
19
|
+
"start:http": "node dist/index.js --http --port 3001",
|
|
20
|
+
"test": "node dist/index.js --test",
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
26
|
+
"convex": "^1.17.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"typescript": "^5.0.0",
|
|
31
|
+
"vite": "^6.4.1"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"convex",
|
|
38
|
+
"mcp",
|
|
39
|
+
"model-context-protocol",
|
|
40
|
+
"schema-browser",
|
|
41
|
+
"database",
|
|
42
|
+
"visualization",
|
|
43
|
+
"graph",
|
|
44
|
+
"dashboard",
|
|
45
|
+
"claude",
|
|
46
|
+
"claude-code"
|
|
47
|
+
],
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/anthropics/convex-mcp-visual"
|
|
52
|
+
},
|
|
53
|
+
"author": "",
|
|
54
|
+
"homepage": "https://github.com/anthropics/convex-mcp-visual#readme"
|
|
55
|
+
}
|