run-gcp-code
Execute TypeScript code using Google Cloud Client Libraries to query and manage GCP resources like Compute Engine, Cloud Storage, and BigQuery across projects and regions.
Instructions
Run GCP code
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| reasoning | Yes | The reasoning behind the code | |
| code | Yes | Your job is to answer questions about GCP environment by writing Javascript/TypeScript code using Google Cloud Client Libraries. The code must adhere to a few rules: - Must use promises and async/await - Think step-by-step before writing the code, approach it logically - Must be written in TypeScript using official Google Cloud client libraries - Avoid hardcoded values like project IDs - Code written should be as parallel as possible enabling the fastest and most optimal execution - Code should handle errors gracefully, especially when doing multiple API calls - Each error should be handled and logged with a reason, script should continue to run despite errors - Data returned from GCP APIs must be returned as JSON containing only the minimal amount of data needed to answer the question - All extra data must be filtered out - Code MUST "return" a value: string, number, boolean or JSON object - If code does not return anything, it will be considered as FAILED - Whenever tool/function call fails, retry it 3 times before giving up - When listing resources, ensure pagination is handled correctly - Do not include any comments in the code - Try to write code that returns as few data as possible to answer without any additional processing required Be concise, professional and to the point. Do not give generic advice, always reply with detailed & contextual data sourced from the current GCP environment. | |
| projectId | No | GCP project ID to use | |
| region | No | Region to use (if not provided, us-central1 is used) |
Implementation Reference
- index.ts:348-403 (handler)Main handler logic for the 'run-gcp-code' tool. Parses input, sets up a sandboxed context with GCP clients, wraps and executes the user-provided code using vm.runInContext, and returns the result or error.if (name === "run-gcp-code") { const { reasoning, code, projectId, region } = RunGCPCodeSchema.parse(args); if (!selectedProject && !projectId) { const projects = await listAvailableProjects(); return createTextResponse( `Please select a project first using the 'select-project' tool! Available projects: ${projects.join(", ")}` ); } if (projectId) { selectedProjectCredentials = await auth.getClient(); selectedProject = projectId; selectedRegion = region || "us-central1"; } // Initialize context with better error handling and type safety const context = { selectedProject, selectedRegion, compute: new InstancesClient({ projectId: selectedProject || undefined }), storage: new Storage({ projectId: selectedProject || undefined }), functions: new CloudFunctionsServiceClient({ projectId: selectedProject || undefined }), run: new ServicesClient({ projectId: selectedProject || undefined }), bigquery: new BigQuery({ projectId: selectedProject || undefined }), resourceManager: new ProjectsClient({ projectId: selectedProject || undefined }), container: new ClusterManagerClient({ projectId: selectedProject || undefined }), logging: new Logging({ projectId: selectedProject || undefined }), sql: new SqlInstancesServiceClient({ projectId: selectedProject || undefined }), // Add helper functions retry: async <T>(fn: () => Promise<T>, retries = 3): Promise<T> => { try { return await fn(); } catch (error) { if (retries > 0) { console.error(`Operation failed, retrying... (${retries} attempts left)`); await new Promise(resolve => setTimeout(resolve, 1000)); return context.retry(fn, retries - 1); } throw error; } }, // Add documentation help: () => gcpClientDocs }; try { const wrappedCode = wrapUserCode(code); const wrappedIIFECode = `(async function() { return (async () => { ${wrappedCode} })(); })()`; const result = await runInContext(wrappedIIFECode, createContext(context)); return createTextResponse(JSON.stringify(result, null, 2)); } catch (error: any) { console.error('Error executing GCP code:', error); return createTextResponse(`Error executing GCP code: ${error.message}\n\nAvailable clients and their usage:\n${gcpClientDocs}`); }
- index.ts:72-97 (registration)Tool registration in the listTools response, including name, description, and input schema definition.{ name: "run-gcp-code", description: "Run GCP code", inputSchema: { type: "object", properties: { reasoning: { type: "string", description: "The reasoning behind the code", }, code: { type: "string", description: codePrompt, }, projectId: { type: "string", description: "GCP project ID to use", }, region: { type: "string", description: "Region to use (if not provided, us-central1 is used)", }, }, required: ["reasoning", "code"], }, },
- index.ts:216-221 (schema)Zod schema for validating 'run-gcp-code' tool arguments, used in the handler.const RunGCPCodeSchema = z.object({ reasoning: z.string(), code: z.string(), projectId: z.string().optional(), region: z.string().optional(), });
- index.ts:658-678 (helper)Helper function to wrap user code, ensuring it returns a value by modifying the AST with ts-morph if necessary.function wrapUserCode(userCode: string) { const project = new Project({ useInMemoryFileSystem: true, }); const sourceFile = project.createSourceFile("userCode.ts", userCode); const lastStatement = sourceFile.getStatements().pop(); if ( lastStatement && lastStatement.getKind() === SyntaxKind.ExpressionStatement ) { const returnStatement = lastStatement.asKind(SyntaxKind.ExpressionStatement); if (returnStatement) { const expression = returnStatement.getExpression(); sourceFile.addStatements(`return ${expression.getText()};`); returnStatement.remove(); } } return sourceFile.getFullText(); }