import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema, type CallToolRequest } from '@modelcontextprotocol/sdk/types.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { handleManageAzureResources, manageAzureResourcesTool, ManageAzureResourcesSchema } from './tools/azure-manager.js';
import { handleGetAzureContext, getAzureContextTool, GetAzureContextSchema } from './tools/context-retriever.js';
import { handleAzureService, azureServiceTool, AzureServiceSchema } from './tools/service-tool.js';
import { validateAzureCLI } from './lib/cli-executor.js';
import { validateCredential } from './lib/auth.js';
import { logger } from './lib/logger.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
const SERVER_NAME = 'azure-omni-tool';
const SERVER_VERSION: string = pkg.version;
type ToolHandler = (args: unknown) => Promise<unknown>;
const toolRegistry = new Map<string, { tool: object; schema: object; handler: ToolHandler }>([
['manage_azure_resources', {
tool: manageAzureResourcesTool,
schema: ManageAzureResourcesSchema,
handler: args => handleManageAzureResources(ManageAzureResourcesSchema.parse(args))
}],
['get_azure_context', {
tool: getAzureContextTool,
schema: GetAzureContextSchema,
handler: args => handleGetAzureContext(GetAzureContextSchema.parse(args))
}],
['azure_service', {
tool: azureServiceTool,
schema: AzureServiceSchema,
handler: args => handleAzureService(AzureServiceSchema.parse(args))
}],
]);
function createServer(): Server {
const server = new Server(
{ name: SERVER_NAME, version: SERVER_VERSION },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: Array.from(toolRegistry.values()).map(r => r.tool),
}));
server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
const { name, arguments: args } = request.params;
try {
const registration = toolRegistry.get(name);
if (!registration) {
return {
content: [{
type: 'text', text: JSON.stringify({
error: `Unknown tool: ${name}`,
available: Array.from(toolRegistry.keys())
})
}],
isError: true,
};
}
const result = await registration.handler(args);
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
} catch (error) {
const msg = error instanceof Error ? error.message : 'Unknown error';
logger.error(`Tool ${name} error`, error instanceof Error ? error : undefined);
return {
content: [{ type: 'text', text: JSON.stringify({ error: msg, tool: name, suggestion: 'Check parameters and retry.' }) }],
isError: true,
};
}
});
return server;
}
async function main(): Promise<void> {
console.error(`[${SERVER_NAME}] Starting v${SERVER_VERSION}`);
const [cliOk, credOk] = await Promise.all([validateAzureCLI(), validateCredential()]);
if (!cliOk) {
console.error(`[${SERVER_NAME}] WARNING: Azure CLI not found. Install: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli`);
} else {
console.error(`[${SERVER_NAME}] Azure CLI detected`);
}
if (!credOk) {
console.error(`[${SERVER_NAME}] WARNING: Azure credentials not configured. Run "az login" or configure environment.`);
} else {
console.error(`[${SERVER_NAME}] Azure credentials validated`);
}
const server = createServer();
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(`[${SERVER_NAME}] Ready. Tools: ${Array.from(toolRegistry.keys()).join(', ')}`);
}
main().catch(error => {
console.error(`[${SERVER_NAME}] Fatal:`, error);
process.exit(1);
});