Skip to main content
Glama

gcp_sql_proxy

Connect locally to Google Cloud SQL databases by running a secure proxy, enabling database operations without exposing public IP addresses.

Instructions

Cloud SQL 프록시|DB 연결|sql proxy|database connect - Cloud SQL Proxy를 실행하여 로컬에서 Cloud SQL에 연결합니다

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
instanceNoCloud SQL 인스턴스 이름 (예: my-instance)
portNo로컬 포트 (기본: 5432 for PostgreSQL, 3306 for MySQL)
project_idNoGCP 프로젝트 ID (기본: 현재 설정된 프로젝트)
regionNo리전 (예: asia-northeast3)
actionNo수행할 작업 (기본: status)status

Implementation Reference

  • Main execution handler for the gcp_sql_proxy tool. Dispatches to status, start, or stop actions based on input.
    export async function gcpSqlProxy(args: SqlProxyArgs) {
      const action = args.action || 'status';
    
      try {
        switch (action) {
          case 'status':
            return await getProxyStatus();
          case 'start':
            return await startProxy(args);
          case 'stop':
            return await stopProxy(args);
          default:
            return {
              content: [{ type: 'text', text: `알 수 없는 액션: ${action}` }],
              isError: true,
            };
        }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `오류: ${error.message || error}` }],
          isError: true,
        };
      }
    }
  • Tool schema definition including input schema for parameters like action, instance, region, port.
    export const gcpSqlProxyDefinition = {
      name: 'gcp_sql_proxy',
      description: 'Cloud SQL 프록시|DB 연결|sql proxy|database connect - Cloud SQL Proxy를 실행하여 로컬에서 Cloud SQL에 연결합니다',
      annotations: {
        title: 'Cloud SQL Proxy 실행',
        readOnlyHint: false,
        destructiveHint: false,
        idempotentHint: false,
        openWorldHint: true,
      },
      inputSchema: {
        type: 'object' as const,
        properties: {
          instance: {
            type: 'string',
            description: 'Cloud SQL 인스턴스 이름 (예: my-instance)',
          },
          port: {
            type: 'number',
            description: '로컬 포트 (기본: 5432 for PostgreSQL, 3306 for MySQL)',
            default: 5432,
          },
          project_id: {
            type: 'string',
            description: 'GCP 프로젝트 ID (기본: 현재 설정된 프로젝트)',
          },
          region: {
            type: 'string',
            description: '리전 (예: asia-northeast3)',
          },
          action: {
            type: 'string',
            enum: ['start', 'status', 'stop'],
            description: '수행할 작업 (기본: status)',
            default: 'status',
          },
        },
        required: [],
      },
    };
  • src/index.ts:77-89 (registration)
    Registration of all tool definitions, including gcpSqlProxyDefinition, in the tools array used by ListToolsRequestHandler.
    const tools = [
      gcpSetupDefinition,
      gcpLogsReadDefinition,
      gcpRunStatusDefinition,
      gcpRunLogsDefinition,
      gcpSqlQueryDefinition,
      gcpSqlProxyDefinition,
      gcpStorageListDefinition,
      gcpSecretListDefinition,
      gcpAuthStatusDefinition,
      gcpServicesListDefinition,
      gcpBillingInfoDefinition,
    ];
  • src/index.ts:233-234 (registration)
    Dispatch case in the CallToolRequestSchema handler that routes calls to the gcpSqlProxy handler function.
    case 'gcp_sql_proxy':
      return await gcpSqlProxy(args as any) as CallToolResult;
  • Core helper function that starts the Cloud SQL proxy process, handles config fallback, validation, and process spawning.
    async function startProxy(args: SqlProxyArgs) {
      // Try to get instance info from config if not provided
      let instanceName = args.instance;
      let region = args.region;
      let port = args.port;
    
      // If instance not provided, try to get from config
      if (!instanceName) {
        const config = await readConfig();
        if (config?.cloud_sql?.length) {
          const firstInstance = config.cloud_sql[0];
          instanceName = firstInstance.name;
          region = region || firstInstance.region;
          port = port || firstInstance.port;
        }
      }
    
      if (!instanceName) {
        return {
          content: [{
            type: 'text',
            text: '❌ instance가 필요합니다.\n\n예: gcp_sql_proxy(action: "start", instance: "my-instance", region: "asia-northeast3")\n\n💡 또는 gcp_setup으로 .hi-gcloud.json에 cloud_sql 설정을 추가하세요.',
          }],
          isError: true,
        };
      }
    
      // If region not provided, try to get from config
      if (!region) {
        const config = await readConfig();
        const sqlConfig = config?.cloud_sql?.find((sql: CloudSqlInstance) => sql.name === instanceName);
        if (sqlConfig) {
          region = sqlConfig.region;
          port = port || sqlConfig.port;
        }
      }
    
      if (!region) {
        return {
          content: [{
            type: 'text',
            text: `❌ region이 필요합니다.\n\n예: gcp_sql_proxy(action: "start", instance: "${instanceName}", region: "asia-northeast3")`,
          }],
          isError: true,
        };
      }
    
      const projectId = await getProjectId(args.project_id);
      port = port || 5432;
      const connectionName = `${projectId}:${region}:${instanceName}`;
    
      // Find cloud-sql-proxy path
      let proxyPath = '';
      const possiblePaths = [
        'cloud-sql-proxy',
        'cloud_sql_proxy',
        '/usr/local/bin/cloud-sql-proxy',
        '/usr/local/bin/cloud_sql_proxy',
      ];
    
      for (const path of possiblePaths) {
        try {
          await execAsync(`${path} --version`, { timeout: 3000 });
          proxyPath = path;
          break;
        } catch {}
      }
    
      if (!proxyPath) {
        return {
          content: [{
            type: 'text',
            text: '❌ Cloud SQL Proxy가 설치되지 않았습니다.\n\ngcp_sql_proxy(action: "status")로 설치 방법을 확인하세요.',
          }],
          isError: true,
        };
      }
    
      // Check if port is already in use
      try {
        await execAsync(`lsof -i :${port}`, { timeout: 3000 });
        return {
          content: [{
            type: 'text',
            text: `❌ 포트 ${port}가 이미 사용 중입니다.\n\n다른 포트를 지정하세요: gcp_sql_proxy(action: "start", instance: "${instanceName}", port: ${port + 1})`,
          }],
          isError: true,
        };
      } catch {
        // Port is available
      }
    
      // Start proxy in background
      const proxyProcess = spawn(proxyPath, [
        connectionName,
        '--port', port.toString(),
      ], {
        detached: true,
        stdio: 'ignore',
      });
    
      proxyProcess.unref();
    
      // Wait a moment and check if it started
      await new Promise(resolve => setTimeout(resolve, 2000));
    
      // Verify proxy is running
      try {
        const { stdout } = await execAsync(`lsof -i :${port}`, { timeout: 3000 });
        if (stdout.includes('cloud')) {
          return {
            content: [{
              type: 'text',
              text: `✅ Cloud SQL Proxy 시작됨
    
    📡 연결 정보:
    - 인스턴스: ${connectionName}
    - 로컬 포트: ${port}
    - PID: ${proxyProcess.pid}
    
    💡 연결 예시:
    \`\`\`bash
    # PostgreSQL
    psql -h localhost -p ${port} -U postgres -d your_database
    
    # MySQL
    mysql -h 127.0.0.1 -P ${port} -u root -p
    \`\`\`
    
    🛑 중지: gcp_sql_proxy(action: "stop")`,
            }],
          };
        }
      } catch {}
    
      return {
        content: [{
          type: 'text',
          text: `⚠️ 프록시 시작을 시도했지만 확인이 필요합니다.
    
    연결 이름: ${connectionName}
    포트: ${port}
    
    gcp_sql_proxy(action: "status")로 상태를 확인하세요.`,
        }],
      };
    }

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/su-record/hi-gcloud'

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