run-azure-code
Execute Azure-specific JavaScript code directly within the Azure MCP Server environment using provided SDK clients, ensuring efficient resource management, subscription handling, and error-free operations with structured JSON outputs.
Instructions
Run Azure code
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Your job is to answer questions about Azure environment by writing Javascript code using Azure SDK. The code must adhere to a few rules: - Use the provided client instances: 'resourceClient' for ResourceManagementClient, 'subscriptionClient' for SubscriptionClient, and 'authorizationClient' for AuthorizationManagementClient - DO NOT create new client instances or import Azure SDK packages - Use async/await and promises - Think step-by-step before writing the code - Avoid hardcoded values like Resource IDs - Handle errors gracefully - Handle pagination correctly using for-await-of loops - Data returned must be JSON containing only the minimal amount of data needed - Code MUST "return" a value: string, number, boolean or JSON object | |
| reasoning | Yes | The reasoning behind the code | |
| subscriptionId | No | Azure Subscription ID | |
| tenantId | No | Azure Tenant ID |
Input Schema (JSON Schema)
{
"properties": {
"code": {
"description": "Your job is to answer questions about Azure environment by writing Javascript code using Azure SDK. The code must adhere to a few rules:\n- Use the provided client instances: 'resourceClient' for ResourceManagementClient, 'subscriptionClient' for SubscriptionClient, and 'authorizationClient' for AuthorizationManagementClient\n- DO NOT create new client instances or import Azure SDK packages\n- Use async/await and promises\n- Think step-by-step before writing the code\n- Avoid hardcoded values like Resource IDs\n- Handle errors gracefully\n- Handle pagination correctly using for-await-of loops\n- Data returned must be JSON containing only the minimal amount of data needed\n- Code MUST \"return\" a value: string, number, boolean or JSON object",
"type": "string"
},
"reasoning": {
"description": "The reasoning behind the code",
"type": "string"
},
"subscriptionId": {
"description": "Azure Subscription ID",
"type": "string"
},
"tenantId": {
"description": "Azure Tenant ID",
"type": "string"
}
},
"required": [
"reasoning",
"code"
],
"type": "object"
}
Implementation Reference
- src/AzureServer.ts:493-528 (handler)The main handler function for the 'run-azure-code' tool. It validates input using RunAzureCodeSchema, initializes Azure clients if tenantId and subscriptionId are provided, wraps the user code for safe execution, and runs it in a Node.js VM sandbox with access to Azure client instances.private async handleRunAzureCode(args: any) { const { code, tenantId, subscriptionId } = RunAzureCodeSchema.parse(args); if (!this.context.selectedTenant && !tenantId) { throw new AzureMCPError( "Please select a tenant first using the 'select-tenant' tool!", "NO_TENANT" ); } if (tenantId && subscriptionId) { await this.initializeClients(tenantId, subscriptionId); } if (!this.context.resourceClient || !this.context.subscriptionClient) { throw new AzureMCPError("Clients not initialized", "NO_CLIENTS"); } const wrappedCode = this.wrapUserCode(code); const wrappedIIFECode = `(async function() { return (async () => { ${wrappedCode} })(); })()`; try { const result = await this.executeWithRetry(() => runInContext(wrappedIIFECode, createContext(this.context)) ); return this.createTextResponse(JSON.stringify(result)); } catch (error) { this.logWithContext("error", `Error executing user code: ${error}`, { error, }); throw new AzureMCPError( `Failed to execute code: ${error}`, "CODE_EXECUTION_FAILED" ); } }
- src/AzureServer.ts:1097-1105 (schema)Zod schema used to validate and parse the input arguments for the run-azure-code tool, including reasoning, code, and optional tenant/subscription IDs.const RunAzureCodeSchema = z.object({ reasoning: z .string() .min(1, "Reasoning cannot be empty") .describe("The reasoning behind the code"), code: z.string().min(1, "Code cannot be empty").describe(codePrompt), tenantId: z.string().optional().describe("Azure Tenant ID"), subscriptionId: z.string().optional().describe("Azure Subscription ID"), });
- src/AzureServer.ts:299-324 (registration)Tool definition registered in the handleListTools method, specifying the name, description, and input schema for the MCP protocol.{ name: "run-azure-code", description: "Run Azure code", inputSchema: { type: "object", properties: { reasoning: { type: "string", description: "The reasoning behind the code", }, code: { type: "string", description: codePrompt, }, tenantId: { type: "string", description: "Azure Tenant ID", }, subscriptionId: { type: "string", description: "Azure Subscription ID", }, }, required: ["reasoning", "code"], }, },
- src/AzureServer.ts:435-436 (registration)Switch case in handleCallTool that dispatches calls to the 'run-azure-code' tool to its handler function.case "run-azure-code": result = await this.handleRunAzureCode(args);
- src/AzureServer.ts:861-898 (helper)Helper function that sanitizes user-provided code (blocks process.env, require, import), uses ts-morph to ensure it returns a value, and prepares it for execution in the VM sandbox.private wrapUserCode(userCode: string): string { try { // Sanitize user code to prevent certain patterns const sanitizedCode = userCode .replace(/process\.env/g, "/* process.env access blocked */") .replace(/require\s*\(/g, "/* require blocked */") .replace(/import\s+.*\s+from/g, "/* import blocked */"); const project = new Project({ useInMemoryFileSystem: true, }); const sourceFile = project.createSourceFile("userCode.ts", sanitizedCode); 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(); } catch (error) { this.logWithContext("error", `Error wrapping user code: ${error}`, { error, }); throw new AzureMCPError( "Failed to process user code", "CODE_WRAP_FAILED" ); } }