Skip to main content
Glama

analyze_icecast_config

Check an Icecast XML configuration file for security flaws, performance issues, capacity limits, and reliability risks, then receive actionable recommendations to optimize your streaming server.

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

  • src/index.ts:319-357 (registration)
    Tool registration in ListToolsRequestSchema handler under the name 'analyze_icecast_config' with input schema requiring configPath and optional expectedListeners.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            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"],
            },
          },
          {
            name: "get_icecast_best_practices",
            description: "Get general best practices and recommendations for Icecast configuration based on use case",
            inputSchema: {
              type: "object",
              properties: {
                useCase: {
                  type: "string",
                  description: "Use case: 'small' (< 50 listeners), 'medium' (50-500 listeners), 'large' (500+ listeners)",
                  enum: ["small", "medium", "large"],
                },
              },
              required: ["useCase"],
            },
          },
        ],
      };
    });
  • Main handler logic in CallToolRequestSchema. Reads the XML file from disk, parses it, analyzes the config, and returns a formatted report.
    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 shape of an Icecast configuration object, used for type inference and validation.
    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(),
    });
  • Parses raw XML content into a typed IcecastConfig 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 || {};
    }
  • Core analysis function that inspects the parsed config and returns an array of ConfigIssue objects covering security, performance, capacity, and reliability.
    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;
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool analyzes and provides recommendations, but does not mention that it is read-only, what permissions might be needed, or any potential side effects. The description is adequate but lacks detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description consists of two concise sentences that immediately convey the primary action and scope. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no output schema, two parameters) and lack of annotations, the description is fairly complete: it identifies the file type, the action, and the areas of analysis. However, it could be improved by specifying the output format or nature of recommendations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for both parameters, so the schema already explains their meaning. The tool description itself does not elaborate on the parameters, but given the schema coverage, it does not need to. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Analyze' and the resource 'Icecast XML configuration file', and specifies the areas of improvement (security, performance, capacity, reliability). This distinguishes it from the sibling tool 'get_icecast_best_practices', which likely provides general best practices rather than analyzing a specific file.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies that the tool should be used when you have a specific Icecast configuration file to analyze, but it does not explicitly state when to use it versus the sibling tool 'get_icecast_best_practices'. No guidance on prerequisites or when not to use it is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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