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
| Name | Required | Description | Default |
|---|---|---|---|
| sequence | Yes | Input sequence to mutate | |
| sequenceType | Yes | Type of sequence: 'dna' or 'protein' | |
| substitutionRate | No | Substitution mutation rate (0-1), default 0.01 | |
| insertionRate | No | Insertion mutation rate (0-1), default 0.001 | |
| deletionRate | No | Deletion mutation rate (0-1), default 0.001 | |
| transitionBias | No | Transition vs transversion bias for DNA (default 2.0) | |
| iterations | No | Number of mutation iterations, default 1 | |
| seed | No | Random seed for reproducible results (optional) | |
| outputFormat | No | Output format: 'fasta' or 'plain' |
Implementation Reference
- src/tools/mutateSequence.ts:61-153 (handler)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) }] }; }
- src/tools/mutateSequence.ts:4-60 (schema)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; });
- src/tools/mutateSequence.ts:156-248 (helper)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; }