Skip to main content
Glama
coreymhudson

MCP Sequence Simulation Server

by coreymhudson

mutate_sequence

Apply mutations to DNA or protein sequences with configurable substitution, insertion, and deletion rates for evolutionary simulation and bioinformatics testing.

Instructions

Apply mutations to DNA or protein sequences

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sequenceYesInput sequence to mutate
sequenceTypeYesType of sequence: 'dna' or 'protein'
substitutionRateNoSubstitution mutation rate (0-1), default 0.01
insertionRateNoInsertion mutation rate (0-1), default 0.001
deletionRateNoDeletion mutation rate (0-1), default 0.001
transitionBiasNoTransition vs transversion bias for DNA (default 2.0)
iterationsNoNumber of mutation iterations, default 1
seedNoRandom seed for reproducible results (optional)
outputFormatNoOutput format: 'fasta' or 'plain'

Implementation Reference

  • Main handler function that executes the mutate_sequence tool logic. It applies mutations to DNA or protein sequences over multiple iterations, tracking changes and returning statistics in FASTA or plain format.
    async handler({ sequence, sequenceType, substitutionRate = 0.01, insertionRate = 0.001, deletionRate = 0.001, transitionBias = 2.0, iterations = 1, seed, outputFormat = "fasta" }: { sequence: string; sequenceType: string; substitutionRate?: number; insertionRate?: number; deletionRate?: number; transitionBias?: number; iterations?: number; seed?: number; outputFormat?: string; }) { const generator = new SequenceGenerator(seed); const mutationParams: MutationParameters = { substitutionRate, insertionRate, deletionRate, transitionBias }; const results = []; let currentSequence = sequence.toUpperCase(); results.push({ iteration: 0, sequence: currentSequence, length: currentSequence.length, changes: [] }); for (let i = 1; i <= iterations; i++) { const previousSequence = currentSequence; if (sequenceType === 'dna') { currentSequence = generator.mutateDNA(currentSequence, mutationParams); } else { currentSequence = mutateProtein(currentSequence, mutationParams, generator); } const changes = findChanges(previousSequence, currentSequence); results.push({ iteration: i, sequence: currentSequence, length: currentSequence.length, changes: changes, changeCount: changes.length }); } let output = ''; if (outputFormat === 'fasta') { output = results.map(result => `>mutated_${sequenceType}_iter_${result.iteration} length=${result.length} changes=${result.changeCount || 0}\n${result.sequence}` ).join('\n\n'); } else { output = results.map(result => result.sequence).join('\n'); } const finalSequence = results[results.length - 1]; const totalChanges = results.slice(1).reduce((sum, r) => sum + (r.changeCount || 0), 0); const stats = { originalLength: sequence.length, finalLength: finalSequence.length, totalIterations: iterations, totalChanges, mutationRates: mutationParams, sequenceType, seed: seed || "random" }; return { content: [{ type: "text", text: JSON.stringify({ statistics: stats, mutations: results, sequences: outputFormat === 'fasta' ? output : undefined, rawOutput: outputFormat === 'plain' ? output : undefined }, null, 2) }] }; }
  • Tool definition including name, description, and input schema. Defines parameters for sequence, sequenceType (dna/protein), mutation rates (substitution, insertion, deletion), transition bias, iterations, random seed, and output format.
    export const mutateSequence = { definition: { name: "mutate_sequence", description: "Apply mutations to DNA or protein sequences", inputSchema: { type: "object", properties: { sequence: { type: "string", description: "Input sequence to mutate" }, sequenceType: { type: "string", description: "Type of sequence: 'dna' or 'protein'", enum: ["dna", "protein"] }, substitutionRate: { type: "number", description: "Substitution mutation rate (0-1), default 0.01", minimum: 0, maximum: 1 }, insertionRate: { type: "number", description: "Insertion mutation rate (0-1), default 0.001", minimum: 0, maximum: 1 }, deletionRate: { type: "number", description: "Deletion mutation rate (0-1), default 0.001", minimum: 0, maximum: 1 }, transitionBias: { type: "number", description: "Transition vs transversion bias for DNA (default 2.0)", minimum: 0 }, iterations: { type: "number", description: "Number of mutation iterations, default 1", minimum: 1 }, seed: { type: "number", description: "Random seed for reproducible results (optional)" }, outputFormat: { type: "string", description: "Output format: 'fasta' or 'plain'", enum: ["fasta", "plain"] } }, required: ["sequence", "sequenceType"] }, },
  • src/server.ts:26-36 (registration)
    Tool registration in the ListToolsRequestSchema handler. The mutate_sequence tool definition is registered in the tools list that the server exposes.
    server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ generateDNA.definition, generateProtein.definition, mutateSequence.definition, evolveSequence.definition, simulatePhylogeny.definition, simulateFastq.definition, ], };
  • src/server.ts:67-78 (registration)
    Handler registration in the CallToolRequestSchema switch statement. When the tool 'mutate_sequence' is called, this routes the request to the mutateSequence.handler function.
    case "mutate_sequence": return await mutateSequence.handler(args as { sequence: string; sequenceType: string; substitutionRate?: number; insertionRate?: number; deletionRate?: number; transitionBias?: number; iterations?: number; seed?: number; outputFormat?: string; });
  • Helper functions for the mutate_sequence tool: mutateProtein handles protein-specific mutations, and findChanges compares sequences to identify substitutions, insertions, and deletions.
    function mutateProtein(sequence: string, params: MutationParameters, generator: SequenceGenerator): string { const { substitutionRate = 0.01, insertionRate = 0.001, deletionRate = 0.001 } = params; const aminoAcids = ['A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I', 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V']; let mutated = sequence.split(''); for (let i = 0; i < mutated.length; i++) { if (Math.random() < substitutionRate) { const currentAA = mutated[i]; let newAA; do { newAA = aminoAcids[Math.floor(Math.random() * aminoAcids.length)]; } while (newAA === currentAA); mutated[i] = newAA; } if (Math.random() < insertionRate) { const randomAA = aminoAcids[Math.floor(Math.random() * aminoAcids.length)]; mutated.splice(i, 0, randomAA); i++; } if (Math.random() < deletionRate && mutated.length > 1) { mutated.splice(i, 1); i--; } } return mutated.join(''); } function findChanges(original: string, mutated: string): Array<{ type: 'substitution' | 'insertion' | 'deletion'; position: number; original?: string; mutated?: string; }> { const changes: Array<{ type: 'substitution' | 'insertion' | 'deletion'; position: number; original?: string; mutated?: string; }> = []; let i = 0, j = 0; while (i < original.length || j < mutated.length) { if (i >= original.length) { changes.push({ type: 'insertion', position: j, mutated: mutated[j] }); j++; } else if (j >= mutated.length) { changes.push({ type: 'deletion', position: i, original: original[i] }); i++; } else if (original[i] !== mutated[j]) { if (i + 1 < original.length && original[i + 1] === mutated[j]) { changes.push({ type: 'deletion', position: i, original: original[i] }); i++; } else if (j + 1 < mutated.length && original[i] === mutated[j + 1]) { changes.push({ type: 'insertion', position: j, mutated: mutated[j] }); j++; } else { changes.push({ type: 'substitution', position: i, original: original[i], mutated: mutated[j] }); i++; j++; } } else { i++; j++; } } return changes; }

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/coreymhudson/mcp-sequence-simulation'

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