azureai-optimizer
Version:
AI-Powered Azure Infrastructure Optimization via Model Context Protocol
158 lines • 7.11 kB
JavaScript
#!/usr/bin/env node
/**
* MCP Server Entry Point
* Minimal wrapper for MCP stdio communication
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
// Disable all console output to prevent protocol interference
console.log = () => { };
console.error = () => { };
async function main() {
try {
const server = new Server({
name: 'azureai-optimizer',
version: '1.0.4'
});
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'analyze_cost_optimization',
description: 'Analyze Azure costs and provide optimization recommendations',
inputSchema: {
type: 'object',
properties: {
subscription_id: { type: 'string', description: 'Azure subscription ID' },
days_back: { type: 'number', description: 'Number of days to analyze', default: 30 }
}
}
},
{
name: 'security_compliance_check',
description: 'Check Azure security compliance against frameworks',
inputSchema: {
type: 'object',
properties: {
subscription_id: { type: 'string', description: 'Azure subscription ID' },
compliance_framework: {
type: 'string',
enum: ['SOC2', 'ISO27001', 'PCI-DSS', 'HIPAA'],
description: 'Compliance framework to check against'
}
}
}
},
{
name: 'right_size_resources',
description: 'Analyze and recommend right-sizing for Azure resources',
inputSchema: {
type: 'object',
properties: {
subscription_id: { type: 'string', description: 'Azure subscription ID' },
resource_types: {
type: 'array',
items: { type: 'string' },
description: 'Resource types to analyze'
}
}
}
},
{
name: 'performance_analysis',
description: 'Analyze performance metrics and identify bottlenecks',
inputSchema: {
type: 'object',
properties: {
subscription_id: { type: 'string', description: 'Azure subscription ID' },
resource_group: { type: 'string', description: 'Resource group to analyze' }
}
}
}
]
};
});
// Execute tool
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
// Check if required environment variables are set
if (!process.env.AZURE_SUBSCRIPTION_ID) {
throw new McpError(ErrorCode.InvalidRequest, 'AZURE_SUBSCRIPTION_ID environment variable is required. Please configure it in your MCP client.');
}
// For now, return a mock response to test the connection
const mockResponses = {
analyze_cost_optimization: {
status: 'success',
message: 'Cost analysis requires valid Azure credentials',
subscription_id: args?.subscription_id || process.env.AZURE_SUBSCRIPTION_ID,
total_cost: 0,
recommendations: [
'Configure Azure authentication to enable cost analysis',
'Set AZURE_TENANT_ID environment variable',
'Optionally configure AI providers (OPENROUTER_API_KEY recommended)'
]
},
security_compliance_check: {
status: 'success',
message: 'Security compliance check requires valid Azure credentials',
framework: args?.compliance_framework || 'SOC2',
compliance_score: 0,
findings: [
'Azure authentication required for security assessment',
'Configure credentials to scan your resources'
]
},
right_size_resources: {
status: 'success',
message: 'Resource right-sizing requires valid Azure credentials',
recommendations: [
'Configure Azure authentication to analyze resources',
'AI-powered analysis available with OPENROUTER_API_KEY'
]
},
performance_analysis: {
status: 'success',
message: 'Performance analysis requires valid Azure credentials',
metrics: {
cpu_utilization: 'N/A',
memory_utilization: 'N/A',
network_throughput: 'N/A'
}
}
};
const result = mockResponses[name] || {
status: 'error',
message: `Unknown tool: ${name}`
};
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
};
});
const transport = new StdioServerTransport();
await server.connect(transport);
// The server is now running and waiting for requests
// Keep the process alive
process.on('SIGINT', async () => {
await server.close();
process.exit(0);
});
process.on('SIGTERM', async () => {
await server.close();
process.exit(0);
});
}
catch (error) {
// In MCP mode, we can't log to stderr, so just exit with error code
process.exit(1);
}
}
// Start immediately when imported
main();
//# sourceMappingURL=mcp-entry.js.map