@onmartech/metabase-ai-assistant 4.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/.env.example +38 -0
  2. package/LICENSE +201 -0
  3. package/README.md +364 -0
  4. package/README_MCP.md +279 -0
  5. package/package.json +99 -0
  6. package/src/ai/assistant.js +982 -0
  7. package/src/cli/interactive.js +500 -0
  8. package/src/database/connection-manager.js +350 -0
  9. package/src/database/direct-client.js +686 -0
  10. package/src/index.js +162 -0
  11. package/src/mcp/handlers/actions.js +213 -0
  12. package/src/mcp/handlers/ai.js +207 -0
  13. package/src/mcp/handlers/analytics.js +1647 -0
  14. package/src/mcp/handlers/cards.js +1544 -0
  15. package/src/mcp/handlers/collections.js +244 -0
  16. package/src/mcp/handlers/dashboard.js +207 -0
  17. package/src/mcp/handlers/dashboard_direct.js +292 -0
  18. package/src/mcp/handlers/database.js +322 -0
  19. package/src/mcp/handlers/docs.js +399 -0
  20. package/src/mcp/handlers/index.js +35 -0
  21. package/src/mcp/handlers/metadata.js +190 -0
  22. package/src/mcp/handlers/questions.js +134 -0
  23. package/src/mcp/handlers/schema.js +1699 -0
  24. package/src/mcp/handlers/sql.js +559 -0
  25. package/src/mcp/handlers/users.js +251 -0
  26. package/src/mcp/job-store.js +199 -0
  27. package/src/mcp/server.js +428 -0
  28. package/src/mcp/tool-registry.js +3244 -0
  29. package/src/mcp/tool-router.js +149 -0
  30. package/src/metabase/client.js +737 -0
  31. package/src/metabase/metadata-client.js +1852 -0
  32. package/src/utils/activity-logger.js +489 -0
  33. package/src/utils/cache.js +176 -0
  34. package/src/utils/config.js +131 -0
  35. package/src/utils/definition-tables.js +938 -0
  36. package/src/utils/file-operations.js +496 -0
  37. package/src/utils/logger.js +45 -0
  38. package/src/utils/parametric-questions.js +627 -0
  39. package/src/utils/response-optimizer.js +190 -0
  40. package/src/utils/sql-sanitizer.js +97 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Configuration Module
3
+ * Centralized configuration with Zod validation
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import dotenv from 'dotenv';
8
+ import { logger } from './logger.js';
9
+
10
+ // Load environment variables
11
+ dotenv.config();
12
+
13
+ /**
14
+ * Environment variable schema
15
+ */
16
+ const envSchema = z.object({
17
+ // Metabase Configuration
18
+ METABASE_URL: z.string().url('METABASE_URL must be a valid URL'),
19
+ METABASE_USERNAME: z.string().email().optional(),
20
+ METABASE_PASSWORD: z.string().min(1).optional(),
21
+ METABASE_API_KEY: z.string().optional(),
22
+
23
+ // Security Settings
24
+ METABASE_READ_ONLY_MODE: z
25
+ .string()
26
+ .default('true')
27
+ .transform(val => val.toLowerCase() === 'true'),
28
+
29
+ // Internal Database ID (for advanced metadata features)
30
+ METABASE_INTERNAL_DB_ID: z.string().optional().transform(val => val ? parseInt(val, 10) : undefined),
31
+
32
+ // Database Configuration
33
+ DATABASE_TYPE: z.enum(['postgres', 'mysql', 'sqlite']).default('postgres'),
34
+ DATABASE_HOST: z.string().optional(),
35
+ DATABASE_PORT: z.string().optional().transform(val => val ? parseInt(val, 10) : undefined),
36
+ DATABASE_NAME: z.string().optional(),
37
+ DATABASE_USER: z.string().optional(),
38
+ DATABASE_PASSWORD: z.string().optional(),
39
+
40
+ // Metadata Configuration
41
+ MB_METADATA_ENABLED: z
42
+ .string()
43
+ .default('false')
44
+ .transform(val => val.toLowerCase() === 'true'),
45
+ MB_METADATA_ENGINE: z.enum(['postgres', 'mysql', 'h2']).default('postgres'),
46
+ MB_METADATA_HOST: z.string().optional(),
47
+ MB_METADATA_PORT: z.string().optional().transform(val => val ? parseInt(val, 10) : undefined),
48
+ MB_METADATA_DATABASE: z.string().optional(),
49
+ MB_METADATA_USER: z.string().optional(),
50
+ MB_METADATA_PASSWORD: z.string().optional(),
51
+ MB_METADATA_SSL: z
52
+ .string()
53
+ .default('false')
54
+ .transform(val => val.toLowerCase() === 'true'),
55
+
56
+ // AI Configuration
57
+ ANTHROPIC_API_KEY: z.string().optional(),
58
+ OPENAI_API_KEY: z.string().optional(),
59
+ AI_PROVIDER: z.enum(['anthropic', 'openai']).optional(),
60
+
61
+ // Application Settings
62
+ PORT: z.string().default('3001').transform(val => parseInt(val, 10)),
63
+ LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
64
+ ENVIRONMENT: z.enum(['development', 'production', 'test']).default('development'),
65
+
66
+ // Cache Settings
67
+ CACHE_TTL_MS: z
68
+ .string()
69
+ .default('600000')
70
+ .transform(val => parseInt(val, 10)),
71
+ }).refine(
72
+ data => data.METABASE_API_KEY || (data.METABASE_USERNAME && data.METABASE_PASSWORD),
73
+ {
74
+ message: 'Either METABASE_API_KEY or both METABASE_USERNAME and METABASE_PASSWORD must be provided',
75
+ path: ['METABASE_API_KEY'],
76
+ }
77
+ );
78
+
79
+ /**
80
+ * Validate and parse environment variables
81
+ * @returns {object} Validated configuration
82
+ */
83
+ function validateConfig() {
84
+ try {
85
+ const config = envSchema.parse(process.env);
86
+ logger.info('Configuration validated successfully');
87
+ return config;
88
+ } catch (error) {
89
+ if (error instanceof z.ZodError) {
90
+ const errorMessages = error.errors.map(err => `${err.path.join('.')}: ${err.message}`);
91
+ logger.error('Environment validation failed:', errorMessages);
92
+
93
+ // In development, log but continue with defaults
94
+ if (process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development') {
95
+ logger.warn('Running with partial configuration in development mode');
96
+ return envSchema.partial().parse(process.env);
97
+ }
98
+
99
+ throw new Error(`Environment validation failed:\n${errorMessages.join('\n')}`);
100
+ }
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Create safe configuration (without sensitive data)
107
+ * @returns {object}
108
+ */
109
+ function createSafeConfig() {
110
+ return {
111
+ metabaseUrl: process.env.METABASE_URL,
112
+ readOnlyMode: process.env.METABASE_READ_ONLY_MODE !== 'false',
113
+ metadataEnabled: process.env.MB_METADATA_ENABLED === 'true',
114
+ aiProvider: process.env.ANTHROPIC_API_KEY ? 'anthropic' : (process.env.OPENAI_API_KEY ? 'openai' : null),
115
+ environment: process.env.ENVIRONMENT || 'development',
116
+ logLevel: process.env.LOG_LEVEL || 'info',
117
+ cacheTTL: parseInt(process.env.CACHE_TTL_MS) || 600000,
118
+ };
119
+ }
120
+
121
+ // Export validated config
122
+ let config;
123
+ try {
124
+ config = validateConfig();
125
+ } catch (error) {
126
+ // Fallback for non-strict mode
127
+ config = createSafeConfig();
128
+ }
129
+
130
+ export { config, validateConfig, createSafeConfig };
131
+ export default config;