Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
ahmedarafa994 avatar

Mix Analyzer Mcp

  • 1 installs
  • Updated March 1, 2026
  • ahmedarafa994/ai-music-analyzer

mix-analyzer-mcp is a Claude Code skill that provides patterns for building MCP server tools that connect AI assistants to the Mix Analyzer audio-analysis API.

About

mix-analyzer-mcp is a Claude Code skill with patterns for developing MCP (Model Context Protocol) server tools for the Mix Analyzer audio-analysis API. It shows how to define Zod input schemas, register tools, implement handlers that call the analysis API, upload audio from a URL, and handle errors. A developer uses it when adding or modifying MCP tools that let AI assistants analyze audio mixes.

  • Patterns for building MCP tools that call the Mix Analyzer audio-analysis API
  • Zod input schemas, tool registration (ListTools/CallTool), and API helper patterns
  • Handles file upload from URL and MCP error handling with McpError

Mix Analyzer Mcp by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #14,102 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Jul 7, 2026 (Skillselion catalog sync)
At a glance

mix-analyzer-mcp capabilities & compatibility

Requires a running Mix Analyzer API (MIX_ANALYZER_API_URL, defaults to localhost:8000).

Capabilities
mcp tool development · api integration
Works with
anthropic
Use cases
api development · orchestration
From the docs

What mix-analyzer-mcp says it does

This skill provides patterns for developing MCP tools that allow AI assistants to interact with the Mix Analyzer API.
SKILL.md
The MCP server (`mcp/src/index.ts`) provides tools for AI systems to:
SKILL.md
const API_BASE_URL = process.env.MIX_ANALYZER_API_URL || 'http://localhost:8000'
SKILL.md
npx skills add https://github.com/ahmedarafa994/ai-music-analyzer --skill mix-analyzer-mcp

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
Last updatedMarch 1, 2026
Repositoryahmedarafa994/ai-music-analyzer

What it does

Add or modify MCP tools that let AI assistants analyze audio mixes via the Mix Analyzer API.

Who is it for?

Extending an MCP server that exposes an audio-analysis API to AI assistants.

When should I use this skill?

Adding an MCP tool, creating a new MCP endpoint, or extending the Mix Analyzer MCP server.

What you get

  • New MCP tool with schema, handler, and registration
  • TypeScript MCP server code

By the numbers

  • Analysis modules include 17 named types (frequency, dynamic_range, stereo, transient, harmonic, clarity, spatial, voice_

Files

SKILL.mdMarkdownGitHub ↗

Mix Analyzer MCP Server Development

This skill provides patterns for developing MCP tools that allow AI assistants to interact with the Mix Analyzer API.

MCP Server Overview

The MCP server (mcp/src/index.ts) provides tools for AI systems to:

  • Analyze audio from URLs or local files
  • Retrieve analysis results and summaries
  • Query specific module data (frequency, dynamics, stereo, etc.)
  • Get usage statistics

Project Structure

mcp/
├── src/
│   └── index.ts        # Main MCP server implementation
├── package.json
├── tsconfig.json
└── README.md

Creating a New MCP Tool

Step 1: Define the Schema

Use Zod for input validation:

// Define input schema
const GetModuleDataSchema = z.object({
  analysis_id: z.string().uuid().describe('The UUID of the analysis'),
  module_name: z.enum([
    'frequency', 'dynamic_range', 'stereo', 'transient',
    'harmonic', 'clarity', 'spatial', 'voice_gender',
    'genre', 'mood', 'instrument', 'surround', 'playback',
    'keywords', 'reference', 'scoring', 'ai_recommendations'
  ]).describe('The module to retrieve data for'),
})

Step 2: Implement the Handler

async function getModuleData(args: z.infer<typeof GetModuleDataSchema>) {
  const { analysis_id, module_name } = args

  // Fetch analysis from API
  const analysis = await apiRequest<AnalysisResponse>(
    `/api/v1/analysis/${analysis_id}`
  )

  // Extract module data
  const moduleData = analysis.results?.[module_name]

  if (!moduleData) {
    throw new McpError(
      ErrorCode.InvalidRequest,
      `Module '${module_name}' not found in analysis ${analysis_id}`
    )
  }

  return {
    module: module_name,
    score: moduleData.score,
    data: moduleData.data,
    issues: moduleData.issues,
    recommendations: moduleData.recommendations,
  }
}

Step 3: Register the Tool

Add to the ListToolsRequestSchema handler:

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    // ... existing tools ...
    {
      name: 'get_module_data',
      description: 'Retrieve data from a specific analysis module',
      inputSchema: {
        type: 'object',
        properties: {
          analysis_id: {
            type: 'string',
            description: 'The UUID of the analysis',
          },
          module_name: {
            type: 'string',
            enum: [
              'frequency', 'dynamic_range', 'stereo', 'transient',
              'harmonic', 'clarity', 'spatial', 'voice_gender',
              'genre', 'mood', 'instrument', 'surround', 'playback',
              'keywords', 'reference', 'scoring', 'ai_recommendations'
            ],
            description: 'The module to retrieve data for',
          },
        },
        required: ['analysis_id', 'module_name'],
      },
    },
  ],
}))

Add to the CallToolRequestSchema handler:

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params

  try {
    switch (name) {
      // ... existing cases ...
      case 'get_module_data': {
        const parsed = GetModuleDataSchema.parse(args)
        const result = await getModuleData(parsed)
        return {
          content: [{
            type: 'text',
            text: JSON.stringify(result, null, 2),
          }],
        }
      }

      default:
        throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`)
    }
  } catch (error) {
    if (error instanceof z.ZodError) {
      throw new McpError(ErrorCode.InvalidParams, error.message)
    }
    throw error
  }
})

API Helper Pattern

const API_BASE_URL = process.env.MIX_ANALYZER_API_URL || 'http://localhost:8000'

async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
  const url = `${API_BASE_URL}${endpoint}`

  const response = await fetch(url, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      ...options.headers,
    },
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new McpError(
      ErrorCode.InternalError,
      `API request failed: ${error.detail || response.statusText}`
    )
  }

  return response.json()
}

File Upload Pattern

For tools that upload files:

async function uploadFromUrl(audioUrl: string, filename?: string): Promise<{ analysis_id: string }> {
  // Fetch audio from URL
  const audioResponse = await fetch(audioUrl)
  if (!audioResponse.ok) {
    throw new McpError(
      ErrorCode.InvalidParams,
      `Failed to fetch audio from URL: ${audioResponse.statusText}`
    )
  }

  const audioBuffer = await audioResponse.arrayBuffer()
  const audioBlob = new Blob([audioBuffer])

  // Determine filename
  const urlFilename = audioUrl.split('/').pop() || 'audio.mp3'
  const finalFilename = filename || urlFilename

  // Create form data
  const formData = new FormData()
  formData.append('file', audioBlob, finalFilename)

  // Upload to API
  const response = await fetch(`${API_BASE_URL}/api/v1/upload`, {
    method: 'POST',
    body: formData,
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Upload failed' }))
    throw new McpError(ErrorCode.InternalError, error.detail)
  }

  return response.json()
}

Error Handling

import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'

// Invalid parameters
throw new McpError(ErrorCode.InvalidParams, 'Parameter X is required')

// API errors
throw new McpError(ErrorCode.InternalError, `API error: ${message}`)

// Not found
throw new McpError(ErrorCode.InvalidRequest, `Analysis ${id} not found`)

// Method not found
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`)

Response Formatting

Return JSON with consistent structure:

return {
  content: [{
    type: 'text',
    text: JSON.stringify({
      success: true,
      data: result,
    }, null, 2),
  }],
}

For human-readable summaries:

function formatAnalysisSummary(analysis: AnalysisResponse): string {
  const lines = [
    `# Analysis Summary: ${analysis.filename}`,
    ``,
    `- **Duration**: ${analysis.duration?.toFixed(1)}s`,
    `- **Sample Rate**: ${analysis.sample_rate} Hz`,
    `- **Overall Score**: ${analysis.overall_score ?? 'N/A'}`,
    ``,
    `## Module Scores`,
  ]

  for (const [module, score] of Object.entries(analysis.module_scores || {})) {
    lines.push(`- ${module}: ${(score * 100).toFixed(0)}%`)
  }

  return lines.join('\n')
}

Building and Testing

cd mcp

# Build TypeScript
npm run build

# Development mode
npm run dev

# Test with Claude Desktop (add to config)

Claude Desktop configuration:

{
  "mcpServers": {
    "mix-analyzer": {
      "command": "node",
      "args": ["/path/to/mix-analyzer/mcp/dist/index.js"],
      "env": {
        "MIX_ANALYZER_API_URL": "http://localhost:8000"
      }
    }
  }
}

Available Tool Patterns

Analysis Tools

  • analyze_audio_url - Analyze from URL
  • analyze_local_file - Analyze local file
  • get_analysis_results - Full results
  • get_analysis_summary - Human-readable summary

Module-Specific Tools

  • get_frequency_analysis - Frequency data
  • get_dynamic_range - Dynamics data
  • get_stereo_analysis - Stereo imaging data
  • get_ai_recommendations - AI suggestions

Utility Tools

  • get_statistics - Usage stats
  • delete_analysis - Remove analysis

Related skills

AI & Agent Buildingagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.