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.
Files changed (40) hide show
  1. package/README.md +844 -0
  2. package/dist/apps/apps/realtime-dashboard/index.html +15 -0
  3. package/dist/apps/apps/schema-browser/index.html +15 -0
  4. package/dist/apps/assets/modulepreload-polyfill-B5Qt9EMX.js +1 -0
  5. package/dist/apps/assets/realtime-dashboard-BPA99DZn.js +140 -0
  6. package/dist/apps/assets/schema-browser-BEcF8hRP.js +499 -0
  7. package/dist/apps/assets/style-BTxSpbLq.css +1 -0
  8. package/dist/convex-client.d.ts +56 -0
  9. package/dist/convex-client.d.ts.map +1 -0
  10. package/dist/convex-client.js +206 -0
  11. package/dist/convex-client.js.map +1 -0
  12. package/dist/index.d.ts +9 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +93 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/resources/dashboard.d.ts +7 -0
  17. package/dist/resources/dashboard.d.ts.map +1 -0
  18. package/dist/resources/dashboard.js +255 -0
  19. package/dist/resources/dashboard.js.map +1 -0
  20. package/dist/resources/schema-browser.d.ts +7 -0
  21. package/dist/resources/schema-browser.d.ts.map +1 -0
  22. package/dist/resources/schema-browser.js +654 -0
  23. package/dist/resources/schema-browser.js.map +1 -0
  24. package/dist/server.d.ts +12 -0
  25. package/dist/server.d.ts.map +1 -0
  26. package/dist/server.js +142 -0
  27. package/dist/server.js.map +1 -0
  28. package/dist/tools/dashboard.d.ts +19 -0
  29. package/dist/tools/dashboard.d.ts.map +1 -0
  30. package/dist/tools/dashboard.js +309 -0
  31. package/dist/tools/dashboard.js.map +1 -0
  32. package/dist/tools/schema-browser.d.ts +19 -0
  33. package/dist/tools/schema-browser.d.ts.map +1 -0
  34. package/dist/tools/schema-browser.js +260 -0
  35. package/dist/tools/schema-browser.js.map +1 -0
  36. package/dist/ui-server.d.ts +26 -0
  37. package/dist/ui-server.d.ts.map +1 -0
  38. package/dist/ui-server.js +202 -0
  39. package/dist/ui-server.js.map +1 -0
  40. 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":"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"}
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
+ }