Skip to main content
Glama

analyze_icecast_config

Analyze Icecast XML configuration files to check security, performance, capacity, and reliability settings, providing actionable recommendations for improvements.

Instructions

Analyze an Icecast XML configuration file and provide recommendations for improvements. Checks security, performance, capacity, and reliability settings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
configPathYesPath to the Icecast XML configuration file
expectedListenersNoExpected number of concurrent listeners (optional, default: 100)

Implementation Reference

  • The main execution handler for the 'analyze_icecast_config' tool within the CallToolRequestSchema handler. Reads the config file, parses XML, analyzes the config, formats issues into a markdown report, and returns the result or error.
    if (name === "analyze_icecast_config") { const configPath = args.configPath as string; const expectedListeners = (args.expectedListeners as number) || 100; try { const xmlContent = readFileSync(configPath, "utf-8"); const config = parseIcecastConfig(xmlContent); const issues = analyzeConfig(config, { expectedListeners }); const report = formatIssues(issues); return { content: [ { type: "text", text: `# Icecast Configuration Analysis\n\nAnalyzing: ${configPath}\nExpected listeners: ${expectedListeners}\n\n${report}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error analyzing configuration: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }
  • Zod schema defining the expected structure of the Icecast configuration object for type safety and validation reference.
    const IcecastConfigSchema = z.object({ location: z.string().optional(), admin: z.string().optional(), limits: z.object({ clients: z.number().optional(), sources: z.number().optional(), "queue-size": z.number().optional(), "burst-size": z.number().optional(), threadpool: z.number().optional(), "source-timeout": z.number().optional(), "header-timeout": z.number().optional(), "client-timeout": z.number().optional(), }).optional(), authentication: z.object({ "source-password": z.string().optional(), "admin-user": z.string().optional(), "admin-password": z.string().optional(), "relay-password": z.string().optional(), }).optional(), hostname: z.string().optional(), "listen-socket": z.union([ z.object({ port: z.number().optional(), "bind-address": z.string().optional(), }), z.array(z.object({ port: z.number().optional(), "bind-address": z.string().optional(), })) ]).optional(), fileserve: z.number().optional(), "use-x-forwarded-for": z.number().optional(), mount: z.union([ z.object({ "mount-name": z.string(), }), z.array(z.object({ "mount-name": z.string(), })) ]).optional(), paths: z.object({ logdir: z.string().optional(), webroot: z.string().optional(), adminroot: z.string().optional(), pidfile: z.string().optional(), }).optional(), logging: z.object({ accesslog: z.string().optional(), errorlog: z.string().optional(), loglevel: z.number().optional(), logsize: z.number().optional(), logarchive: z.number().optional(), }).optional(), });
  • src/index.ts:322-339 (registration)
    Tool registration in the ListToolsRequestSchema handler, defining the tool name, description, and input schema.
    { name: "analyze_icecast_config", description: "Analyze an Icecast XML configuration file and provide recommendations for improvements. Checks security, performance, capacity, and reliability settings.", inputSchema: { type: "object", properties: { configPath: { type: "string", description: "Path to the Icecast XML configuration file", }, expectedListeners: { type: "number", description: "Expected number of concurrent listeners (optional, default: 100)", }, }, required: ["configPath"], }, },
  • Primary helper function performing the detailed analysis of the Icecast configuration, identifying issues across categories like security, performance, capacity, and providing recommendations.
    function analyzeConfig(config: IcecastConfig, context?: { expectedListeners?: number }): ConfigIssue[] { const issues: ConfigIssue[] = []; const expectedListeners = context?.expectedListeners || 100; // Check client limits const clientLimit = config.limits?.clients; if (clientLimit !== undefined) { if (clientLimit > 1000 && expectedListeners < 500) { issues.push({ severity: "info", category: "Performance", issue: "Client limit may be unnecessarily high", recommendation: `Client limit is ${clientLimit}. Consider lowering to ${Math.max(128, expectedListeners * 2)} unless you expect high traffic.`, currentValue: clientLimit, recommendedValue: Math.max(128, expectedListeners * 2), }); } if (clientLimit < 50) { issues.push({ severity: "warning", category: "Capacity", issue: "Client limit is quite low", recommendation: `Client limit is ${clientLimit}. This may cause connection rejections during peak times.`, currentValue: clientLimit, recommendedValue: 128, }); } } else { issues.push({ severity: "warning", category: "Configuration", issue: "No client limit specified", recommendation: "Set an explicit client limit to control resource usage.", recommendedValue: 128, }); } // Check authentication if (!config.authentication) { issues.push({ severity: "critical", category: "Security", issue: "No authentication configured", recommendation: "Configure source-password and admin-password to secure your stream.", }); } else { if (config.authentication["admin-user"] === "admin") { issues.push({ severity: "warning", category: "Security", issue: "Using default admin username", recommendation: "Change admin username from 'admin' to something less predictable.", currentValue: "admin", }); } if (!config.authentication["relay-password"]) { issues.push({ severity: "info", category: "Security", issue: "No relay password configured", recommendation: "If you plan to use relays, configure a relay-password.", }); } } // Check mount configuration if (!config.mount) { issues.push({ severity: "warning", category: "Configuration", issue: "No mount points configured", recommendation: "Configure at least one mount point with appropriate settings.", }); } else { const mounts = Array.isArray(config.mount) ? config.mount : [config.mount]; if (mounts.length === 1) { issues.push({ severity: "info", category: "Reliability", issue: "No fallback mount configured", recommendation: "Consider adding a fallback mount for better reliability.", }); } } // Check logging if (config.logging) { if (!config.logging.logarchive) { issues.push({ severity: "info", category: "Maintenance", issue: "Log archiving not configured", recommendation: "Enable log archiving to automatically rotate old logs.", recommendedValue: 1, }); } const logLevel = config.logging.loglevel; if (logLevel !== undefined && logLevel > 3) { issues.push({ severity: "info", category: "Performance", issue: "High log verbosity", recommendation: `Log level is ${logLevel}. Consider level 3 for production (4 for debug).`, currentValue: logLevel, recommendedValue: 3, }); } } // Check burst size const burstSize = config.limits?.["burst-size"]; const queueSize = config.limits?.["queue-size"]; if (burstSize && queueSize && burstSize > queueSize / 2) { issues.push({ severity: "warning", category: "Performance", issue: "Burst size is very large relative to queue size", recommendation: `Burst size (${burstSize}) should typically be less than half of queue size (${queueSize}).`, currentValue: burstSize, recommendedValue: Math.floor(queueSize / 2), }); } // Check hostname if (config.hostname === "localhost") { issues.push({ severity: "info", category: "Configuration", issue: "Hostname is set to localhost", recommendation: "Set hostname to your actual domain name for proper stream URLs in directory listings.", }); } // Check X-Forwarded-For if (config["use-x-forwarded-for"] === 1) { issues.push({ severity: "info", category: "Configuration", issue: "X-Forwarded-For is enabled", recommendation: "Good! This is correct when running behind a reverse proxy like Caddy.", }); } return issues; }
  • Helper function to parse the Icecast XML configuration file into a JavaScript object using fast-xml-parser.
    function parseIcecastConfig(xmlContent: string): IcecastConfig { const parser = new XMLParser({ ignoreAttributes: false, parseTagValue: true, parseAttributeValue: true, }); const parsed = parser.parse(xmlContent); return parsed.icecast || {}; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/splinesreticulating/icecast-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server