@democratize-quality/mcp-server 1.2.0 → 1.2.1
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/cli.js +248 -0
- package/package.json +7 -5
- package/src/chatmodes//360/237/214/220 api-generator.chatmode.md" +409 -0
- package/src/chatmodes//360/237/214/220 api-healer.chatmode.md" +494 -0
- package/src/chatmodes//360/237/214/220 api-planner.chatmode.md" +954 -0
- package/src/config/environments/api-only.js +72 -0
- package/src/config/environments/development.js +73 -0
- package/src/config/environments/production.js +88 -0
- package/src/config/index.js +360 -0
- package/src/config/server.js +60 -0
- package/src/config/tools/api.js +86 -0
- package/src/config/tools/browser.js +109 -0
- package/src/config/tools/default.js +51 -0
- package/src/docs/Agent_README.md +310 -0
- package/src/docs/QUICK_REFERENCE.md +111 -0
- package/src/server.ts +234 -0
- package/src/services/browserService.js +344 -0
- package/src/skills/api-planning/SKILL.md +224 -0
- package/src/skills/test-execution/SKILL.md +777 -0
- package/src/skills/test-generation/SKILL.md +309 -0
- package/src/skills/test-healing/SKILL.md +405 -0
- package/src/tools/api/api-generator.js +1884 -0
- package/src/tools/api/api-healer.js +636 -0
- package/src/tools/api/api-planner.js +2617 -0
- package/src/tools/api/api-project-setup.js +332 -0
- package/src/tools/api/api-request.js +660 -0
- package/src/tools/api/api-session-report.js +1297 -0
- package/src/tools/api/api-session-status.js +414 -0
- package/src/tools/api/prompts/README.md +293 -0
- package/src/tools/api/prompts/generation-prompts.js +722 -0
- package/src/tools/api/prompts/healing-prompts.js +214 -0
- package/src/tools/api/prompts/index.js +44 -0
- package/src/tools/api/prompts/orchestrator.js +353 -0
- package/src/tools/api/prompts/validation-rules.js +358 -0
- package/src/tools/base/ToolBase.js +249 -0
- package/src/tools/base/ToolRegistry.js +288 -0
- package/src/tools/browser/advanced/browser-console.js +403 -0
- package/src/tools/browser/advanced/browser-dialog.js +338 -0
- package/src/tools/browser/advanced/browser-evaluate.js +356 -0
- package/src/tools/browser/advanced/browser-file.js +499 -0
- package/src/tools/browser/advanced/browser-keyboard.js +362 -0
- package/src/tools/browser/advanced/browser-mouse.js +351 -0
- package/src/tools/browser/advanced/browser-network.js +440 -0
- package/src/tools/browser/advanced/browser-pdf.js +426 -0
- package/src/tools/browser/advanced/browser-tabs.js +516 -0
- package/src/tools/browser/advanced/browser-wait.js +397 -0
- package/src/tools/browser/click.js +187 -0
- package/src/tools/browser/close.js +79 -0
- package/src/tools/browser/dom.js +89 -0
- package/src/tools/browser/launch.js +86 -0
- package/src/tools/browser/navigate.js +289 -0
- package/src/tools/browser/screenshot.js +370 -0
- package/src/tools/browser/type.js +193 -0
- package/src/tools/index.js +114 -0
- package/src/utils/agentInstaller.js +437 -0
- package/src/utils/browserHelpers.js +102 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 Democratize Quality
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Democratize Quality MCP Server.
|
|
5
|
+
*
|
|
6
|
+
* Democratize Quality MCP Server is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* Democratize Quality MCP Server is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU Affero General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
* along with Democratize Quality MCP Server. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* API-only environment configuration
|
|
22
|
+
* Only enables API testing tools, disables all browser automation tools
|
|
23
|
+
* Ideal for lightweight deployments focused on API testing
|
|
24
|
+
*/
|
|
25
|
+
module.exports = {
|
|
26
|
+
features: {
|
|
27
|
+
enableDebugMode: process.env.MCP_FEATURES_ENABLEDEBUGMODE === 'true',
|
|
28
|
+
// Only API tools enabled
|
|
29
|
+
enableApiTools: true,
|
|
30
|
+
enableBrowserTools: false,
|
|
31
|
+
enableAdvancedTools: false,
|
|
32
|
+
enableFileTools: false,
|
|
33
|
+
enableNetworkTools: false,
|
|
34
|
+
enableOtherTools: false
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
logging: {
|
|
38
|
+
level: 'warn',
|
|
39
|
+
enableToolDebug: false
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
tools: {
|
|
43
|
+
validationLevel: 'strict',
|
|
44
|
+
// API tool specific configurations
|
|
45
|
+
api: {
|
|
46
|
+
api_request: {
|
|
47
|
+
maxSessionTimeout: 300000, // 5 minutes
|
|
48
|
+
maxConcurrentSessions: 10,
|
|
49
|
+
enableRetries: true,
|
|
50
|
+
defaultRetryAttempts: 3,
|
|
51
|
+
enableRequestLogging: true,
|
|
52
|
+
enableResponseLogging: true
|
|
53
|
+
},
|
|
54
|
+
api_session_report: {
|
|
55
|
+
defaultTheme: 'light',
|
|
56
|
+
includeTimestamp: true,
|
|
57
|
+
maxReportSize: '10MB',
|
|
58
|
+
enableCompressionForLargeReports: true
|
|
59
|
+
},
|
|
60
|
+
api_session_status: {
|
|
61
|
+
enableRealTimeUpdates: true,
|
|
62
|
+
maxHistoryEntries: 1000
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
security: {
|
|
68
|
+
enableInputValidation: true,
|
|
69
|
+
rateLimiting: true,
|
|
70
|
+
maxRequestsPerMinute: 100
|
|
71
|
+
}
|
|
72
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 Democratize Quality
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Democratize Quality MCP Server.
|
|
5
|
+
*
|
|
6
|
+
* Democratize Quality MCP Server is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* Democratize Quality MCP Server is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU Affero General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
* along with Democratize Quality MCP Server. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Development environment configuration
|
|
22
|
+
* Settings optimized for development and debugging
|
|
23
|
+
*/
|
|
24
|
+
module.exports = {
|
|
25
|
+
features: {
|
|
26
|
+
enableDebugMode: true,
|
|
27
|
+
// Tool category feature flags - all enabled by default in development
|
|
28
|
+
enableApiTools: true,
|
|
29
|
+
enableBrowserTools: true,
|
|
30
|
+
enableAdvancedTools: true,
|
|
31
|
+
enableFileTools: true,
|
|
32
|
+
enableNetworkTools: true,
|
|
33
|
+
enableOtherTools: true
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
logging: {
|
|
37
|
+
level: 'debug',
|
|
38
|
+
enableToolDebug: true
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
tools: {
|
|
42
|
+
validationLevel: 'strict',
|
|
43
|
+
browser: {
|
|
44
|
+
browser_launch: {
|
|
45
|
+
defaultHeadless: false, // Show browser in development
|
|
46
|
+
maxInstances: 5,
|
|
47
|
+
chromeFlags: [
|
|
48
|
+
'--disable-gpu',
|
|
49
|
+
'--no-sandbox',
|
|
50
|
+
'--disable-web-security', // Allow CORS in development
|
|
51
|
+
'--disable-features=VizDisplayCompositor'
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
browser_screenshot: {
|
|
55
|
+
enableTimestamps: true,
|
|
56
|
+
outputDirectory: require('path').resolve(__dirname, '../../../output/dev')
|
|
57
|
+
},
|
|
58
|
+
browser_dom: {
|
|
59
|
+
highlightElements: true, // Highlight elements for debugging
|
|
60
|
+
enableRetries: true
|
|
61
|
+
},
|
|
62
|
+
global: {
|
|
63
|
+
enableScreenshotOnError: true,
|
|
64
|
+
enablePerformanceMetrics: true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
security: {
|
|
70
|
+
enableInputValidation: true,
|
|
71
|
+
rateLimiting: false
|
|
72
|
+
}
|
|
73
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 Democratize Quality
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Democratize Quality MCP Server.
|
|
5
|
+
*
|
|
6
|
+
* Democratize Quality MCP Server is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* Democratize Quality MCP Server is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU Affero General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
* along with Democratize Quality MCP Server. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Production environment configuration
|
|
22
|
+
* Settings optimized for production deployment
|
|
23
|
+
*/
|
|
24
|
+
module.exports = {
|
|
25
|
+
features: {
|
|
26
|
+
enableDebugMode: false,
|
|
27
|
+
// Tool category feature flags - API tools enabled by default, others can be controlled
|
|
28
|
+
enableApiTools: true,
|
|
29
|
+
enableBrowserTools: process.env.ENABLE_BROWSER_TOOLS !== 'false',
|
|
30
|
+
enableAdvancedTools: process.env.ENABLE_ADVANCED_TOOLS === 'true',
|
|
31
|
+
enableFileTools: process.env.ENABLE_FILE_TOOLS === 'true',
|
|
32
|
+
enableNetworkTools: process.env.ENABLE_NETWORK_TOOLS === 'true',
|
|
33
|
+
enableOtherTools: process.env.ENABLE_OTHER_TOOLS === 'true'
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
logging: {
|
|
37
|
+
level: 'error',
|
|
38
|
+
enableToolDebug: false
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
tools: {
|
|
42
|
+
validationLevel: 'strict',
|
|
43
|
+
browser: {
|
|
44
|
+
browser_launch: {
|
|
45
|
+
defaultHeadless: true, // Always headless in production
|
|
46
|
+
maxInstances: 3, // Conservative limit
|
|
47
|
+
launchTimeout: 15000, // Shorter timeout
|
|
48
|
+
chromeFlags: [
|
|
49
|
+
'--headless=new',
|
|
50
|
+
'--disable-gpu',
|
|
51
|
+
'--no-sandbox',
|
|
52
|
+
'--disable-dev-shm-usage',
|
|
53
|
+
'--disable-background-timer-throttling',
|
|
54
|
+
'--disable-backgrounding-occluded-windows',
|
|
55
|
+
'--disable-renderer-backgrounding',
|
|
56
|
+
'--memory-pressure-off',
|
|
57
|
+
'--max_old_space_size=4096'
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
browser_screenshot: {
|
|
61
|
+
defaultQuality: 60, // Lower quality for performance
|
|
62
|
+
compressionLevel: 9, // Higher compression
|
|
63
|
+
enableTimestamps: false
|
|
64
|
+
},
|
|
65
|
+
browser_dom: {
|
|
66
|
+
highlightElements: false,
|
|
67
|
+
enableRetries: false, // Fail fast in production
|
|
68
|
+
defaultWaitTimeout: 3000 // Shorter timeout
|
|
69
|
+
},
|
|
70
|
+
browser_type: {
|
|
71
|
+
typingDelay: 5, // Faster typing
|
|
72
|
+
enableNaturalTyping: false
|
|
73
|
+
},
|
|
74
|
+
global: {
|
|
75
|
+
maxConcurrentOperations: 2,
|
|
76
|
+
enableScreenshotOnError: false,
|
|
77
|
+
enablePerformanceMetrics: false,
|
|
78
|
+
healthCheckInterval: 300000 // 5 minutes
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
security: {
|
|
84
|
+
enableInputValidation: true,
|
|
85
|
+
rateLimiting: true,
|
|
86
|
+
maxRequestSize: '5MB'
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 Democratize Quality
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Democratize Quality MCP Server.
|
|
5
|
+
*
|
|
6
|
+
* Democratize Quality MCP Server is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* Democratize Quality MCP Server is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU Affero General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
* along with Democratize Quality MCP Server. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const path = require('path');
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Configuration Management System
|
|
25
|
+
* Loads and manages configuration from multiple sources with environment-based overrides
|
|
26
|
+
*/
|
|
27
|
+
class ConfigManager {
|
|
28
|
+
constructor(options = {}) {
|
|
29
|
+
this.config = {};
|
|
30
|
+
this.environment = process.env.NODE_ENV || 'api-only';
|
|
31
|
+
this.configDir = path.join(__dirname);
|
|
32
|
+
|
|
33
|
+
// Check for debug mode early
|
|
34
|
+
const debugFromEnv = process.env.MCP_FEATURES_ENABLEDEBUGMODE === 'true' || this.environment === 'development';
|
|
35
|
+
this.quiet = options.quiet !== undefined ? options.quiet : !debugFromEnv;
|
|
36
|
+
|
|
37
|
+
this.loadConfiguration();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Load configuration from multiple sources in order of precedence:
|
|
42
|
+
* 1. Environment variables (highest precedence)
|
|
43
|
+
* 2. Environment-specific config files
|
|
44
|
+
* 3. Default configuration files (lowest precedence)
|
|
45
|
+
*/
|
|
46
|
+
loadConfiguration() {
|
|
47
|
+
if (!this.quiet) {
|
|
48
|
+
console.error('[Config] Loading configuration...');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
// Load base server configuration
|
|
53
|
+
this.config = this.loadConfigFile('server.js', {});
|
|
54
|
+
|
|
55
|
+
// Load tool configurations
|
|
56
|
+
this.config.tools = this.loadToolConfigs();
|
|
57
|
+
|
|
58
|
+
// Load environment-specific overrides
|
|
59
|
+
this.loadEnvironmentConfig();
|
|
60
|
+
|
|
61
|
+
// Apply environment variable overrides (highest precedence)
|
|
62
|
+
this.applyEnvironmentVariables();
|
|
63
|
+
|
|
64
|
+
if (!this.quiet) {
|
|
65
|
+
console.error(`[Config] Configuration loaded for environment: ${this.environment}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('[Config] Error loading configuration:', error.message);
|
|
70
|
+
// Use defaults if config loading fails
|
|
71
|
+
this.config = this.getDefaultConfig();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Load a configuration file if it exists
|
|
77
|
+
* @param {string} filename - The config file name
|
|
78
|
+
* @param {object} defaultValue - Default value if file doesn't exist
|
|
79
|
+
* @returns {object} - The loaded configuration
|
|
80
|
+
*/
|
|
81
|
+
loadConfigFile(filename, defaultValue = {}) {
|
|
82
|
+
const filePath = path.join(this.configDir, filename);
|
|
83
|
+
|
|
84
|
+
if (fs.existsSync(filePath)) {
|
|
85
|
+
try {
|
|
86
|
+
return require(filePath);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(`[Config] Error loading ${filename}:`, error.message);
|
|
89
|
+
return defaultValue;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return defaultValue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Load all tool-specific configurations
|
|
98
|
+
* @returns {object} - Combined tool configurations
|
|
99
|
+
*/
|
|
100
|
+
loadToolConfigs() {
|
|
101
|
+
const toolsDir = path.join(this.configDir, 'tools');
|
|
102
|
+
const toolConfigs = {};
|
|
103
|
+
|
|
104
|
+
// Load default tool config
|
|
105
|
+
const defaultToolConfig = this.loadConfigFile('tools/default.js', {});
|
|
106
|
+
|
|
107
|
+
if (fs.existsSync(toolsDir)) {
|
|
108
|
+
const toolConfigFiles = fs.readdirSync(toolsDir).filter(file =>
|
|
109
|
+
file.endsWith('.js') && file !== 'default.js'
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
for (const file of toolConfigFiles) {
|
|
113
|
+
const configName = path.basename(file, '.js');
|
|
114
|
+
toolConfigs[configName] = {
|
|
115
|
+
...defaultToolConfig,
|
|
116
|
+
...this.loadConfigFile(`tools/${file}`, {})
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return toolConfigs;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Load environment-specific configuration overrides
|
|
126
|
+
*/
|
|
127
|
+
loadEnvironmentConfig() {
|
|
128
|
+
const envConfig = this.loadConfigFile(`environments/${this.environment}.js`, {});
|
|
129
|
+
|
|
130
|
+
// Deep merge environment config
|
|
131
|
+
this.config = this.deepMerge(this.config, envConfig);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Apply environment variable overrides
|
|
136
|
+
* Environment variables follow the pattern: MCP_SECTION_KEY=value
|
|
137
|
+
*/
|
|
138
|
+
applyEnvironmentVariables() {
|
|
139
|
+
const envPrefix = 'MCP_';
|
|
140
|
+
|
|
141
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
142
|
+
if (key.startsWith(envPrefix)) {
|
|
143
|
+
let configPath = key.substring(envPrefix.length).toLowerCase().split('_');
|
|
144
|
+
const parsedValue = this.parseEnvValue(value);
|
|
145
|
+
|
|
146
|
+
// Special handling for feature flags to maintain camelCase
|
|
147
|
+
if (configPath[0] === 'features' && configPath.length > 1) {
|
|
148
|
+
// Convert features_enablebrowsertools to features.enableBrowserTools
|
|
149
|
+
const featureName = configPath.slice(1).join('_');
|
|
150
|
+
const camelCaseFeature = this.toCamelCase(featureName);
|
|
151
|
+
configPath = ['features', camelCaseFeature];
|
|
152
|
+
|
|
153
|
+
// Remove the lowercase version if it exists
|
|
154
|
+
if (this.config.features && this.config.features[featureName]) {
|
|
155
|
+
delete this.config.features[featureName];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this.setNestedValue(this.config, configPath, parsedValue);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Convert snake_case to camelCase
|
|
166
|
+
* @param {string} str - Snake case string
|
|
167
|
+
* @returns {string} - CamelCase string
|
|
168
|
+
*/
|
|
169
|
+
toCamelCase(str) {
|
|
170
|
+
// Handle special cases for tool feature flags
|
|
171
|
+
if (str === 'enableapitools') return 'enableApiTools';
|
|
172
|
+
if (str === 'enablebrowsertools') return 'enableBrowserTools';
|
|
173
|
+
if (str === 'enableadvancedtools') return 'enableAdvancedTools';
|
|
174
|
+
if (str === 'enablefiletools') return 'enableFileTools';
|
|
175
|
+
if (str === 'enablenetworktools') return 'enableNetworkTools';
|
|
176
|
+
if (str === 'enableothertools') return 'enableOtherTools';
|
|
177
|
+
if (str === 'enabledebugmode') return 'enableDebugMode';
|
|
178
|
+
|
|
179
|
+
// General snake_case to camelCase conversion
|
|
180
|
+
return str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Parse environment variable values to appropriate types
|
|
185
|
+
* @param {string} value - The environment variable value
|
|
186
|
+
* @returns {any} - Parsed value
|
|
187
|
+
*/
|
|
188
|
+
parseEnvValue(value) {
|
|
189
|
+
// Boolean values
|
|
190
|
+
if (value.toLowerCase() === 'true') return true;
|
|
191
|
+
if (value.toLowerCase() === 'false') return false;
|
|
192
|
+
|
|
193
|
+
// Number values
|
|
194
|
+
if (/^\d+$/.test(value)) return parseInt(value, 10);
|
|
195
|
+
if (/^\d+\.\d+$/.test(value)) return parseFloat(value);
|
|
196
|
+
|
|
197
|
+
// JSON values
|
|
198
|
+
if (value.startsWith('{') || value.startsWith('[')) {
|
|
199
|
+
try {
|
|
200
|
+
return JSON.parse(value);
|
|
201
|
+
} catch {
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Deep merge two objects
|
|
211
|
+
* @param {object} target - Target object
|
|
212
|
+
* @param {object} source - Source object
|
|
213
|
+
* @returns {object} - Merged object
|
|
214
|
+
*/
|
|
215
|
+
deepMerge(target, source) {
|
|
216
|
+
const result = { ...target };
|
|
217
|
+
|
|
218
|
+
for (const [key, value] of Object.entries(source)) {
|
|
219
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
220
|
+
result[key] = this.deepMerge(result[key] || {}, value);
|
|
221
|
+
} else {
|
|
222
|
+
result[key] = value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Set a nested value in an object using a path array
|
|
231
|
+
* @param {object} obj - Target object
|
|
232
|
+
* @param {Array<string>} path - Path array
|
|
233
|
+
* @param {any} value - Value to set
|
|
234
|
+
*/
|
|
235
|
+
setNestedValue(obj, path, value) {
|
|
236
|
+
let current = obj;
|
|
237
|
+
|
|
238
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
239
|
+
if (!(path[i] in current)) {
|
|
240
|
+
current[path[i]] = {};
|
|
241
|
+
}
|
|
242
|
+
current = current[path[i]];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
current[path[path.length - 1]] = value;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Get default configuration
|
|
250
|
+
* @returns {object} - Default configuration
|
|
251
|
+
*/
|
|
252
|
+
getDefaultConfig() {
|
|
253
|
+
return {
|
|
254
|
+
server: {
|
|
255
|
+
name: 'democratize-quality-mcp-server',
|
|
256
|
+
version: '1.0.0',
|
|
257
|
+
protocolVersion: '2024-11-05',
|
|
258
|
+
port: process.env.PORT || 3000
|
|
259
|
+
},
|
|
260
|
+
features: {
|
|
261
|
+
// Tool category feature flags with sensible defaults
|
|
262
|
+
enableApiTools: true,
|
|
263
|
+
enableBrowserTools: true,
|
|
264
|
+
enableAdvancedTools: false, // Conservative default for advanced tools
|
|
265
|
+
enableFileTools: false, // Security consideration
|
|
266
|
+
enableNetworkTools: false, // Security consideration
|
|
267
|
+
enableOtherTools: false, // Conservative default
|
|
268
|
+
enableDebugMode: this.environment !== 'production'
|
|
269
|
+
},
|
|
270
|
+
tools: {
|
|
271
|
+
autoDiscovery: true,
|
|
272
|
+
enableCache: true,
|
|
273
|
+
validationLevel: 'strict',
|
|
274
|
+
browser: {
|
|
275
|
+
maxInstances: 10,
|
|
276
|
+
defaultHeadless: true,
|
|
277
|
+
launchTimeout: 30000
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
logging: {
|
|
281
|
+
level: this.environment === 'production' ? 'error' : 'debug',
|
|
282
|
+
enableToolDebug: this.environment !== 'production'
|
|
283
|
+
},
|
|
284
|
+
// Legacy compatibility
|
|
285
|
+
PORT: process.env.PORT || 3000,
|
|
286
|
+
OUTPUT_DIR: path.resolve(__dirname, '../../output')
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Get configuration value by path
|
|
292
|
+
* @param {string} path - Dot-separated path (e.g., 'tools.browser.maxInstances')
|
|
293
|
+
* @param {any} defaultValue - Default value if path doesn't exist
|
|
294
|
+
* @returns {any} - Configuration value
|
|
295
|
+
*/
|
|
296
|
+
get(path, defaultValue = undefined) {
|
|
297
|
+
const keys = path.split('.');
|
|
298
|
+
let current = this.config;
|
|
299
|
+
|
|
300
|
+
for (const key of keys) {
|
|
301
|
+
if (current && typeof current === 'object' && key in current) {
|
|
302
|
+
current = current[key];
|
|
303
|
+
} else {
|
|
304
|
+
return defaultValue;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return current;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Check if a feature is enabled
|
|
313
|
+
* @param {string} featureName - Name of the feature
|
|
314
|
+
* @returns {boolean} - True if enabled
|
|
315
|
+
*/
|
|
316
|
+
isFeatureEnabled(featureName) {
|
|
317
|
+
return this.get(`features.${featureName}`, false);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Get tool-specific configuration
|
|
322
|
+
* @param {string} toolName - Name of the tool
|
|
323
|
+
* @param {string} configKey - Configuration key (optional)
|
|
324
|
+
* @returns {any} - Tool configuration
|
|
325
|
+
*/
|
|
326
|
+
getToolConfig(toolName, configKey = null) {
|
|
327
|
+
const toolConfig = this.get(`tools.${toolName}`, {});
|
|
328
|
+
|
|
329
|
+
if (configKey) {
|
|
330
|
+
return toolConfig[configKey];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return toolConfig;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Set quiet mode for logging
|
|
338
|
+
* @param {boolean} quiet - Whether to suppress non-essential logs
|
|
339
|
+
*/
|
|
340
|
+
setQuiet(quiet) {
|
|
341
|
+
this.quiet = quiet;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get all configuration
|
|
346
|
+
* @returns {object} - Complete configuration
|
|
347
|
+
*/
|
|
348
|
+
getAll() {
|
|
349
|
+
return { ...this.config };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Legacy compatibility methods
|
|
353
|
+
get PORT() { return this.get('PORT', 3000); }
|
|
354
|
+
get OUTPUT_DIR() { return this.get('OUTPUT_DIR'); }
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Create singleton instance
|
|
358
|
+
const configManager = new ConfigManager();
|
|
359
|
+
|
|
360
|
+
module.exports = configManager;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 Democratize Quality
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Democratize Quality MCP Server.
|
|
5
|
+
*
|
|
6
|
+
* Democratize Quality MCP Server is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* Democratize Quality MCP Server is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU Affero General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
* along with Democratize Quality MCP Server. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Server-level configuration
|
|
22
|
+
* Core server settings and MCP protocol configuration
|
|
23
|
+
*/
|
|
24
|
+
module.exports = {
|
|
25
|
+
server: {
|
|
26
|
+
name: 'democratize-quality-mcp-server',
|
|
27
|
+
version: '1.0.0',
|
|
28
|
+
protocolVersion: '2024-11-05',
|
|
29
|
+
port: process.env.PORT || 3000
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
features: {
|
|
33
|
+
enableBrowserTools: true,
|
|
34
|
+
enableFileTools: false,
|
|
35
|
+
enableNetworkTools: false,
|
|
36
|
+
enableOtherTools: true,
|
|
37
|
+
enableDebugMode: process.env.NODE_ENV !== 'production'
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
tools: {
|
|
41
|
+
autoDiscovery: true,
|
|
42
|
+
enableCache: true,
|
|
43
|
+
validationLevel: 'strict' // 'strict', 'loose', 'none'
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
logging: {
|
|
47
|
+
level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
|
|
48
|
+
enableToolDebug: process.env.NODE_ENV !== 'production'
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
security: {
|
|
52
|
+
enableInputValidation: true,
|
|
53
|
+
maxRequestSize: '10MB',
|
|
54
|
+
rateLimiting: false // Disabled by default for MCP
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
// Legacy compatibility
|
|
58
|
+
PORT: process.env.PORT || 3000,
|
|
59
|
+
OUTPUT_DIR: require('path').resolve(__dirname, '../../output')
|
|
60
|
+
};
|