Skip to main content
Glama
dandeliongold

Decent-Sampler Drums MCP Server

generate_drum_groups

Create DecentSampler drum kit XML configurations by organizing samples into groups with velocity layers, muting, and optional advanced controls for realistic drum presets.

Instructions

Generate DecentSampler XML for drum kits.

This tool supports two configuration types:

BasicDrumKitConfig:

  • For simple presets with minimal features

  • No UI controls, effects, or routing

  • Only supports basic sample mapping and optional velocity layers

  • Recommended for straightforward drum kits

AdvancedDrumKitConfig:

  • For complex setups combining multiple features

  • Supports UI controls, effects, and routing

  • Integrates with other tools (configure_drum_controls, configure_mic_routing, etc.)

  • Use when you need advanced features like round robin or multi-mic setups

Best Practices:

  • IMPORTANT: Always use absolute paths (e.g., 'C:/Users/username/Documents/Samples/kick.wav')

  • Group all samples for a drum piece into a single group

  • When using multiple mic positions, include them all in the same group

  • Use velocity layers within a group to control dynamics

Error Handling:

  • Validates all sample paths exist

  • Checks for valid MIDI note numbers

  • Ensures velocity layers don't overlap

  • Verifies muting group configurations

  • Returns specific errors for any invalid settings

Example Configurations:

  1. Basic Configuration (simple drum kit): { "globalSettings": { "velocityLayers": [ { "low": 1, "high": 42, "name": "soft" }, { "low": 43, "high": 85, "name": "medium" }, { "low": 86, "high": 127, "name": "hard" } ] }, "drumPieces": [{ "name": "Kick", "rootNote": 36, "samples": [ {"path": "C:/Samples/Kick_Soft.wav"}, {"path": "C:/Samples/Kick_Medium.wav"}, {"path": "C:/Samples/Kick_Hard.wav"} ] }] }

  2. Advanced Configuration (multi-mic kit with controls): { "globalSettings": { "velocityLayers": [ { "low": 1, "high": 127, "name": "full" } ], "drumControls": { "kick": { "pitch": { "default": 0, "min": -12, "max": 12 }, "envelope": { "attack": 0.001, "decay": 0.5, "sustain": 0, "release": 0.1 } } }, "micBuses": [ { "name": "Close Mic", "outputTarget": "MAIN_OUTPUT", "volume": { "default": 0, "midiCC": 20 } } ] }, "drumPieces": [{ "name": "Kick", "rootNote": 36, "samples": [ { "path": "C:/Samples/Kick_Close.wav", "micConfig": { "position": "close", "busIndex": 0 } } ], "muting": { "tags": ["kick"], "silencedByTags": [] } }] }

Success Response: Returns complete XML structure with:

  • Organized sample groups

  • Velocity layer mappings

  • Muting group configurations

  • All sample references and settings

  • Advanced features when using AdvancedDrumKitConfig

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
globalSettingsYes
drumPiecesYes

Implementation Reference

  • MCP CallToolRequestSchema handler case for 'generate_drum_groups'. Validates input using type guards for BasicDrumKitConfig or AdvancedDrumKitConfig and calls generateGroupsXml to produce the XML output.
    case "generate_drum_groups": {
      // Validate input matches our expected type
      const args = request.params.arguments;
      if (!args || typeof args !== 'object') {
        throw new McpError(
          ErrorCode.InvalidParams,
          "Invalid arguments: expected object"
        );
      }
    
      // Try advanced configuration first
      if (isAdvancedDrumKitConfig(args)) {
        const xml = generateGroupsXml(args);
        return {
          content: [{
            type: "text",
            text: xml
          }]
        };
      }
    
      // Fall back to basic configuration
      if (isBasicDrumKitConfig(args)) {
        const config: BasicDrumKitConfig = args;
        const xml = generateGroupsXml(config);
        return {
          content: [{
            type: "text",
            text: xml
          }]
        };
      }
    
      throw new McpError(
        ErrorCode.InvalidParams,
        "Invalid arguments: does not match either BasicDrumKitConfig or AdvancedDrumKitConfig schema"
      );
    }
  • Core helper function that implements the drum groups XML generation logic. Processes drum pieces, samples, applies velocity layers, muting, round-robin, envelopes, pitch controls, and mic bus routing based on the configuration type.
    export function generateGroupsXml(config: BasicDrumKitConfig | AdvancedDrumKitConfig): string {
      const { globalSettings, drumPieces } = config;
      
      // Generate buses XML if mic routing is configured (advanced only)
      const busesXml = 'micBuses' in globalSettings && globalSettings.micBuses ? 
        configureMicBuses(globalSettings.micBuses) : '';
      
      // Add round robin attributes to top-level groups if configured
      const roundRobinAttrs = 'roundRobin' in globalSettings && globalSettings.roundRobin
        ? ` seqMode="${globalSettings.roundRobin.mode}"${
            globalSettings.roundRobin.length 
              ? ` seqLength="${globalSettings.roundRobin.length}"`
              : ''
          }`
        : '';
    
      const groups: string[] = [];
    
      for (const piece of drumPieces) {
        // Combine muting and round robin attributes for group (advanced only)
        let groupAttrs = 'muting' in piece && piece.muting 
          ? ` tags="${piece.muting.tags.join(',')}" silencedByTags="${piece.muting.silencedByTags.join(',')}" silencingMode="fast"`
          : '';
        
        // Add group-level round robin settings if present
        if ('seqMode' in piece && piece.seqMode) {
          groupAttrs += ` seqMode="${piece.seqMode}"`;
        }
        if ('seqLength' in piece && piece.seqLength) {
          groupAttrs += ` seqLength="${piece.seqLength}"`;
        }
        if ('seqPosition' in piece && piece.seqPosition) {
          groupAttrs += ` seqPosition="${piece.seqPosition}"`;
        }
    
        // Add drum controls if configured (advanced only)
        const drumControls = 'drumControls' in globalSettings && globalSettings.drumControls?.[piece.name];
        let envelopeAttrs = '';
        let pitchControl = '';
        
        if (drumControls) {
          // Add envelope attributes if configured
          if (drumControls.envelope) {
            const env = drumControls.envelope;
            envelopeAttrs = ` attack="${env.attack}" decay="${env.decay}" sustain="${env.sustain}" release="${env.release}"`;
            if (env.attackCurve !== undefined) envelopeAttrs += ` attackCurve="${env.attackCurve}"`;
            if (env.decayCurve !== undefined) envelopeAttrs += ` decayCurve="${env.decayCurve}"`;
            if (env.releaseCurve !== undefined) envelopeAttrs += ` releaseCurve="${env.releaseCurve}"`;
          }
          
          // Add pitch control if configured
          if (drumControls.pitch) {
            const pitch = drumControls.pitch;
            groupAttrs += ` tuning="${pitch.default}"`;
            pitchControl = `      <control type="pitch" name="${piece.name} Pitch" default="${pitch.default}"` +
              (pitch.min !== undefined ? ` minimum="${pitch.min}"` : '') +
              (pitch.max !== undefined ? ` maximum="${pitch.max}"` : '') +
              `>\n        <binding type="general" level="group" position="0" parameter="groupTuning" />\n      </control>\n`;
          }
        }
    
        const sampleElements: string[] = [];
        
        for (const sample of piece.samples) {
          const volumeAttr = sample.volume ? ` volume="${sample.volume}"` : '';
          let velocityAttrs = '';
          if (globalSettings.velocityLayers) {
            const layerIndex = piece.samples.indexOf(sample);
            if (layerIndex < globalSettings.velocityLayers.length) {
              const layer = globalSettings.velocityLayers[layerIndex];
              velocityAttrs = ` loVel="${layer.low}" hiVel="${layer.high}"`;
            }
          }
          
          // Add sample-level round robin settings
          let sampleRRAttrs = '';
          if ('seqMode' in sample && sample.seqMode) {
            sampleRRAttrs += ` seqMode="${sample.seqMode}"`;
          }
          if ('seqLength' in sample && sample.seqLength) {
            sampleRRAttrs += ` seqLength="${sample.seqLength}"`;
          }
          if ('seqPosition' in sample && sample.seqPosition) {
            sampleRRAttrs += ` seqPosition="${sample.seqPosition}"`;
          }
    
          // Generate sample element with bus routing if configured (advanced only)
          const sampleXml = 'micConfig' in sample && sample.micConfig ? 
            generateSampleBusRouting(sample.path, sample.micConfig.busIndex, sample.micConfig.volume) :
            `      <sample path="${sample.path}"${volumeAttr} rootNote="${piece.rootNote}" ` +
            `loNote="${piece.rootNote}" hiNote="${piece.rootNote}"${velocityAttrs}${sampleRRAttrs} />`;
          
          sampleElements.push(sampleXml);
        }
    
        groups.push(
          `  <group name="${piece.name}" ampVelTrack="1"${groupAttrs}${envelopeAttrs}>\n` +
          (pitchControl ? pitchControl : '') +
          `${sampleElements.join('\n')}\n` +
          `  </group>`
        );
      }
    
      // Combine buses and groups XML
      const xml = [];
      if (busesXml) xml.push(busesXml);
      xml.push(`<groups${roundRobinAttrs}>\n${groups.join('\n\n')}\n</groups>`);
      
      return xml.join('\n\n');
    }
  • src/index.ts:386-544 (registration)
    Registration of the 'generate_drum_groups' tool in the ListToolsRequestSchema response, including comprehensive description and input schema defining the expected structure for globalSettings and drumPieces.
          {
            name: "generate_drum_groups",
            description: `Generate DecentSampler <groups> XML for drum kits.
    
    This tool supports two configuration types:
    
    BasicDrumKitConfig:
    - For simple presets with minimal features
    - No UI controls, effects, or routing
    - Only supports basic sample mapping and optional velocity layers
    - Recommended for straightforward drum kits
    
    AdvancedDrumKitConfig:
    - For complex setups combining multiple features
    - Supports UI controls, effects, and routing
    - Integrates with other tools (configure_drum_controls, configure_mic_routing, etc.)
    - Use when you need advanced features like round robin or multi-mic setups
    
    Best Practices:
    - IMPORTANT: Always use absolute paths (e.g., 'C:/Users/username/Documents/Samples/kick.wav')
    - Group all samples for a drum piece into a single group
    - When using multiple mic positions, include them all in the same group
    - Use velocity layers within a group to control dynamics
    
    Error Handling:
    - Validates all sample paths exist
    - Checks for valid MIDI note numbers
    - Ensures velocity layers don't overlap
    - Verifies muting group configurations
    - Returns specific errors for any invalid settings
    
    Example Configurations:
    
    1. Basic Configuration (simple drum kit):
    {
      "globalSettings": {
        "velocityLayers": [
          { "low": 1, "high": 42, "name": "soft" },
          { "low": 43, "high": 85, "name": "medium" },
          { "low": 86, "high": 127, "name": "hard" }
        ]
      },
      "drumPieces": [{
        "name": "Kick",
        "rootNote": 36,
        "samples": [
          {"path": "C:/Samples/Kick_Soft.wav"},
          {"path": "C:/Samples/Kick_Medium.wav"},
          {"path": "C:/Samples/Kick_Hard.wav"}
        ]
      }]
    }
    
    2. Advanced Configuration (multi-mic kit with controls):
    {
      "globalSettings": {
        "velocityLayers": [
          { "low": 1, "high": 127, "name": "full" }
        ],
        "drumControls": {
          "kick": {
            "pitch": { "default": 0, "min": -12, "max": 12 },
            "envelope": {
              "attack": 0.001,
              "decay": 0.5,
              "sustain": 0,
              "release": 0.1
            }
          }
        },
        "micBuses": [
          {
            "name": "Close Mic",
            "outputTarget": "MAIN_OUTPUT",
            "volume": { "default": 0, "midiCC": 20 }
          }
        ]
      },
      "drumPieces": [{
        "name": "Kick",
        "rootNote": 36,
        "samples": [
          {
            "path": "C:/Samples/Kick_Close.wav",
            "micConfig": {
              "position": "close",
              "busIndex": 0
            }
          }
        ],
        "muting": {
          "tags": ["kick"],
          "silencedByTags": []
        }
      }]
    }
    
    Success Response:
    Returns complete XML structure with:
    - Organized sample groups
    - Velocity layer mappings
    - Muting group configurations
    - All sample references and settings
    - Advanced features when using AdvancedDrumKitConfig`,
            inputSchema: {
              type: "object",
              properties: {
                globalSettings: {
                  type: "object",
                  properties: {
                    velocityLayers: {
                      type: "array",
                      items: {
                        type: "object",
                        properties: {
                          low: { type: "number" },
                          high: { type: "number" },
                          name: { type: "string" }
                        },
                        required: ["low", "high", "name"]
                      }
                    }
                  },
                  required: []
                },
                drumPieces: {
                  type: "array",
                  items: {
                    type: "object",
                    properties: {
                      name: { type: "string" },
                      rootNote: { type: "number" },
                      samples: {
                        type: "array",
                        items: {
                          type: "object",
                          properties: {
                            path: { type: "string" },
                            volume: { type: "string" }
                          },
                          required: ["path"]
                        }
                      },
                      muting: {
                        type: "object",
                        properties: {
                          tags: { type: "array", items: { type: "string" } },
                          silencedByTags: { type: "array", items: { type: "string" } }
                        },
                        required: ["tags", "silencedByTags"]
                      }
                    },
                    required: ["name", "rootNote", "samples"]
                  }
                }
              },
              required: ["globalSettings", "drumPieces"]
            }
          }
  • JSON schema for tool input validation, specifying structure for global settings (velocity layers) and drum pieces (name, rootNote, samples with path/volume, optional muting).
    inputSchema: {
      type: "object",
      properties: {
        globalSettings: {
          type: "object",
          properties: {
            velocityLayers: {
              type: "array",
              items: {
                type: "object",
                properties: {
                  low: { type: "number" },
                  high: { type: "number" },
                  name: { type: "string" }
                },
                required: ["low", "high", "name"]
              }
            }
          },
          required: []
        },
        drumPieces: {
          type: "array",
          items: {
            type: "object",
            properties: {
              name: { type: "string" },
              rootNote: { type: "number" },
              samples: {
                type: "array",
                items: {
                  type: "object",
                  properties: {
                    path: { type: "string" },
                    volume: { type: "string" }
                  },
                  required: ["path"]
                }
              },
              muting: {
                type: "object",
                properties: {
                  tags: { type: "array", items: { type: "string" } },
                  silencedByTags: { type: "array", items: { type: "string" } }
                },
                required: ["tags", "silencedByTags"]
              }
            },
            required: ["name", "rootNote", "samples"]
          }
        }
      },
      required: ["globalSettings", "drumPieces"]
    }
  • Type guard helper used in handler to validate BasicDrumKitConfig inputs, ensuring no advanced features are present and basic structure is correct.
    // Type guard for BasicDrumKitConfig
    export function isBasicDrumKitConfig(obj: unknown): obj is BasicDrumKitConfig {
      if (!obj || typeof obj !== 'object') return false;
    
      const config = obj as Partial<BasicDrumKitConfig>;
      
      // Check globalSettings and ensure no advanced features
      if (!config.globalSettings || typeof config.globalSettings !== 'object') {
        return false;
      }
    
      // Check for advanced features in globalSettings
      const globalSettings = config.globalSettings as any;
      if (
        globalSettings.drumControls !== undefined ||
        globalSettings.roundRobin !== undefined ||
        globalSettings.micBuses !== undefined
      ) {
        return false;
      }
    
      // Validate velocity layers if they exist
      if (config.globalSettings.velocityLayers !== undefined) {
        if (!Array.isArray(config.globalSettings.velocityLayers)) {
          return false;
        }
        
        if (!config.globalSettings.velocityLayers.every(layer => 
          layer &&
          typeof layer === 'object' &&
          typeof layer.low === 'number' &&
          typeof layer.high === 'number' &&
          typeof layer.name === 'string'
        )) {
          return false;
        }
      }
    
      // Check drumPieces
      if (!Array.isArray(config.drumPieces)) {
        return false;
      }
    
      return config.drumPieces.every(piece => 
        piece &&
        typeof piece === 'object' &&
        typeof piece.name === 'string' &&
        typeof piece.rootNote === 'number' &&
        Array.isArray(piece.samples) &&
        piece.samples.every(sample => {
          if (!sample || typeof sample !== 'object' || typeof sample.path !== 'string') {
            return false;
          }
    
          // Optional volume validation
          if (sample.volume !== undefined && typeof sample.volume !== 'string') {
            return false;
          }
    
          // Check for advanced sample features
          const sampleObj = sample as any;
          if (
            sampleObj.seqPosition !== undefined ||
            sampleObj.micConfig !== undefined
          ) {
            return false;
          }
    
          return true;
        }) &&
        // Check for advanced drum piece features
        !(piece as any).muting
      );
    }
Behavior4/5

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

With no annotations provided, the description carries full burden and does an excellent job disclosing behavioral traits: it explains error handling (validates paths, MIDI notes, velocity layers), best practices (absolute paths, grouping samples), and success response details. It doesn't mention performance characteristics like rate limits or authentication needs, but covers most operational behavior thoroughly.

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

Conciseness4/5

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

The description is well-structured with clear sections (configuration types, best practices, error handling, examples, success response) and every sentence adds value. While comprehensive, it's appropriately sized for a complex tool with 0% schema coverage. The front-loaded purpose statement is clear, though some details could be more condensed.

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

Completeness5/5

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

Given the complexity (2 nested parameters, 0% schema coverage, no output schema, no annotations), the description provides complete context: it explains what the tool does, how to use it, what inputs mean, what errors to expect, and what the output contains. The examples and success response details compensate for the lack of output schema.

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

Parameters5/5

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

With 0% schema description coverage and 2 complex nested parameters, the description compensates fully by explaining both configuration types in detail, providing comprehensive examples, and clarifying the meaning of key fields like velocityLayers, drumPieces, samples, muting, and advanced features. It adds substantial meaning beyond the bare schema structure.

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 specific action ('Generate DecentSampler <groups> XML for drum kits') with the exact output format and target resource. It distinguishes from sibling tools by focusing on XML generation rather than analysis or configuration tasks like 'analyze_wav_samples' or 'configure_drum_controls'.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use each configuration type (BasicDrumKitConfig vs AdvancedDrumKitConfig), including specific scenarios and recommendations. It mentions integration with sibling tools ('configure_drum_controls, configure_mic_routing, etc.') and clearly states when to use advanced features versus basic ones.

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/dandeliongold/mcp-decent-sampler-drums'

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