Skip to main content
Glama
ooples

MCP Console Automation Server

gcp.md25.6 kB
# Google Cloud Platform (GCP) Protocol Documentation ## Overview The GCP Protocol provides comprehensive integration with Google Cloud Platform services, enabling automated console access to Google Cloud Shell, Compute Engine instances, and Google Kubernetes Engine (GKE) clusters. This protocol supports multiple authentication methods including service accounts, OAuth2, and Application Default Credentials (ADC). ## Features - **Google Cloud Shell Integration**: Direct browser-based terminal access with pre-installed tools - **Compute Engine VM Access**: SSH connections via OS Login or traditional key-based authentication - **GKE Cluster Management**: kubectl access and pod execution capabilities - **Identity-Aware Proxy (IAP) Support**: Secure access without external IPs - **OS Login Integration**: Centralized SSH key and user management - **Multi-Project Support**: Manage resources across multiple GCP projects - **Quota Management**: Monitor and enforce API quotas and rate limits - **Advanced Authentication**: Service accounts, OAuth2, and ADC support ## Configuration ### Basic Configuration ```javascript const gcpOptions = { // Project configuration projectId: 'my-project-id', region: 'us-central1', zone: 'us-central1-a', // Authentication (choose one method) keyFile: '/path/to/service-account-key.json', // OR keyFilename: './service-account.json', // OR credentials: { /* service account object */ }, // Cloud Shell settings cloudShellType: 'bash', // or 'fish', 'zsh' machineType: 'e2-small', diskSizeGb: 20, // Compute Engine settings vmName: 'my-instance', vmZone: 'us-central1-a', vmProject: 'compute-project-id', // OS Login settings osLoginEnabled: true, osLoginUser: 'user@example.com' }; ``` ### OAuth2 Configuration ```javascript const oauth2Options = { projectId: 'my-project-id', oauth2Config: { clientId: 'your-oauth2-client-id', clientSecret: 'your-oauth2-client-secret', refreshToken: 'your-refresh-token', accessToken: 'your-access-token' // optional, will be refreshed } }; ``` ### Advanced Configuration ```javascript const advancedOptions = { // Multi-project setup projectId: 'management-project', vmProject: 'compute-project', networkProject: 'network-project', // GKE configuration clusterName: 'my-gke-cluster', clusterLocation: 'us-central1-a', // or region for regional clusters namespace: 'production', podName: 'web-server-xyz', containerName: 'nginx', // IAP configuration iapTunnelEnabled: true, iapConfig: { clientId: 'iap-client-id', audience: '/projects/123456789/global/backendServices/my-backend' }, // Network configuration networkTags: ['web-server', 'database'], serviceAccountEmail: 'compute@my-project.iam.gserviceaccount.com', // Security settings requireOSLogin: true, enableShieldedVm: true, enablePreemptibleInstances: false, // Custom scopes scopes: [ 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/compute.oslogin' ] }; ``` ## Usage Examples ### Google Cloud Shell Session ```javascript import { GCPProtocol } from './protocols/GCPProtocol.js'; const gcp = new GCPProtocol(); // Create Cloud Shell session const session = await gcp.createCloudShellSession('cloudshell-1', { projectId: 'my-project-id', keyFile: './service-account-key.json', cloudShellType: 'bash', region: 'us-central1', diskSizeGb: 10 }); // Listen for output gcp.on('output', (output) => { console.log(`[${output.sessionId}] ${output.data}`); }); gcp.on('session-connected', async (event) => { console.log(`Session ${event.sessionId} connected via ${event.type}`); // Execute Cloud Shell commands await gcp.sendInput('cloudshell-1', 'gcloud config list\n'); await gcp.sendInput('cloudshell-1', 'kubectl get namespaces\n'); await gcp.sendInput('cloudshell-1', 'terraform version\n'); await gcp.sendInput('cloudshell-1', 'docker --version\n'); }); // Handle errors gcp.on('session-error', (event) => { console.error(`Session error: ${event.error.message}`); }); ``` ### Compute Engine VM Access ```javascript // Connect to Compute Engine VM via SSH const vmSession = await gcp.createComputeSession('vm-ssh-1', { projectId: 'compute-project-id', vmName: 'web-server-1', vmZone: 'us-central1-a', osLoginEnabled: true, osLoginUser: 'admin@company.com', keyFile: './service-account-key.json' }); gcp.on('session-connected', async (event) => { if (event.sessionId === 'vm-ssh-1') { console.log('Connected to Compute Engine VM'); // System administration commands await gcp.sendInput('vm-ssh-1', 'sudo systemctl status nginx\n'); await gcp.sendInput('vm-ssh-1', 'docker ps -a\n'); await gcp.sendInput('vm-ssh-1', 'df -h\n'); await gcp.sendInput('vm-ssh-1', 'htop\n'); } }); ``` ### GKE Cluster Management ```javascript // Connect to GKE cluster const gkeSession = await gcp.createGKESession('gke-1', { projectId: 'kubernetes-project', clusterName: 'production-cluster', clusterLocation: 'us-central1-a', namespace: 'default', keyFile: './service-account-key.json' }); gcp.on('session-connected', async (event) => { if (event.sessionId === 'gke-1') { console.log('Connected to GKE cluster'); // Kubernetes management commands await gcp.sendInput('gke-1', 'kubectl get pods --all-namespaces\n'); await gcp.sendInput('gke-1', 'kubectl get services\n'); await gcp.sendInput('gke-1', 'kubectl describe deployment nginx\n'); await gcp.sendInput('gke-1', 'kubectl logs -f deployment/api-server\n'); } }); ``` ### Multi-Environment Management ```javascript // Manage multiple GCP environments const environments = [ { name: 'dev', projectId: 'dev-project-123' }, { name: 'staging', projectId: 'staging-project-456' }, { name: 'prod', projectId: 'prod-project-789' } ]; const sessions = await Promise.all( environments.map(env => gcp.createCloudShellSession(`shell-${env.name}`, { projectId: env.projectId, keyFile: `./keys/${env.name}-service-account.json`, cloudShellType: 'bash' }) ) ); // Deploy to all environments const deployToAllEnvironments = async (command) => { for (const session of sessions) { await gcp.sendInput(session.sessionId, command + '\n'); } }; // Execute deployment commands await deployToAllEnvironments('gcloud app deploy app.yaml --quiet'); await deployToAllEnvironments('gcloud sql import sql my-instance gs://my-bucket/backup.sql'); ``` ## Advanced Features ### Identity-Aware Proxy (IAP) Access ```javascript // Connect to VM behind IAP without external IP const iapSession = await gcp.createComputeSession('iap-vm-1', { projectId: 'secure-project', vmName: 'private-server', vmZone: 'us-central1-a', iapTunnelEnabled: true, iapConfig: { clientId: 'your-iap-client-id.apps.googleusercontent.com', audience: '/projects/123456789/global/backendServices/my-backend' }, osLoginEnabled: true, keyFile: './service-account-key.json' }); // IAP tunnel will be automatically established gcp.on('session-connected', async (event) => { if (event.sessionId === 'iap-vm-1') { console.log('Connected via IAP tunnel'); await gcp.sendInput('iap-vm-1', 'curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/name\n'); } }); ``` ### OS Login Integration ```javascript // Use OS Login for centralized SSH key management const osLoginSession = await gcp.createComputeSession('oslogin-1', { projectId: 'my-project', vmName: 'secure-vm', vmZone: 'europe-west1-b', osLoginEnabled: true, osLoginUser: 'engineer@company.com', // Will use OS Login API keyFile: './service-account-key.json' }); // OS Login automatically manages SSH keys and user permissions gcp.on('session-connected', async (event) => { if (event.sessionId === 'oslogin-1') { // User permissions and SSH keys are managed by OS Login await gcp.sendInput('oslogin-1', 'id\n'); // Shows OS Login user info await gcp.sendInput('oslogin-1', 'sudo whoami\n'); // May work if user has sudo access } }); ``` ### GKE Pod Execution ```javascript // Execute commands inside specific GKE pods const podExecSession = await gcp.createGKESession('pod-exec-1', { projectId: 'k8s-project', clusterName: 'app-cluster', clusterLocation: 'us-west1-a', namespace: 'production', podName: 'api-server-abc123', containerName: 'app-container', keyFile: './service-account-key.json' }); gcp.on('session-connected', async (event) => { if (event.sessionId === 'pod-exec-1') { console.log('Connected to pod container'); // Execute commands inside the container await gcp.sendInput('pod-exec-1', 'kubectl exec -it api-server-abc123 -c app-container -- /bin/bash\n'); // Now commands run inside the container await gcp.sendInput('pod-exec-1', 'ps aux\n'); await gcp.sendInput('pod-exec-1', 'netstat -tulpn\n'); await gcp.sendInput('pod-exec-1', 'cat /app/config.yaml\n'); } }); ``` ### Batch Operations ```javascript // Execute commands across multiple VMs class GCPFleetManager { constructor() { this.gcp = new GCPProtocol(); this.sessions = new Map(); } async connectToFleet(vmList) { const connections = vmList.map(vm => this.gcp.createComputeSession(vm.name, { projectId: vm.projectId, vmName: vm.name, vmZone: vm.zone, osLoginEnabled: true, keyFile: './service-account-key.json' }) ); const sessions = await Promise.all(connections); sessions.forEach(session => this.sessions.set(session.sessionId, session) ); return sessions; } async broadcastCommand(command) { const sessionIds = Array.from(this.sessions.keys()); await Promise.all( sessionIds.map(sessionId => this.gcp.sendInput(sessionId, command + '\n') ) ); } async updateSecurity() { await this.broadcastCommand('sudo apt update && sudo apt upgrade -y'); await this.broadcastCommand('sudo systemctl restart security-agent'); await this.broadcastCommand('sudo fail2ban-client status'); } } // Usage const fleetManager = new GCPFleetManager(); await fleetManager.connectToFleet([ { name: 'web-1', projectId: 'prod', zone: 'us-central1-a' }, { name: 'web-2', projectId: 'prod', zone: 'us-central1-b' }, { name: 'api-1', projectId: 'prod', zone: 'us-central1-a' } ]); await fleetManager.updateSecurity(); ``` ## Authentication Methods ### Service Account Authentication ```javascript // Method 1: JSON Key File const serviceAccountAuth = { projectId: 'my-project-id', keyFile: '/path/to/service-account-key.json' }; // Method 2: Key File Path const keyFilenameAuth = { projectId: 'my-project-id', keyFilename: './credentials/service-account.json' }; // Method 3: Inline Credentials const inlineAuth = { projectId: 'my-project-id', credentials: { type: 'service_account', project_id: 'my-project-id', private_key_id: 'key-id', private_key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n', client_email: 'service@my-project.iam.gserviceaccount.com', client_id: '123456789', auth_uri: 'https://accounts.google.com/o/oauth2/auth', token_uri: 'https://oauth2.googleapis.com/token', auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs', client_x509_cert_url: 'https://www.googleapis.com/robot/v1/metadata/x509/service%40my-project.iam.gserviceaccount.com' } }; ``` ### Application Default Credentials (ADC) ```javascript // Uses environment variables or metadata service const adcAuth = { projectId: 'my-project-id' // No explicit credentials - uses GOOGLE_APPLICATION_CREDENTIALS // environment variable or GCE/Cloud Shell metadata service }; // Set environment variable before running // export GOOGLE_APPLICATION_CREDENTIALS="path/to/service-account-key.json" ``` ### OAuth2 User Authentication ```javascript const oauth2Auth = { projectId: 'my-project-id', oauth2Config: { clientId: '123456789-abc.apps.googleusercontent.com', clientSecret: 'your-oauth2-client-secret', refreshToken: 'refresh-token-from-oauth2-flow' } }; ``` ## Error Handling ### Common Error Scenarios ```javascript gcp.on('session-error', (event) => { const { sessionId, error } = event; switch (error.code) { case 401: console.error(`Authentication failed for ${sessionId}: ${error.message}`); // Handle credential refresh or re-authentication break; case 403: console.error(`Permission denied for ${sessionId}: ${error.message}`); // Check IAM permissions and service account roles break; case 404: console.error(`Resource not found for ${sessionId}: ${error.message}`); // Verify project ID, zone, instance name, etc. break; case 429: console.error(`Rate limit exceeded for ${sessionId}: ${error.message}`); // Implement exponential backoff break; case 'COMPUTE_VM_NOT_RUNNING': console.error(`VM is not in RUNNING state: ${error.message}`); // Start the VM or wait for it to be ready break; case 'GKE_CLUSTER_UNREACHABLE': console.error(`GKE cluster is unreachable: ${error.message}`); // Check cluster status and network connectivity break; default: console.error(`Unexpected error in ${sessionId}:`, error); } }); ``` ### Connection Recovery ```javascript // Implement automatic reconnection with exponential backoff let reconnectAttempts = 0; const maxReconnectAttempts = 5; gcp.on('session-disconnected', async (event) => { const { sessionId } = event; console.log(`Session ${sessionId} disconnected`); if (reconnectAttempts < maxReconnectAttempts) { reconnectAttempts++; const backoffDelay = Math.min(1000 * Math.pow(2, reconnectAttempts - 1), 30000); console.log(`Attempting reconnection ${reconnectAttempts}/${maxReconnectAttempts} in ${backoffDelay}ms...`); setTimeout(async () => { try { const session = gcp.getSession(sessionId); if (session) { // Recreate session based on type if ('webSocketUrl' in session) { await gcp.createCloudShellSession(sessionId, session); } else if ('vmName' in session) { await gcp.createComputeSession(sessionId, session); } else if ('clusterName' in session) { await gcp.createGKESession(sessionId, session); } } reconnectAttempts = 0; // Reset on successful reconnection } catch (error) { console.error(`Reconnection attempt ${reconnectAttempts} failed:`, error); } }, backoffDelay); } else { console.error(`Max reconnection attempts reached for ${sessionId}`); } }); ``` ## Performance Optimization ### Connection Pooling ```javascript class GCPConnectionPool { constructor(maxConnections = 10) { this.gcp = new GCPProtocol(); this.pool = new Map(); this.maxConnections = maxConnections; } async getConnection(type, config) { const poolKey = this.generatePoolKey(type, config); if (!this.pool.has(poolKey)) { this.pool.set(poolKey, { connections: [], waiting: [] }); } const pool = this.pool.get(poolKey); // Return available connection const available = pool.connections.find(conn => !conn.inUse); if (available) { available.inUse = true; return available; } // Create new connection if under limit if (pool.connections.length < this.maxConnections) { const newConnection = await this.createConnection(type, config); newConnection.inUse = true; pool.connections.push(newConnection); return newConnection; } // Wait for available connection return new Promise((resolve) => { pool.waiting.push(resolve); }); } releaseConnection(connection) { connection.inUse = false; // Fulfill waiting requests const poolKey = this.getPoolKeyForConnection(connection); const pool = this.pool.get(poolKey); if (pool && pool.waiting.length > 0) { const waitingResolve = pool.waiting.shift(); connection.inUse = true; waitingResolve(connection); } } private async createConnection(type, config) { switch (type) { case 'cloudshell': return await this.gcp.createCloudShellSession(this.generateSessionId(), config); case 'compute': return await this.gcp.createComputeSession(this.generateSessionId(), config); case 'gke': return await this.gcp.createGKESession(this.generateSessionId(), config); default: throw new Error(`Unknown connection type: ${type}`); } } } ``` ### Resource Monitoring ```javascript // Monitor GCP quotas and usage class GCPResourceMonitor { constructor(gcp) { this.gcp = gcp; this.quotaAlerts = new Map(); } async monitorQuotas(services = ['compute', 'gke', 'cloudshell']) { for (const service of services) { const quotas = await this.gcp.getQuotaInfo(service); for (const quota of quotas) { const usagePercent = (quota.usage / quota.limit) * 100; if (usagePercent > 80) { console.warn(`High quota usage for ${quota.quotaName}: ${usagePercent.toFixed(1)}%`); if (usagePercent > 90) { this.sendQuotaAlert(quota, usagePercent); } } } } } sendQuotaAlert(quota, usagePercent) { const alertKey = `${quota.service}:${quota.quotaName}`; const lastAlert = this.quotaAlerts.get(alertKey); const now = Date.now(); // Throttle alerts to once per hour if (!lastAlert || (now - lastAlert) > 3600000) { console.error(`QUOTA ALERT: ${quota.quotaName} usage is ${usagePercent.toFixed(1)}% (${quota.usage}/${quota.limit} ${quota.unit})`); this.quotaAlerts.set(alertKey, now); // Send notification (implement your notification system) this.sendNotification('quota-alert', { service: quota.service, quota: quota.quotaName, usage: quota.usage, limit: quota.limit, usagePercent }); } } } ``` ## Security Best Practices ### IAM and Permissions ```javascript // Use least privilege principle for service accounts const secureConfig = { projectId: 'my-project', keyFile: './service-account-key.json', // Restricted service account // Required roles for different operations: // Cloud Shell: roles/cloudshell.user // Compute SSH: roles/compute.osLogin or roles/compute.instanceAdmin // GKE: roles/container.developer or roles/container.clusterAdmin // IAP: roles/iap.tunnelResourceAccessor // Additional security settings requireOSLogin: true, enableShieldedVm: true, usePrivateGoogleAccess: true }; ``` ### Network Security ```javascript // Secure network configuration const secureNetworkConfig = { projectId: 'secure-project', keyFile: './limited-service-account.json', // Use IAP instead of external IPs iapTunnelEnabled: true, // OS Login for centralized SSH key management osLoginEnabled: true, // Network tags for firewall rules networkTags: ['secure-access', 'monitoring'], // VPC configuration network: 'projects/shared-vpc-host/global/networks/secure-network', subnetwork: 'projects/shared-vpc-host/regions/us-central1/subnetworks/private-subnet', // Disable external IP access externalIpDisabled: true }; ``` ### Secret Management ```javascript // Use Google Secret Manager for sensitive data const secretConfig = { projectId: 'my-project', keyFile: './service-account-key.json', // Reference secrets instead of hardcoding secrets: { databasePassword: 'projects/my-project/secrets/db-password/versions/latest', apiKey: 'projects/my-project/secrets/api-key/versions/latest' } }; // Retrieve secrets during session setup gcp.on('session-connected', async (event) => { // Retrieve secret values (implement Secret Manager client) const dbPassword = await getSecretValue(secretConfig.secrets.databasePassword); const apiKey = await getSecretValue(secretConfig.secrets.apiKey); // Use secrets in commands await gcp.sendInput(event.sessionId, `export DB_PASSWORD='${dbPassword}'\n`); await gcp.sendInput(event.sessionId, `export API_KEY='${apiKey}'\n`); }); ``` ## Troubleshooting ### Common Issues 1. **Authentication Failures** ```bash # Check service account permissions gcloud auth activate-service-account --key-file=service-account-key.json gcloud auth list # Verify project access gcloud projects get-iam-policy PROJECT_ID ``` 2. **Cloud Shell Access Issues** - Verify Cloud Shell API is enabled - Check if user has `cloudshell.user` role - Ensure quota limits are not exceeded 3. **Compute Engine Connection Issues** - Verify VM is in RUNNING state - Check firewall rules allow SSH (port 22) - Ensure OS Login is properly configured - Verify service account has necessary compute roles 4. **GKE Access Issues** - Check cluster status and master authorized networks - Verify service account has container.developer role - Ensure kubectl credentials are valid ### Debug Mode ```javascript // Enable comprehensive logging const debugGcp = new GCPProtocol(); // Monitor all events debugGcp.on('*', (eventName, ...args) => { console.log(`GCP Event: ${eventName}`, args); }); // Get detailed session information const sessions = debugGcp.listSessions(); sessions.forEach(({ sessionId, type, session }) => { console.log(`Session ${sessionId} (${type}):`, session); }); // Monitor quota usage const quotaInfo = await debugGcp.getQuotaInfo('compute', 'us-central1'); console.log('Quota Information:', quotaInfo); // Check rate limiting const rateLimitInfo = debugGcp.getRateLimitInfo('compute', 'instances.get'); console.log('Rate Limit Info:', rateLimitInfo); ``` ## Integration Examples ### CI/CD Pipeline Integration ```javascript // Google Cloud Build integration class CloudBuildPipeline { constructor() { this.gcp = new GCPProtocol(); } async deployToGKE(environment) { const session = await this.gcp.createGKESession(`deploy-${environment}`, { projectId: process.env[`GCP_PROJECT_${environment.toUpperCase()}`], clusterName: `app-cluster-${environment}`, clusterLocation: 'us-central1-a', namespace: environment, keyFile: `./keys/${environment}-deploy-sa.json` }); try { // Deploy application await this.gcp.sendInput(session.sessionId, 'kubectl apply -f k8s/\n'); // Wait for rollout await this.gcp.sendInput(session.sessionId, 'kubectl rollout status deployment/app\n'); // Run smoke tests await this.gcp.sendInput(session.sessionId, 'kubectl run smoke-test --image=smoketest:latest --rm -it --restart=Never\n'); return { success: true, sessionId: session.sessionId }; } catch (error) { throw new Error(`Deployment failed: ${error.message}`); } } } ``` ### Infrastructure as Code ```javascript // Terraform deployment via Cloud Shell async function deployInfrastructure(workspaceName) { const session = await gcp.createCloudShellSession(`terraform-${workspaceName}`, { projectId: 'infrastructure-project', keyFile: './terraform-service-account.json', cloudShellType: 'bash', diskSizeGb: 20 // Extra space for Terraform state }); const terraformCommands = [ `cd /home/user/terraform/${workspaceName}`, 'terraform init', 'terraform workspace select ' + workspaceName, 'terraform plan -out=tfplan', 'terraform apply tfplan', 'terraform output -json > outputs.json', 'gsutil cp outputs.json gs://terraform-state-bucket/' ]; for (const command of terraformCommands) { await gcp.sendInput(session.sessionId, command + '\n'); // Wait for command completion await new Promise(resolve => { const timeout = setTimeout(resolve, 30000); // 30 second timeout gcp.once('output', (output) => { if (output.sessionId === session.sessionId && output.data.includes('$')) { clearTimeout(timeout); resolve(); } }); }); } return session.sessionId; } ``` ## API Reference ### Class: GCPProtocol #### Methods - `createCloudShellSession(sessionId, options)` - Create Cloud Shell session - `createComputeSession(sessionId, options)` - Create Compute Engine session - `createGKESession(sessionId, options)` - Create GKE session - `sendInput(sessionId, input)` - Send input to session - `closeSession(sessionId)` - Close session - `getSession(sessionId)` - Get session information - `listSessions()` - List all active sessions - `getQuotaInfo(service, region, zone)` - Get quota information - `getRateLimitInfo(service, method)` - Get rate limit information - `cleanup()` - Cleanup all sessions and resources #### Events - `session-created` - Session created successfully - `session-connected` - Session connection established - `session-disconnected` - Session connection lost - `session-error` - Session error occurred - `output` - Output received from session This comprehensive documentation covers all aspects of the GCP Protocol implementation, providing production-ready examples and best practices for Google Cloud Platform automation.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ooples/mcp-console-automation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server