@revealui/mcp 0.1.0 → 0.1.3
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/LICENSE +22 -0
- package/LICENSE.commercial +111 -0
- package/README.md +3 -0
- package/dist/{packages/mcp/src/adapters → adapters}/db.d.ts +1 -1
- package/dist/adapters/db.d.ts.map +1 -0
- package/dist/adapters/db.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js.map +1 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js.map +1 -0
- package/dist/{packages/mcp/src/hypervisor.d.ts → hypervisor.d.ts} +56 -0
- package/dist/hypervisor.d.ts.map +1 -0
- package/dist/{packages/mcp/src/hypervisor.js → hypervisor.js} +209 -1
- package/dist/hypervisor.js.map +1 -0
- package/dist/{packages/mcp/src/index.d.ts → index.d.ts} +9 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/{packages/mcp/src/index.js → index.js} +8 -4
- package/dist/index.js.map +1 -0
- package/dist/{packages/mcp/src/servers → servers}/adapter.d.ts +11 -1
- package/dist/servers/adapter.d.ts.map +1 -0
- package/dist/{packages/mcp/src/servers → servers}/adapter.js +20 -4
- package/dist/servers/adapter.js.map +1 -0
- package/dist/servers/revealui-content.d.ts +21 -0
- package/dist/servers/revealui-content.d.ts.map +1 -0
- package/dist/servers/revealui-content.js +211 -0
- package/dist/servers/revealui-content.js.map +1 -0
- package/dist/servers/revealui-email.d.ts +18 -0
- package/dist/servers/revealui-email.d.ts.map +1 -0
- package/dist/servers/revealui-email.js +190 -0
- package/dist/servers/revealui-email.js.map +1 -0
- package/dist/servers/revealui-stripe.d.ts +19 -0
- package/dist/servers/revealui-stripe.d.ts.map +1 -0
- package/dist/servers/revealui-stripe.js +228 -0
- package/dist/servers/revealui-stripe.js.map +1 -0
- package/package.json +50 -11
- package/.env.example +0 -9
- package/MCP_MAINTENANCE.md +0 -265
- package/__tests__/crdt.integration.test.ts +0 -156
- package/configs/README.md +0 -77
- package/configs/claude-template.json +0 -54
- package/dist/packages/core/src/database/ssl-config.d.ts +0 -9
- package/dist/packages/core/src/database/ssl-config.d.ts.map +0 -1
- package/dist/packages/core/src/database/ssl-config.js +0 -8
- package/dist/packages/core/src/database/ssl-config.js.map +0 -1
- package/dist/packages/core/src/features.d.ts +0 -86
- package/dist/packages/core/src/features.d.ts.map +0 -1
- package/dist/packages/core/src/features.js +0 -93
- package/dist/packages/core/src/features.js.map +0 -1
- package/dist/packages/core/src/license.d.ts +0 -75
- package/dist/packages/core/src/license.d.ts.map +0 -1
- package/dist/packages/core/src/license.js +0 -174
- package/dist/packages/core/src/license.js.map +0 -1
- package/dist/packages/core/src/monitoring/alerts.d.ts +0 -118
- package/dist/packages/core/src/monitoring/alerts.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/alerts.js +0 -325
- package/dist/packages/core/src/monitoring/alerts.js.map +0 -1
- package/dist/packages/core/src/monitoring/cleanup-manager.d.ts +0 -71
- package/dist/packages/core/src/monitoring/cleanup-manager.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/cleanup-manager.js +0 -227
- package/dist/packages/core/src/monitoring/cleanup-manager.js.map +0 -1
- package/dist/packages/core/src/monitoring/health-monitor.d.ts +0 -22
- package/dist/packages/core/src/monitoring/health-monitor.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/health-monitor.js +0 -143
- package/dist/packages/core/src/monitoring/health-monitor.js.map +0 -1
- package/dist/packages/core/src/monitoring/index.d.ts +0 -14
- package/dist/packages/core/src/monitoring/index.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/index.js +0 -18
- package/dist/packages/core/src/monitoring/index.js.map +0 -1
- package/dist/packages/core/src/monitoring/process-registry.d.ts +0 -97
- package/dist/packages/core/src/monitoring/process-registry.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/process-registry.js +0 -223
- package/dist/packages/core/src/monitoring/process-registry.js.map +0 -1
- package/dist/packages/core/src/monitoring/types.d.ts +0 -231
- package/dist/packages/core/src/monitoring/types.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/types.js +0 -43
- package/dist/packages/core/src/monitoring/types.js.map +0 -1
- package/dist/packages/core/src/monitoring/zombie-detector.d.ts +0 -81
- package/dist/packages/core/src/monitoring/zombie-detector.d.ts.map +0 -1
- package/dist/packages/core/src/monitoring/zombie-detector.js +0 -232
- package/dist/packages/core/src/monitoring/zombie-detector.js.map +0 -1
- package/dist/packages/core/src/observability/logger.d.ts +0 -47
- package/dist/packages/core/src/observability/logger.d.ts.map +0 -1
- package/dist/packages/core/src/observability/logger.js +0 -141
- package/dist/packages/core/src/observability/logger.js.map +0 -1
- package/dist/packages/core/src/utils/logger-server.d.ts +0 -32
- package/dist/packages/core/src/utils/logger-server.d.ts.map +0 -1
- package/dist/packages/core/src/utils/logger-server.js +0 -69
- package/dist/packages/core/src/utils/logger-server.js.map +0 -1
- package/dist/packages/core/src/utils/request-context.d.ts +0 -143
- package/dist/packages/core/src/utils/request-context.d.ts.map +0 -1
- package/dist/packages/core/src/utils/request-context.js +0 -169
- package/dist/packages/core/src/utils/request-context.js.map +0 -1
- package/dist/packages/dev/src/code-validator/index.d.ts +0 -20
- package/dist/packages/dev/src/code-validator/index.d.ts.map +0 -1
- package/dist/packages/dev/src/code-validator/index.js +0 -20
- package/dist/packages/dev/src/code-validator/index.js.map +0 -1
- package/dist/packages/dev/src/code-validator/types.d.ts +0 -67
- package/dist/packages/dev/src/code-validator/types.d.ts.map +0 -1
- package/dist/packages/dev/src/code-validator/types.js +0 -7
- package/dist/packages/dev/src/code-validator/types.js.map +0 -1
- package/dist/packages/dev/src/code-validator/validator.d.ts +0 -48
- package/dist/packages/dev/src/code-validator/validator.d.ts.map +0 -1
- package/dist/packages/dev/src/code-validator/validator.js +0 -176
- package/dist/packages/dev/src/code-validator/validator.js.map +0 -1
- package/dist/packages/mcp/src/adapters/db.d.ts.map +0 -1
- package/dist/packages/mcp/src/adapters/db.js.map +0 -1
- package/dist/packages/mcp/src/config/index.d.ts.map +0 -1
- package/dist/packages/mcp/src/config/index.js.map +0 -1
- package/dist/packages/mcp/src/contracts.d.ts.map +0 -1
- package/dist/packages/mcp/src/contracts.js.map +0 -1
- package/dist/packages/mcp/src/hypervisor.d.ts.map +0 -1
- package/dist/packages/mcp/src/hypervisor.js.map +0 -1
- package/dist/packages/mcp/src/index.d.ts.map +0 -1
- package/dist/packages/mcp/src/index.js.map +0 -1
- package/dist/packages/mcp/src/servers/adapter.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/adapter.js.map +0 -1
- package/dist/packages/mcp/src/servers/code-validator.d.ts +0 -24
- package/dist/packages/mcp/src/servers/code-validator.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/code-validator.js +0 -156
- package/dist/packages/mcp/src/servers/code-validator.js.map +0 -1
- package/dist/packages/mcp/src/servers/neon.d.ts +0 -11
- package/dist/packages/mcp/src/servers/neon.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/neon.js +0 -90
- package/dist/packages/mcp/src/servers/neon.js.map +0 -1
- package/dist/packages/mcp/src/servers/next-devtools.d.ts +0 -11
- package/dist/packages/mcp/src/servers/next-devtools.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/next-devtools.js +0 -215
- package/dist/packages/mcp/src/servers/next-devtools.js.map +0 -1
- package/dist/packages/mcp/src/servers/playwright.d.ts +0 -11
- package/dist/packages/mcp/src/servers/playwright.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/playwright.js +0 -68
- package/dist/packages/mcp/src/servers/playwright.js.map +0 -1
- package/dist/packages/mcp/src/servers/stripe.d.ts +0 -11
- package/dist/packages/mcp/src/servers/stripe.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/stripe.js +0 -86
- package/dist/packages/mcp/src/servers/stripe.js.map +0 -1
- package/dist/packages/mcp/src/servers/supabase.d.ts +0 -11
- package/dist/packages/mcp/src/servers/supabase.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/supabase.js +0 -144
- package/dist/packages/mcp/src/servers/supabase.js.map +0 -1
- package/dist/packages/mcp/src/servers/vercel.d.ts +0 -11
- package/dist/packages/mcp/src/servers/vercel.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/vercel.js +0 -87
- package/dist/packages/mcp/src/servers/vercel.js.map +0 -1
- package/dist/packages/mcp/src/servers/vultr-test.d.ts +0 -3
- package/dist/packages/mcp/src/servers/vultr-test.d.ts.map +0 -1
- package/dist/packages/mcp/src/servers/vultr-test.js +0 -82
- package/dist/packages/mcp/src/servers/vultr-test.js.map +0 -1
- package/dist/scripts/lib/analyzers/console-analyzer.d.ts +0 -188
- package/dist/scripts/lib/analyzers/console-analyzer.d.ts.map +0 -1
- package/dist/scripts/lib/analyzers/console-analyzer.js +0 -432
- package/dist/scripts/lib/analyzers/console-analyzer.js.map +0 -1
- package/dist/scripts/lib/analyzers/index.d.ts +0 -11
- package/dist/scripts/lib/analyzers/index.d.ts.map +0 -1
- package/dist/scripts/lib/analyzers/index.js +0 -11
- package/dist/scripts/lib/analyzers/index.js.map +0 -1
- package/dist/scripts/lib/args.d.ts +0 -104
- package/dist/scripts/lib/args.d.ts.map +0 -1
- package/dist/scripts/lib/args.js +0 -304
- package/dist/scripts/lib/args.js.map +0 -1
- package/dist/scripts/lib/cache.d.ts +0 -185
- package/dist/scripts/lib/cache.d.ts.map +0 -1
- package/dist/scripts/lib/cache.js +0 -390
- package/dist/scripts/lib/cache.js.map +0 -1
- package/dist/scripts/lib/cli/dispatch.d.ts +0 -116
- package/dist/scripts/lib/cli/dispatch.d.ts.map +0 -1
- package/dist/scripts/lib/cli/dispatch.js +0 -206
- package/dist/scripts/lib/cli/dispatch.js.map +0 -1
- package/dist/scripts/lib/cli/index.d.ts +0 -10
- package/dist/scripts/lib/cli/index.d.ts.map +0 -1
- package/dist/scripts/lib/cli/index.js +0 -10
- package/dist/scripts/lib/cli/index.js.map +0 -1
- package/dist/scripts/lib/database/ssl-config.d.ts +0 -26
- package/dist/scripts/lib/database/ssl-config.d.ts.map +0 -1
- package/dist/scripts/lib/database/ssl-config.js +0 -47
- package/dist/scripts/lib/database/ssl-config.js.map +0 -1
- package/dist/scripts/lib/errors.d.ts +0 -218
- package/dist/scripts/lib/errors.d.ts.map +0 -1
- package/dist/scripts/lib/errors.js +0 -543
- package/dist/scripts/lib/errors.js.map +0 -1
- package/dist/scripts/lib/exec.d.ts +0 -107
- package/dist/scripts/lib/exec.d.ts.map +0 -1
- package/dist/scripts/lib/exec.js +0 -232
- package/dist/scripts/lib/exec.js.map +0 -1
- package/dist/scripts/lib/index.d.ts +0 -50
- package/dist/scripts/lib/index.d.ts.map +0 -1
- package/dist/scripts/lib/index.js +0 -65
- package/dist/scripts/lib/index.js.map +0 -1
- package/dist/scripts/lib/logger.d.ts +0 -50
- package/dist/scripts/lib/logger.d.ts.map +0 -1
- package/dist/scripts/lib/logger.js +0 -159
- package/dist/scripts/lib/logger.js.map +0 -1
- package/dist/scripts/lib/output.d.ts +0 -149
- package/dist/scripts/lib/output.d.ts.map +0 -1
- package/dist/scripts/lib/output.js +0 -263
- package/dist/scripts/lib/output.js.map +0 -1
- package/dist/scripts/lib/parallel.d.ts +0 -164
- package/dist/scripts/lib/parallel.d.ts.map +0 -1
- package/dist/scripts/lib/parallel.js +0 -355
- package/dist/scripts/lib/parallel.js.map +0 -1
- package/dist/scripts/lib/paths.d.ts +0 -92
- package/dist/scripts/lib/paths.d.ts.map +0 -1
- package/dist/scripts/lib/paths.js +0 -171
- package/dist/scripts/lib/paths.js.map +0 -1
- package/dist/scripts/lib/state/adapters/memory.d.ts +0 -42
- package/dist/scripts/lib/state/adapters/memory.d.ts.map +0 -1
- package/dist/scripts/lib/state/adapters/memory.js +0 -110
- package/dist/scripts/lib/state/adapters/memory.js.map +0 -1
- package/dist/scripts/lib/state/adapters/pglite.d.ts +0 -46
- package/dist/scripts/lib/state/adapters/pglite.d.ts.map +0 -1
- package/dist/scripts/lib/state/adapters/pglite.js +0 -256
- package/dist/scripts/lib/state/adapters/pglite.js.map +0 -1
- package/dist/scripts/lib/state/index.d.ts +0 -16
- package/dist/scripts/lib/state/index.d.ts.map +0 -1
- package/dist/scripts/lib/state/index.js +0 -16
- package/dist/scripts/lib/state/index.js.map +0 -1
- package/dist/scripts/lib/state/types.d.ts +0 -111
- package/dist/scripts/lib/state/types.d.ts.map +0 -1
- package/dist/scripts/lib/state/types.js +0 -8
- package/dist/scripts/lib/state/types.js.map +0 -1
- package/dist/scripts/lib/state/workflow-state.d.ts +0 -110
- package/dist/scripts/lib/state/workflow-state.d.ts.map +0 -1
- package/dist/scripts/lib/state/workflow-state.js +0 -331
- package/dist/scripts/lib/state/workflow-state.js.map +0 -1
- package/dist/scripts/lib/telemetry.d.ts +0 -194
- package/dist/scripts/lib/telemetry.d.ts.map +0 -1
- package/dist/scripts/lib/telemetry.js +0 -394
- package/dist/scripts/lib/telemetry.js.map +0 -1
- package/dist/scripts/lib/utils.d.ts +0 -270
- package/dist/scripts/lib/utils.d.ts.map +0 -1
- package/dist/scripts/lib/utils.js +0 -473
- package/dist/scripts/lib/utils.js.map +0 -1
- package/dist/scripts/lib/validation/database.d.ts +0 -83
- package/dist/scripts/lib/validation/database.d.ts.map +0 -1
- package/dist/scripts/lib/validation/database.js +0 -199
- package/dist/scripts/lib/validation/database.js.map +0 -1
- package/dist/scripts/lib/validation/env.d.ts +0 -80
- package/dist/scripts/lib/validation/env.d.ts.map +0 -1
- package/dist/scripts/lib/validation/env.js +0 -246
- package/dist/scripts/lib/validation/env.js.map +0 -1
- package/dist/scripts/lib/validation/index.d.ts +0 -16
- package/dist/scripts/lib/validation/index.d.ts.map +0 -1
- package/dist/scripts/lib/validation/index.js +0 -16
- package/dist/scripts/lib/validation/index.js.map +0 -1
- package/dist/scripts/lib/validation/post-execution.d.ts +0 -74
- package/dist/scripts/lib/validation/post-execution.d.ts.map +0 -1
- package/dist/scripts/lib/validation/post-execution.js +0 -110
- package/dist/scripts/lib/validation/post-execution.js.map +0 -1
- package/dist/scripts/lib/validation/pre-execution.d.ts +0 -165
- package/dist/scripts/lib/validation/pre-execution.d.ts.map +0 -1
- package/dist/scripts/lib/validation/pre-execution.js +0 -466
- package/dist/scripts/lib/validation/pre-execution.js.map +0 -1
- package/dist/scripts/lib/validators/documentation-validator.d.ts +0 -242
- package/dist/scripts/lib/validators/documentation-validator.d.ts.map +0 -1
- package/dist/scripts/lib/validators/documentation-validator.js +0 -584
- package/dist/scripts/lib/validators/documentation-validator.js.map +0 -1
- package/dist/scripts/lib/validators/index.d.ts +0 -11
- package/dist/scripts/lib/validators/index.d.ts.map +0 -1
- package/dist/scripts/lib/validators/index.js +0 -11
- package/dist/scripts/lib/validators/index.js.map +0 -1
- package/docker-compose.yml +0 -46
- package/docs/INDEX.md +0 -88
- package/docs/README.md +0 -774
- package/docs/SETUP.md +0 -264
- package/docs/servers/code-validator.md +0 -586
- package/eslint.config.js +0 -7
- package/migrations/0001_add_crdt_columns.sql +0 -8
- package/migrations/0001_rollback.sql +0 -6
- package/migrations/005_performance_indexes.sql +0 -190
- package/migrations/backfill_crdt_meta.js +0 -45
- package/src/__tests__/hypervisor.test.ts +0 -212
- package/src/adapters/db.ts +0 -180
- package/src/config/config.json +0 -49
- package/src/config/index.ts +0 -30
- package/src/contracts.ts +0 -221
- package/src/hypervisor.ts +0 -464
- package/src/index.ts +0 -87
- package/src/servers/adapter.ts +0 -643
- package/src/servers/code-validator.ts +0 -188
- package/src/servers/neon.ts +0 -103
- package/src/servers/next-devtools.ts +0 -230
- package/src/servers/playwright.ts +0 -77
- package/src/servers/stripe.ts +0 -99
- package/src/servers/supabase.ts +0 -161
- package/src/servers/vercel.ts +0 -100
- package/src/servers/vultr-test.ts +0 -97
- package/tsconfig.json +0 -12
- package/vitest.config.ts +0 -22
- /package/dist/{packages/mcp/src/adapters → adapters}/db.js +0 -0
- /package/dist/{packages/mcp/src/config → config}/index.d.ts +0 -0
- /package/dist/{packages/mcp/src/config → config}/index.js +0 -0
- /package/dist/{packages/mcp/src/contracts.d.ts → contracts.d.ts} +0 -0
- /package/dist/{packages/mcp/src/contracts.js → contracts.js} +0 -0
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
-- Performance Indexes Migration
|
|
2
|
-
-- Adds strategic indexes to improve query performance
|
|
3
|
-
|
|
4
|
-
-- ============================================================================
|
|
5
|
-
-- USER INDEXES
|
|
6
|
-
-- ============================================================================
|
|
7
|
-
|
|
8
|
-
-- Email lookup (used in authentication)
|
|
9
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email
|
|
10
|
-
ON users(email);
|
|
11
|
-
|
|
12
|
-
-- Created at for sorting recent users
|
|
13
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_created_at
|
|
14
|
-
ON users(created_at DESC);
|
|
15
|
-
|
|
16
|
-
-- Email verification status
|
|
17
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email_verified
|
|
18
|
-
ON users(email_verified_at)
|
|
19
|
-
WHERE email_verified_at IS NOT NULL;
|
|
20
|
-
|
|
21
|
-
-- ============================================================================
|
|
22
|
-
-- POST INDEXES
|
|
23
|
-
-- ============================================================================
|
|
24
|
-
|
|
25
|
-
-- Slug lookup (used in public URLs)
|
|
26
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_slug
|
|
27
|
-
ON posts(slug);
|
|
28
|
-
|
|
29
|
-
-- Published posts sorted by date
|
|
30
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_published_at
|
|
31
|
-
ON posts(published_at DESC)
|
|
32
|
-
WHERE published_at IS NOT NULL;
|
|
33
|
-
|
|
34
|
-
-- Author foreign key
|
|
35
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_author_id
|
|
36
|
-
ON posts(author_id);
|
|
37
|
-
|
|
38
|
-
-- Status filtering
|
|
39
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_status
|
|
40
|
-
ON posts(status);
|
|
41
|
-
|
|
42
|
-
-- Composite index for author's posts by status
|
|
43
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_author_status
|
|
44
|
-
ON posts(author_id, status);
|
|
45
|
-
|
|
46
|
-
-- Composite index for published posts list
|
|
47
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_published_status
|
|
48
|
-
ON posts(published_at DESC, status)
|
|
49
|
-
WHERE status = 'published';
|
|
50
|
-
|
|
51
|
-
-- Full text search on title and content
|
|
52
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_search
|
|
53
|
-
ON posts USING gin(to_tsvector('english', coalesce(title, '') || ' ' || coalesce(content, '')));
|
|
54
|
-
|
|
55
|
-
-- ============================================================================
|
|
56
|
-
-- SESSION INDEXES
|
|
57
|
-
-- ============================================================================
|
|
58
|
-
|
|
59
|
-
-- Token lookup (used in authentication)
|
|
60
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_token
|
|
61
|
-
ON sessions(token);
|
|
62
|
-
|
|
63
|
-
-- User sessions lookup
|
|
64
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_user_id
|
|
65
|
-
ON sessions(user_id);
|
|
66
|
-
|
|
67
|
-
-- Expiration cleanup
|
|
68
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_expires_at
|
|
69
|
-
ON sessions(expires_at);
|
|
70
|
-
|
|
71
|
-
-- Active sessions by user
|
|
72
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_user_active
|
|
73
|
-
ON sessions(user_id, expires_at)
|
|
74
|
-
WHERE expires_at > NOW();
|
|
75
|
-
|
|
76
|
-
-- ============================================================================
|
|
77
|
-
-- COMMENT INDEXES (if comments table exists)
|
|
78
|
-
-- ============================================================================
|
|
79
|
-
|
|
80
|
-
-- Post comments lookup
|
|
81
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_post_id
|
|
82
|
-
ON comments(post_id)
|
|
83
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
|
|
84
|
-
|
|
85
|
-
-- Author comments lookup
|
|
86
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_author_id
|
|
87
|
-
ON comments(author_id)
|
|
88
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
|
|
89
|
-
|
|
90
|
-
-- Approved comments
|
|
91
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_approved
|
|
92
|
-
ON comments(approved_at, created_at DESC)
|
|
93
|
-
WHERE approved_at IS NOT NULL
|
|
94
|
-
AND EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
|
|
95
|
-
|
|
96
|
-
-- ============================================================================
|
|
97
|
-
-- CATEGORY/TAG INDEXES (if exists)
|
|
98
|
-
-- ============================================================================
|
|
99
|
-
|
|
100
|
-
-- Category slug lookup
|
|
101
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_categories_slug
|
|
102
|
-
ON categories(slug)
|
|
103
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'categories');
|
|
104
|
-
|
|
105
|
-
-- Tag slug lookup
|
|
106
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tags_slug
|
|
107
|
-
ON tags(slug)
|
|
108
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tags');
|
|
109
|
-
|
|
110
|
-
-- Post-Tag junction table
|
|
111
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_post_tags_post_id
|
|
112
|
-
ON post_tags(post_id)
|
|
113
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'post_tags');
|
|
114
|
-
|
|
115
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_post_tags_tag_id
|
|
116
|
-
ON post_tags(tag_id)
|
|
117
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'post_tags');
|
|
118
|
-
|
|
119
|
-
-- ============================================================================
|
|
120
|
-
-- MEDIA/ASSETS INDEXES (if exists)
|
|
121
|
-
-- ============================================================================
|
|
122
|
-
|
|
123
|
-
-- Media type lookup
|
|
124
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_media_type
|
|
125
|
-
ON media(type)
|
|
126
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'media');
|
|
127
|
-
|
|
128
|
-
-- Media owner lookup
|
|
129
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_media_user_id
|
|
130
|
-
ON media(user_id)
|
|
131
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'media');
|
|
132
|
-
|
|
133
|
-
-- ============================================================================
|
|
134
|
-
-- ANALYTICS/METRICS INDEXES (if exists)
|
|
135
|
-
-- ============================================================================
|
|
136
|
-
|
|
137
|
-
-- Page views by date range
|
|
138
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_analytics_created_at
|
|
139
|
-
ON analytics(created_at DESC)
|
|
140
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'analytics');
|
|
141
|
-
|
|
142
|
-
-- Page views by resource
|
|
143
|
-
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_analytics_resource
|
|
144
|
-
ON analytics(resource_type, resource_id)
|
|
145
|
-
WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'analytics');
|
|
146
|
-
|
|
147
|
-
-- ============================================================================
|
|
148
|
-
-- VERIFICATION
|
|
149
|
-
-- ============================================================================
|
|
150
|
-
|
|
151
|
-
-- View all indexes
|
|
152
|
-
-- SELECT
|
|
153
|
-
-- schemaname,
|
|
154
|
-
-- tablename,
|
|
155
|
-
-- indexname,
|
|
156
|
-
-- indexdef
|
|
157
|
-
-- FROM pg_indexes
|
|
158
|
-
-- WHERE schemaname = 'public'
|
|
159
|
-
-- ORDER BY tablename, indexname;
|
|
160
|
-
|
|
161
|
-
-- Check index usage
|
|
162
|
-
-- SELECT
|
|
163
|
-
-- schemaname,
|
|
164
|
-
-- tablename,
|
|
165
|
-
-- indexname,
|
|
166
|
-
-- idx_scan as index_scans,
|
|
167
|
-
-- idx_tup_read as tuples_read,
|
|
168
|
-
-- idx_tup_fetch as tuples_fetched
|
|
169
|
-
-- FROM pg_stat_user_indexes
|
|
170
|
-
-- ORDER BY idx_scan DESC;
|
|
171
|
-
|
|
172
|
-
-- Find unused indexes
|
|
173
|
-
-- SELECT
|
|
174
|
-
-- schemaname,
|
|
175
|
-
-- tablename,
|
|
176
|
-
-- indexname,
|
|
177
|
-
-- idx_scan
|
|
178
|
-
-- FROM pg_stat_user_indexes
|
|
179
|
-
-- WHERE idx_scan = 0
|
|
180
|
-
-- AND indexname NOT LIKE 'pg_toast%'
|
|
181
|
-
-- ORDER BY tablename, indexname;
|
|
182
|
-
|
|
183
|
-
-- Check index sizes
|
|
184
|
-
-- SELECT
|
|
185
|
-
-- schemaname,
|
|
186
|
-
-- tablename,
|
|
187
|
-
-- indexname,
|
|
188
|
-
-- pg_size_pretty(pg_relation_size(indexrelid)) as index_size
|
|
189
|
-
-- FROM pg_stat_user_indexes
|
|
190
|
-
-- ORDER BY pg_relation_size(indexrelid) DESC;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/*
|
|
3
|
-
Backfill script to populate `_electric_meta` columns where NULL.
|
|
4
|
-
Usage: ELECTRIC_DATABASE_URL=postgres://... node backfill_crdt_meta.js
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { Client } = require('pg')
|
|
8
|
-
const { logger } = require('@revealui/core/observability/logger')
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
const url = process.env.ELECTRIC_DATABASE_URL || process.env.DATABASE_URL
|
|
12
|
-
if (!url) {
|
|
13
|
-
logger.error(
|
|
14
|
-
'Set ELECTRIC_DATABASE_URL or DATABASE_URL before running.',
|
|
15
|
-
new Error('Missing database URL'),
|
|
16
|
-
)
|
|
17
|
-
process.exit(1)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const client = new Client({ connectionString: url })
|
|
21
|
-
await client.connect()
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
logger.info('Backfilling documents._electric_meta where null...')
|
|
25
|
-
await client.query(
|
|
26
|
-
"UPDATE documents SET _electric_meta = '{}'::jsonb WHERE _electric_meta IS NULL",
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
logger.info('Backfilling subscription_state._electric_meta where null...')
|
|
30
|
-
await client.query(
|
|
31
|
-
"UPDATE subscription_state SET _electric_meta = '{}'::jsonb WHERE _electric_meta IS NULL",
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
logger.info('Backfill complete.')
|
|
35
|
-
} catch (err) {
|
|
36
|
-
logger.error('Backfill failed', err instanceof Error ? err : new Error(String(err)))
|
|
37
|
-
process.exitCode = 1
|
|
38
|
-
} finally {
|
|
39
|
-
await client.end()
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (require.main === module) {
|
|
44
|
-
main()
|
|
45
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import { MCPHypervisor, type MCPServerConfig } from '../hypervisor.js'
|
|
3
|
-
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// Mocks
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
vi.mock('@revealui/core/monitoring', () => ({
|
|
9
|
-
registerCleanupHandler: vi.fn(),
|
|
10
|
-
}))
|
|
11
|
-
|
|
12
|
-
vi.mock('@revealui/core/observability/logger', () => ({
|
|
13
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
14
|
-
}))
|
|
15
|
-
|
|
16
|
-
// Mock child_process.spawn
|
|
17
|
-
const mockProcess = {
|
|
18
|
-
pid: 12345,
|
|
19
|
-
exitCode: null as number | null,
|
|
20
|
-
stdin: { write: vi.fn() },
|
|
21
|
-
stdout: { on: vi.fn() },
|
|
22
|
-
stderr: { on: vi.fn() },
|
|
23
|
-
on: vi.fn(),
|
|
24
|
-
kill: vi.fn(),
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
vi.mock('node:child_process', () => ({
|
|
28
|
-
spawn: vi.fn(() => mockProcess),
|
|
29
|
-
}))
|
|
30
|
-
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
// Helpers
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
|
|
35
|
-
const testConfig: MCPServerConfig = {
|
|
36
|
-
name: 'test-server',
|
|
37
|
-
command: 'node',
|
|
38
|
-
args: ['test-mcp-server.js'],
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
// Tests
|
|
43
|
-
// ---------------------------------------------------------------------------
|
|
44
|
-
|
|
45
|
-
describe('MCPHypervisor', () => {
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
MCPHypervisor._resetForTests()
|
|
48
|
-
mockProcess.exitCode = null
|
|
49
|
-
mockProcess.stdin.write.mockClear()
|
|
50
|
-
mockProcess.stdout.on.mockClear()
|
|
51
|
-
mockProcess.stderr.on.mockClear()
|
|
52
|
-
mockProcess.on.mockClear()
|
|
53
|
-
mockProcess.kill.mockClear()
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
afterEach(() => {
|
|
57
|
-
MCPHypervisor._resetForTests()
|
|
58
|
-
vi.clearAllMocks()
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
describe('getInstance()', () => {
|
|
62
|
-
it('returns a singleton', () => {
|
|
63
|
-
const a = MCPHypervisor.getInstance()
|
|
64
|
-
const b = MCPHypervisor.getInstance()
|
|
65
|
-
expect(a).toBe(b)
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('registerServer()', () => {
|
|
70
|
-
it('registers a server config', () => {
|
|
71
|
-
const hv = MCPHypervisor.getInstance()
|
|
72
|
-
hv.registerServer(testConfig)
|
|
73
|
-
|
|
74
|
-
const status = hv.getStatus()
|
|
75
|
-
expect(status['test-server']).toMatchObject({
|
|
76
|
-
healthy: false,
|
|
77
|
-
toolCount: 0,
|
|
78
|
-
pid: null,
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('ignores duplicate registrations', () => {
|
|
83
|
-
const hv = MCPHypervisor.getInstance()
|
|
84
|
-
hv.registerServer(testConfig)
|
|
85
|
-
hv.registerServer(testConfig) // duplicate — no throw
|
|
86
|
-
|
|
87
|
-
const status = hv.getStatus()
|
|
88
|
-
expect(Object.keys(status)).toHaveLength(1)
|
|
89
|
-
})
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
describe('getAllTools()', () => {
|
|
93
|
-
it('returns empty array when no servers are healthy', () => {
|
|
94
|
-
const hv = MCPHypervisor.getInstance()
|
|
95
|
-
hv.registerServer(testConfig)
|
|
96
|
-
|
|
97
|
-
expect(hv.getAllTools()).toHaveLength(0)
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('returns namespaced tools from healthy servers', () => {
|
|
101
|
-
const hv = MCPHypervisor.getInstance()
|
|
102
|
-
hv.registerServer(testConfig)
|
|
103
|
-
|
|
104
|
-
// Directly inject tools into the server entry via internal state
|
|
105
|
-
// (bypasses spawn for unit testing)
|
|
106
|
-
// Access private state via type cast — for testing only
|
|
107
|
-
const servers = (
|
|
108
|
-
hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
|
|
109
|
-
).servers
|
|
110
|
-
const entry = servers.get('test-server')!
|
|
111
|
-
entry.healthy = true
|
|
112
|
-
entry.tools = [
|
|
113
|
-
{
|
|
114
|
-
name: 'create_payment',
|
|
115
|
-
description: 'Create a payment',
|
|
116
|
-
inputSchema: { type: 'object' as const, properties: {}, required: [] },
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
name: 'list_payments',
|
|
120
|
-
description: 'List payments',
|
|
121
|
-
inputSchema: { type: 'object' as const, properties: {}, required: [] },
|
|
122
|
-
},
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
const tools = hv.getAllTools()
|
|
126
|
-
|
|
127
|
-
expect(tools).toHaveLength(2)
|
|
128
|
-
expect(tools[0]?.namespacedName).toBe('@@mcp_test-server_create_payment')
|
|
129
|
-
expect(tools[1]?.namespacedName).toBe('@@mcp_test-server_list_payments')
|
|
130
|
-
expect(tools[0]?.serverName).toBe('test-server')
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
it('skips unhealthy servers', () => {
|
|
134
|
-
const hv = MCPHypervisor.getInstance()
|
|
135
|
-
hv.registerServer(testConfig)
|
|
136
|
-
|
|
137
|
-
const servers = (
|
|
138
|
-
hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
|
|
139
|
-
).servers
|
|
140
|
-
const entry = servers.get('test-server')!
|
|
141
|
-
entry.healthy = false
|
|
142
|
-
entry.tools = [
|
|
143
|
-
{ name: 'some_tool', description: '', inputSchema: { type: 'object' as const } },
|
|
144
|
-
]
|
|
145
|
-
|
|
146
|
-
expect(hv.getAllTools()).toHaveLength(0)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('namespaces tools from multiple healthy servers', () => {
|
|
150
|
-
const hv = MCPHypervisor.getInstance()
|
|
151
|
-
hv.registerServer({ name: 'stripe', command: 'node', args: [] })
|
|
152
|
-
hv.registerServer({ name: 'vercel', command: 'node', args: [] })
|
|
153
|
-
|
|
154
|
-
const servers = (
|
|
155
|
-
hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
|
|
156
|
-
).servers
|
|
157
|
-
|
|
158
|
-
const stripe = servers.get('stripe')!
|
|
159
|
-
stripe.healthy = true
|
|
160
|
-
stripe.tools = [{ name: 'charge', description: '', inputSchema: { type: 'object' as const } }]
|
|
161
|
-
|
|
162
|
-
const vercel = servers.get('vercel')!
|
|
163
|
-
vercel.healthy = true
|
|
164
|
-
vercel.tools = [{ name: 'deploy', description: '', inputSchema: { type: 'object' as const } }]
|
|
165
|
-
|
|
166
|
-
const tools = hv.getAllTools()
|
|
167
|
-
const names = tools.map((t) => t.namespacedName)
|
|
168
|
-
|
|
169
|
-
expect(names).toContain('@@mcp_stripe_charge')
|
|
170
|
-
expect(names).toContain('@@mcp_vercel_deploy')
|
|
171
|
-
})
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
describe('pingServer()', () => {
|
|
175
|
-
it('returns false for unknown server', async () => {
|
|
176
|
-
const hv = MCPHypervisor.getInstance()
|
|
177
|
-
const result = await hv.pingServer('nonexistent')
|
|
178
|
-
expect(result).toBe(false)
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('returns false when process is not running', async () => {
|
|
182
|
-
const hv = MCPHypervisor.getInstance()
|
|
183
|
-
hv.registerServer(testConfig)
|
|
184
|
-
|
|
185
|
-
const result = await hv.pingServer('test-server')
|
|
186
|
-
expect(result).toBe(false)
|
|
187
|
-
})
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
describe('getStatus()', () => {
|
|
191
|
-
it('reflects registered servers', () => {
|
|
192
|
-
const hv = MCPHypervisor.getInstance()
|
|
193
|
-
hv.registerServer({ name: 'alpha', command: 'node', args: [] })
|
|
194
|
-
hv.registerServer({ name: 'beta', command: 'node', args: [] })
|
|
195
|
-
|
|
196
|
-
const status = hv.getStatus()
|
|
197
|
-
expect(Object.keys(status)).toHaveLength(2)
|
|
198
|
-
expect(status['alpha']?.healthy).toBe(false)
|
|
199
|
-
expect(status['beta']?.healthy).toBe(false)
|
|
200
|
-
})
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
describe('unregisterServer()', () => {
|
|
204
|
-
it('removes a registered server', async () => {
|
|
205
|
-
const hv = MCPHypervisor.getInstance()
|
|
206
|
-
hv.registerServer(testConfig)
|
|
207
|
-
await hv.unregisterServer('test-server')
|
|
208
|
-
|
|
209
|
-
expect(hv.getStatus()).not.toHaveProperty('test-server')
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
})
|
package/src/adapters/db.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DB adapter for MCP.
|
|
3
|
-
* - `connectPglite()` initializes ElectricSQL/pglite client with CRDT metadata.
|
|
4
|
-
* - `connectPostgres()` creates a standard Postgres client with Electric metadata.
|
|
5
|
-
* - `createMcpDbClient()` factory that selects adapter based on config.
|
|
6
|
-
*
|
|
7
|
-
* Uses @revealui/contracts as the single source of truth for CRDT operation types.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { mkdir } from 'node:fs/promises'
|
|
11
|
-
import { dirname } from 'node:path'
|
|
12
|
-
import getMcpConfig from '@revealui/config/mcp'
|
|
13
|
-
import type { CrdtOperationsInsert, CrdtOperationsRow } from '@revealui/contracts'
|
|
14
|
-
import { getSSLConfig } from '@revealui/core/database/ssl-config'
|
|
15
|
-
|
|
16
|
-
export interface QueryResult<T = Record<string, unknown>> {
|
|
17
|
-
rows: T[]
|
|
18
|
-
affectedRows?: number
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type McpDbClient = {
|
|
22
|
-
query: <T = Record<string, unknown>>(sql: string, params?: unknown[]) => Promise<QueryResult<T>>
|
|
23
|
-
close: () => Promise<void>
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Re-export contracts CRDT types for consumers */
|
|
27
|
-
export type { CrdtOperationsRow, CrdtOperationsInsert }
|
|
28
|
-
|
|
29
|
-
// Type for PGlite instance (minimal interface to avoid import issues)
|
|
30
|
-
interface PGliteInstance {
|
|
31
|
-
waitReady: Promise<void>
|
|
32
|
-
query<T = Record<string, unknown>>(
|
|
33
|
-
sql: string,
|
|
34
|
-
params?: unknown[],
|
|
35
|
-
): Promise<{ rows: T[]; affectedRows?: number }>
|
|
36
|
-
exec(query: string): Promise<unknown>
|
|
37
|
-
close(): Promise<void>
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// CRDT operations table schema for conflict-free replication
|
|
41
|
-
const CRDT_TABLE_SQL = `
|
|
42
|
-
CREATE TABLE IF NOT EXISTS crdt_operations (
|
|
43
|
-
id TEXT PRIMARY KEY,
|
|
44
|
-
document_id TEXT NOT NULL,
|
|
45
|
-
operation_type TEXT NOT NULL,
|
|
46
|
-
payload JSONB NOT NULL,
|
|
47
|
-
vector_clock JSONB NOT NULL,
|
|
48
|
-
node_id TEXT NOT NULL,
|
|
49
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
50
|
-
applied_at TIMESTAMPTZ
|
|
51
|
-
);
|
|
52
|
-
CREATE INDEX IF NOT EXISTS idx_crdt_ops_document ON crdt_operations(document_id);
|
|
53
|
-
CREATE INDEX IF NOT EXISTS idx_crdt_ops_node ON crdt_operations(node_id);
|
|
54
|
-
CREATE INDEX IF NOT EXISTS idx_crdt_ops_created ON crdt_operations(created_at DESC);
|
|
55
|
-
`
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Connect to PGlite (embedded PostgreSQL) for local development/testing.
|
|
59
|
-
* Uses dynamic import to avoid bundling @electric-sql/pglite when not needed.
|
|
60
|
-
*
|
|
61
|
-
* @param options - Optional connection options
|
|
62
|
-
* @param options.dataDir - Override the default data directory. Use ':memory:' for in-memory.
|
|
63
|
-
*/
|
|
64
|
-
export async function connectPglite(options?: { dataDir?: string }): Promise<McpDbClient> {
|
|
65
|
-
const cfg = getMcpConfig()
|
|
66
|
-
|
|
67
|
-
// Determine data directory from options, config, or default
|
|
68
|
-
// Use ':memory:' for in-memory database (useful for testing)
|
|
69
|
-
const dataDir = options?.dataDir || cfg.electricDatabaseUrl || '.revealui/mcp/pglite'
|
|
70
|
-
|
|
71
|
-
let db: PGliteInstance
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
// Ensure directory exists if not in-memory
|
|
75
|
-
if (dataDir !== ':memory:') {
|
|
76
|
-
await mkdir(dirname(dataDir), { recursive: true })
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const { PGlite } = await import('@electric-sql/pglite')
|
|
80
|
-
db = new PGlite(dataDir) as PGliteInstance
|
|
81
|
-
await db.waitReady
|
|
82
|
-
} catch (error) {
|
|
83
|
-
const err = error as Error
|
|
84
|
-
if (err.message?.includes('Cannot find module') || err.message?.includes('MODULE_NOT_FOUND')) {
|
|
85
|
-
throw new Error(
|
|
86
|
-
'@electric-sql/pglite is not installed. Run: pnpm add -D @electric-sql/pglite',
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
throw error
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Create CRDT operations table
|
|
93
|
-
await db.exec(CRDT_TABLE_SQL)
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
async query<T = Record<string, unknown>>(
|
|
97
|
-
sql: string,
|
|
98
|
-
params?: unknown[],
|
|
99
|
-
): Promise<QueryResult<T>> {
|
|
100
|
-
const result = await db.query(sql, params)
|
|
101
|
-
return {
|
|
102
|
-
rows: result.rows as T[],
|
|
103
|
-
affectedRows: result.affectedRows,
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
async close(): Promise<void> {
|
|
107
|
-
await db.close()
|
|
108
|
-
},
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Connect to PostgreSQL for production use.
|
|
114
|
-
* Supports Neon, Supabase, and generic PostgreSQL with SSL.
|
|
115
|
-
*/
|
|
116
|
-
export async function connectPostgres(): Promise<McpDbClient> {
|
|
117
|
-
const cfg = getMcpConfig()
|
|
118
|
-
|
|
119
|
-
const connectionString =
|
|
120
|
-
cfg.electricDatabaseUrl ||
|
|
121
|
-
process.env.DATABASE_URL ||
|
|
122
|
-
process.env.POSTGRES_URL ||
|
|
123
|
-
process.env.SUPABASE_DATABASE_URI
|
|
124
|
-
|
|
125
|
-
if (!connectionString) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
'Database connection string not found. Set ELECTRIC_DATABASE_URL, DATABASE_URL, POSTGRES_URL, or SUPABASE_DATABASE_URI.',
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const { Pool } = await import('pg')
|
|
132
|
-
const pool = new Pool({
|
|
133
|
-
connectionString,
|
|
134
|
-
ssl: getSSLConfig(connectionString),
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
// Test connection
|
|
138
|
-
const client = await pool.connect()
|
|
139
|
-
try {
|
|
140
|
-
await client.query('SELECT 1')
|
|
141
|
-
} finally {
|
|
142
|
-
client.release()
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Create CRDT operations table
|
|
146
|
-
await pool.query(CRDT_TABLE_SQL)
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
async query<T = Record<string, unknown>>(
|
|
150
|
-
sql: string,
|
|
151
|
-
params?: unknown[],
|
|
152
|
-
): Promise<QueryResult<T>> {
|
|
153
|
-
const result = await pool.query(sql, params)
|
|
154
|
-
return {
|
|
155
|
-
rows: result.rows as T[],
|
|
156
|
-
affectedRows: result.rowCount ?? undefined,
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
async close(): Promise<void> {
|
|
160
|
-
await pool.end()
|
|
161
|
-
},
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Factory function that creates an MCP database client based on configuration.
|
|
167
|
-
* Reads `persistenceDriver` from getMcpConfig() to determine which adapter to use.
|
|
168
|
-
*/
|
|
169
|
-
export async function createMcpDbClient(): Promise<McpDbClient> {
|
|
170
|
-
const cfg = getMcpConfig()
|
|
171
|
-
|
|
172
|
-
if (cfg.persistenceDriver === 'postgres') {
|
|
173
|
-
return connectPostgres()
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Default to pglite for local development
|
|
177
|
-
return connectPglite()
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export default { connectPglite, connectPostgres, createMcpDbClient }
|
package/src/config/config.json
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "MCP server configuration. This config is synchronized with .cursor/mcp-config.json (source of truth). All 6 servers are included for consistency.",
|
|
3
|
-
"_source_of_truth": ".cursor/mcp-config.json",
|
|
4
|
-
"_last_synced": "2025-01",
|
|
5
|
-
"mcpServers": {
|
|
6
|
-
"vercel": {
|
|
7
|
-
"command": "pnpm",
|
|
8
|
-
"args": ["mcp:vercel"],
|
|
9
|
-
"env": {
|
|
10
|
-
"VERCEL_API_KEY": "${VERCEL_API_KEY}",
|
|
11
|
-
"VERCEL_TOKEN": "${VERCEL_TOKEN}"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"stripe": {
|
|
15
|
-
"command": "pnpm",
|
|
16
|
-
"args": ["mcp:stripe"],
|
|
17
|
-
"env": {
|
|
18
|
-
"STRIPE_SECRET_KEY": "${STRIPE_SECRET_KEY}"
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"neon": {
|
|
22
|
-
"command": "pnpm",
|
|
23
|
-
"args": ["mcp:neon"],
|
|
24
|
-
"env": {
|
|
25
|
-
"NEON_API_KEY": "${NEON_API_KEY}"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"supabase": {
|
|
29
|
-
"command": "pnpm",
|
|
30
|
-
"args": ["mcp:supabase"],
|
|
31
|
-
"env": {
|
|
32
|
-
"SUPABASE_URL": "${SUPABASE_URL}",
|
|
33
|
-
"SUPABASE_ANON_KEY": "${SUPABASE_ANON_KEY}",
|
|
34
|
-
"SUPABASE_SERVICE_ROLE_KEY": "${SUPABASE_SERVICE_ROLE_KEY}"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
"playwright": {
|
|
38
|
-
"command": "pnpm",
|
|
39
|
-
"args": ["mcp:playwright"]
|
|
40
|
-
},
|
|
41
|
-
"next-devtools": {
|
|
42
|
-
"command": "pnpm",
|
|
43
|
-
"args": ["mcp:next-devtools"],
|
|
44
|
-
"env": {
|
|
45
|
-
"NEXT_TELEMETRY_DISABLED": "${NEXT_TELEMETRY_DISABLED:-0}"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|