google-context-mcp
Version:
Secure Google Search MCP server providing real-time coding context to AI models and LLMs - find latest docs, solutions, and best practices while coding
142 lines ⢠6.12 kB
JavaScript
import { createInterface } from 'readline';
import { ConfigManager } from './config-manager.js';
export class SetupWizard {
rl;
configManager;
constructor() {
this.configManager = new ConfigManager();
this.rl = createInterface({
input: process.stdin,
output: process.stdout
});
}
question(prompt) {
return new Promise((resolve) => {
this.rl.question(prompt, (answer) => {
resolve(answer.trim());
});
});
}
async questionWithValidation(prompt, validator, errorMessage) {
while (true) {
const answer = await this.question(prompt);
const validation = validator(answer);
if (validation === true) {
return answer;
}
console.log(`ā ${errorMessage}: ${validation}`);
}
}
validateApiKey(input) {
if (!input || input.length < 10) {
return 'API key must be at least 10 characters long';
}
if (!input.startsWith('AIza')) {
return 'API key should start with "AIza"';
}
return true;
}
validateCustomSearchEngineId(input) {
if (!input || input.length < 10) {
return 'Custom Search Engine ID must be at least 10 characters long';
}
return true;
}
validateLanguage(input) {
if (!input)
return true;
if (!/^[a-z]{2}$/.test(input)) {
return 'Language code must be 2 letters (e.g., en, es, fr)';
}
return true;
}
validateCountry(input) {
if (!input)
return true;
if (!/^[A-Z]{2}$/.test(input)) {
return 'Country code must be 2 uppercase letters (e.g., US, GB, IN)';
}
return true;
}
validateSafeSearch(input) {
if (!input)
return true;
if (!['off', 'medium', 'high'].includes(input)) {
return 'Safe search must be one of: off, medium, high';
}
return true;
}
validateNumResults(input) {
if (!input)
return true;
const num = parseInt(input);
if (isNaN(num) || num < 1 || num > 10) {
return 'Number of results must be between 1 and 10';
}
return true;
}
async run() {
console.log('š Welcome to Google Search MCP Setup Wizard!');
console.log('This wizard will help you configure your Google API credentials.\n');
console.log('š Prerequisites:');
console.log('1. Google Cloud Project with Custom Search API enabled');
console.log('2. API key for Custom Search API');
console.log('3. Custom Search Engine ID from https://programmablesearchengine.google.com/');
console.log('');
const proceed = await this.question('Do you have these ready? (y/n): ');
if (proceed.toLowerCase() !== 'y' && proceed.toLowerCase() !== 'yes') {
console.log('\nš Please visit these resources to get started:');
console.log('⢠Google Cloud Console: https://console.cloud.google.com/');
console.log('⢠Custom Search Engine: https://programmablesearchengine.google.com/');
console.log('⢠API Documentation: https://developers.google.com/custom-search/v1/introduction');
console.log('\nRun this setup again when you\'re ready!');
this.rl.close();
return;
}
console.log('\nš Let\'s configure your credentials...\n');
const config = {};
config.googleApiKey = await this.questionWithValidation('Enter your Google API Key: ', this.validateApiKey, 'Invalid API key');
config.customSearchEngineId = await this.questionWithValidation('Enter your Custom Search Engine ID: ', this.validateCustomSearchEngineId, 'Invalid Custom Search Engine ID');
console.log('\nāļø Optional Settings (press Enter to skip):\n');
config.defaultLanguage = await this.questionWithValidation('Default language code (e.g., en, es, fr): ', this.validateLanguage, 'Invalid language code');
config.defaultCountry = await this.questionWithValidation('Default country code (e.g., US, GB, IN): ', this.validateCountry, 'Invalid country code');
config.defaultSafeSearch = await this.questionWithValidation('Default safe search level (off/medium/high): ', this.validateSafeSearch, 'Invalid safe search level');
const defaultNumResultsStr = await this.questionWithValidation('Default number of results (1-10): ', this.validateNumResults, 'Invalid number of results');
if (defaultNumResultsStr) {
config.defaultNumResults = parseInt(defaultNumResultsStr);
}
try {
await this.configManager.saveConfig(config);
console.log('\nā
Configuration saved successfully!');
console.log(`š Config file location: ${this.configManager.getConfigPath()}`);
console.log('\nš Setup complete! You can now use:');
console.log('⢠npx google-search-mcp search "your query"');
console.log('⢠npx google-search-mcp test');
console.log('⢠npx google-search-mcp info');
}
catch (error) {
console.error('\nā Failed to save configuration:', error);
}
this.rl.close();
}
async testCredentials() {
const credentials = await this.configManager.getCredentials();
if (!credentials) {
return false;
}
try {
const { GoogleSearchMCP } = await import('./google-search-mcp.js');
const mcp = new GoogleSearchMCP(credentials.apiKey, credentials.customSearchEngineId);
const results = await mcp['performSearch']({
query: 'test',
numResults: 1
});
return results.length > 0;
}
catch (error) {
console.error('ā Credential test failed:', error);
return false;
}
}
}
//# sourceMappingURL=setup-wizard.js.map