dynamic_grounding_for_github_copilot 0.1.0

MCP server providing Google Gemini AI integration for enhanced codebase search and analysis
Documentation
use dynamic_grounding_for_github_copilot::*;
use std::env;
use std::sync::Arc;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize tracing - write to stderr to avoid interfering with MCP stdio protocol
    tracing_subscriber::registry()
        .with(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "dynamic_grounding_for_github_copilot=info".into()),
        )
        .with(
            tracing_subscriber::fmt::layer().with_writer(std::io::stderr), // Write logs to stderr, not stdout
        )
        .init();

    // Check for setup flag
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && (args[1] == "--setup" || args[1] == "setup") {
        run_setup_wizard().await?;
        return Ok(());
    }

    // Create quota tracker
    let quota_tracker = Arc::new(QuotaTracker::new());

    // Create API key provider for MCP
    let api_key_provider = Arc::new(mcp_server::MCPApiKeyProvider::new());

    // Read API key from environment or MCP initialization
    // For now, expect it to be provided via MCP protocol initialization
    // The VS Code extension will send it securely
    if let Ok(key) = std::env::var("GEMINI_API_KEY") {
        let trimmed_key = key.trim();
        tracing::info!(
            "API key loaded from environment, length: {}, starts with: {}",
            trimmed_key.len(),
            if trimmed_key.len() >= 4 {
                &trimmed_key[0..4]
            } else {
                trimmed_key
            }
        );
        api_key_provider.set_key(trimmed_key.to_string());
    } else {
        tracing::warn!("GEMINI_API_KEY environment variable not set");
    }

    // Create Gemini client
    let gemini_client = Arc::new(GeminiClient::new(api_key_provider.clone(), quota_tracker));

    // Create and run MCP server
    let server = MCPServer::new(gemini_client);
    server.run().await?;

    Ok(())
}

/// Run the interactive setup wizard
async fn run_setup_wizard() -> anyhow::Result<()> {
    let provider = Arc::new(mcp_server::MCPApiKeyProvider::new());
    let wizard = SetupWizard::with_provider(provider.clone() as Arc<dyn api_key::ApiKeyProvider>);

    match wizard.run().await {
        Ok(_key) => {
            println!("\n✓ Setup completed successfully!");
            println!("You can now run the MCP server without the --setup flag.");
            Ok(())
        }
        Err(e) => {
            eprintln!("\n✗ Setup failed: {}", e);
            std::process::exit(1);
        }
    }
}