@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.
- package/.env.example +38 -0
- package/LICENSE +201 -0
- package/README.md +364 -0
- package/README_MCP.md +279 -0
- package/package.json +99 -0
- package/src/ai/assistant.js +982 -0
- package/src/cli/interactive.js +500 -0
- package/src/database/connection-manager.js +350 -0
- package/src/database/direct-client.js +686 -0
- package/src/index.js +162 -0
- package/src/mcp/handlers/actions.js +213 -0
- package/src/mcp/handlers/ai.js +207 -0
- package/src/mcp/handlers/analytics.js +1647 -0
- package/src/mcp/handlers/cards.js +1544 -0
- package/src/mcp/handlers/collections.js +244 -0
- package/src/mcp/handlers/dashboard.js +207 -0
- package/src/mcp/handlers/dashboard_direct.js +292 -0
- package/src/mcp/handlers/database.js +322 -0
- package/src/mcp/handlers/docs.js +399 -0
- package/src/mcp/handlers/index.js +35 -0
- package/src/mcp/handlers/metadata.js +190 -0
- package/src/mcp/handlers/questions.js +134 -0
- package/src/mcp/handlers/schema.js +1699 -0
- package/src/mcp/handlers/sql.js +559 -0
- package/src/mcp/handlers/users.js +251 -0
- package/src/mcp/job-store.js +199 -0
- package/src/mcp/server.js +428 -0
- package/src/mcp/tool-registry.js +3244 -0
- package/src/mcp/tool-router.js +149 -0
- package/src/metabase/client.js +737 -0
- package/src/metabase/metadata-client.js +1852 -0
- package/src/utils/activity-logger.js +489 -0
- package/src/utils/cache.js +176 -0
- package/src/utils/config.js +131 -0
- package/src/utils/definition-tables.js +938 -0
- package/src/utils/file-operations.js +496 -0
- package/src/utils/logger.js +45 -0
- package/src/utils/parametric-questions.js +627 -0
- package/src/utils/response-optimizer.js +190 -0
- 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;
|