synth-execute
Generate and execute SynthDef code to produce sound. Input SynthDef details and duration for playback, ideal for real-time audio synthesis and testing.
Instructions
SynthDefのコードを生成し、そのコードを実行して音を出します。 コードは{}でくくるようにしてください。
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| duration | No | 再生時間(ミリ秒)。デフォルトは5000(5秒) | |
| synth | Yes | 再生するシンセの情報 |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration": {
"description": "再生時間(ミリ秒)。デフォルトは5000(5秒)",
"type": "number"
},
"synth": {
"additionalProperties": false,
"description": "再生するシンセの情報",
"properties": {
"code": {
"description": "シンセのコード",
"type": "string"
},
"name": {
"description": "シンセの名前",
"type": "string"
}
},
"required": [
"name",
"code"
],
"type": "object"
}
},
"required": [
"synth"
],
"type": "object"
}
Implementation Reference
- src/index.ts:99-140 (handler)Executes the provided SynthDef code using SuperCollider server: initializes server, creates synthDef and synth, plays for specified duration, then cleans up and returns execution details.async ({ synth, duration = 5000 }) => { try { const scServer = await initServer(); const def = await scServer.synthDef(synth.name, synth.code); await scServer.synth(def); console.error(`シンセを${duration / 1000}秒間演奏中...`); await new Promise(resolve => setTimeout(resolve, duration)); await cleanupServer(); console.error('シンセの演奏完了'); return { content: [ { type: "text", text: `シンセ名: ${synth.name}`, }, { type: "text", text: `コード: ${synth.code}`, }, { type: "text", text: `再生時間: ${duration / 1000}秒`, } ], }; } catch (error) { console.error("SuperCollider実行エラー:", error); return { content: [ { type: "text", text: `エラーが発生しました: ${error instanceof Error ? error.message : JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, } ], }; } }
- src/index.ts:92-98 (schema)Zod schema for tool inputs: required 'synth' object with 'name' and 'code' strings, optional 'duration' number in milliseconds.{ synth: z.object({ name: z.string().describe("シンセの名前"), code: z.string().describe("シンセのコード") }).describe("再生するシンセの情報"), duration: z.number().optional().describe("再生時間(ミリ秒)。デフォルトは5000(5秒)") },
- src/index.ts:88-141 (registration)Registers the 'synth-execute' tool on the MCP server with name, description, input schema, and handler function.server.tool( "synth-execute", `SynthDefのコードを生成し、そのコードを実行して音を出します。 コードは{}でくくるようにしてください。`, { synth: z.object({ name: z.string().describe("シンセの名前"), code: z.string().describe("シンセのコード") }).describe("再生するシンセの情報"), duration: z.number().optional().describe("再生時間(ミリ秒)。デフォルトは5000(5秒)") }, async ({ synth, duration = 5000 }) => { try { const scServer = await initServer(); const def = await scServer.synthDef(synth.name, synth.code); await scServer.synth(def); console.error(`シンセを${duration / 1000}秒間演奏中...`); await new Promise(resolve => setTimeout(resolve, duration)); await cleanupServer(); console.error('シンセの演奏完了'); return { content: [ { type: "text", text: `シンセ名: ${synth.name}`, }, { type: "text", text: `コード: ${synth.code}`, }, { type: "text", text: `再生時間: ${duration / 1000}秒`, } ], }; } catch (error) { console.error("SuperCollider実行エラー:", error); return { content: [ { type: "text", text: `エラーが発生しました: ${error instanceof Error ? error.message : JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, } ], }; } } );
- src/index.ts:21-46 (helper)Initializes and boots the SuperCollider server lazily, ensuring singleton instance.async function initServer(): Promise<SCServer> { if (serverInitPromise) { return serverInitPromise; } serverInitPromise = (async () => { try { console.error("SuperColliderサーバーを起動中..."); const server = await (sc as any).server.boot({ debug: false, echo: false, stderr: './supercollider-error.log' }) as SCServer; console.error("SuperColliderサーバー起動完了"); scServerInstance = server; return server; } catch (err) { console.error("SuperColliderサーバー起動エラー:", err); serverInitPromise = null; throw err; } })(); return serverInitPromise!; }
- src/index.ts:55-79 (helper)Shuts down the SuperCollider server, kills processes, and resets state. Used after tool execution.async function cleanupServer() { if (scServerInstance) { try { await scServerInstance.quit(); scServerInstance = null; serverInitPromise = null; activeSynths = []; try { if (process.platform === 'win32') { require('child_process').execSync('taskkill /F /IM sclang.exe', { stdio: 'ignore' }); } else { require('child_process').execSync('pkill -f sclang', { stdio: 'ignore' }); } } catch (killErr) { console.error('sclangプロセス終了試行:', killErr); } console.error('SuperColliderサーバーを終了しました'); } catch (error) { console.error("サーバー終了エラー:", error); } } }