nascoder-azure-ai-mcp
Version:
Professional Azure AI Foundry MCP Server with comprehensive Azure AI services integration, intelligent routing, and advanced capabilities for AI assistants.
184 lines • 6.26 kB
JavaScript
import { z } from 'zod';
// MCP Error Codes
export const MCPErrorCodes = {
PARSE_ERROR: -32700,
INVALID_REQUEST: -32600,
METHOD_NOT_FOUND: -32601,
INVALID_PARAMS: -32602,
INTERNAL_ERROR: -32603,
TOOL_ERROR: -32000,
};
export class MCPServer {
name;
version;
description;
tools = new Map();
resources = new Map();
constructor(name, version, description) {
this.name = name;
this.version = version;
this.description = description;
}
registerTool(tool) {
this.tools.set(tool.name, tool);
}
registerResource(uri, resource) {
this.resources.set(uri, resource);
}
async handleRequest(request) {
try {
switch (request.method) {
case 'initialize':
return this.handleInitialize(request);
case 'tools/list':
return this.handleToolsList(request);
case 'tools/call':
return this.handleToolCall(request);
case 'resources/list':
return this.handleResourcesList(request);
case 'resources/read':
return this.handleResourceRead(request);
default:
return this.createErrorResponse(request.id, MCPErrorCodes.METHOD_NOT_FOUND, `Method '${request.method}' not found`);
}
}
catch (error) {
return this.createErrorResponse(request.id, MCPErrorCodes.INTERNAL_ERROR, error instanceof Error ? error.message : 'Unknown error');
}
}
handleInitialize(request) {
return {
jsonrpc: '2.0',
id: request.id,
result: {
protocolVersion: '2024-11-05',
capabilities: {
tools: {},
resources: {},
},
serverInfo: {
name: this.name,
version: this.version,
description: this.description,
},
},
};
}
handleToolsList(request) {
const tools = Array.from(this.tools.values()).map(tool => ({
name: tool.name,
description: tool.description,
inputSchema: this.zodToJsonSchema(tool.inputSchema),
}));
return {
jsonrpc: '2.0',
id: request.id,
result: { tools },
};
}
async handleToolCall(request) {
const { name, arguments: args } = request.params;
const tool = this.tools.get(name);
if (!tool) {
return this.createErrorResponse(request.id, MCPErrorCodes.METHOD_NOT_FOUND, `Tool '${name}' not found`);
}
try {
// Validate input parameters
const validatedArgs = tool.inputSchema.parse(args);
// Execute tool
const result = await tool.handler(validatedArgs);
return {
jsonrpc: '2.0',
id: request.id,
result: {
content: [
{
type: 'text',
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
},
],
},
};
}
catch (error) {
if (error instanceof z.ZodError) {
return this.createErrorResponse(request.id, MCPErrorCodes.INVALID_PARAMS, `Invalid parameters: ${error.message}`);
}
return this.createErrorResponse(request.id, MCPErrorCodes.TOOL_ERROR, error instanceof Error ? error.message : 'Tool execution failed');
}
}
handleResourcesList(request) {
const resources = Array.from(this.resources.keys()).map(uri => ({
uri,
name: uri.split('/').pop() || uri,
description: `Resource: ${uri}`,
mimeType: 'application/json',
}));
return {
jsonrpc: '2.0',
id: request.id,
result: { resources },
};
}
handleResourceRead(request) {
const { uri } = request.params;
const resource = this.resources.get(uri);
if (!resource) {
return this.createErrorResponse(request.id, MCPErrorCodes.METHOD_NOT_FOUND, `Resource '${uri}' not found`);
}
return {
jsonrpc: '2.0',
id: request.id,
result: {
contents: [
{
uri,
mimeType: 'application/json',
text: JSON.stringify(resource, null, 2),
},
],
},
};
}
createErrorResponse(id, code, message) {
return {
jsonrpc: '2.0',
id,
error: { code, message },
};
}
zodToJsonSchema(schema) {
// Simple Zod to JSON Schema conversion
// In production, use a proper library like zod-to-json-schema
if (schema instanceof z.ZodObject) {
const shape = schema.shape;
const properties = {};
const required = [];
for (const [key, value] of Object.entries(shape)) {
const zodValue = value; // Type assertion for Zod schema
if (zodValue instanceof z.ZodString) {
properties[key] = { type: 'string' };
}
else if (zodValue instanceof z.ZodNumber) {
properties[key] = { type: 'number' };
}
else if (zodValue instanceof z.ZodBoolean) {
properties[key] = { type: 'boolean' };
}
else {
properties[key] = { type: 'string' }; // fallback
}
if (!zodValue.isOptional()) {
required.push(key);
}
}
return {
type: 'object',
properties,
required,
};
}
return { type: 'object' }; // fallback
}
}
//# sourceMappingURL=protocol.js.map