# Directory Structure ``` ├── .gitignore ├── dist │ └── index.js ├── package-lock.json ├── package.json ├── README.md ├── sounds │ └── completion.mp3 ├── src │ └── index.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # Database *.db # testing /coverage # storybook storybook-static *storybook.log # playwright /test-results/ /playwright-report/ /playwright/.cache/ # next.js /.next /out # cache .swc/ # production /build # misc .DS_Store *.pem Thumbs.db # debug npm-debug.log* pnpm-debug.log* yarn-debug.log* yarn-error.log* # local env files .env*.local # Sentry Config File .env.sentry-build-plugin # local folder local # vercel .vercel ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Cursor Sound MCP A Model Context Protocol (MCP) implementation that plays sound effects after Cursor AI completes code generation. This MCP integrates with Cursor to provide audio feedback for a more interactive coding experience. Inspired by @EricListin on X.com - I have made some changes to the code to not error out and be online. ## Features - Plays a sound effect when Cursor completes code generation - Uses the Model Context Protocol (MCP) for standardized integration - Configurable sound effects - Improved error handling and logging - Stable JSON response format ## Cursor Rules Add this to your Cursor custom instructions: "EVERY TIME you finish any task or you need something from me, run the sound-mcp MCP server to get my attention." ## Installation 1. Install dependencies: ```bash npm install ``` 2. Add your sound effects: Place your sound files in the `sounds` directory. The default expected sound is: - `sounds/completion.mp3` - Played after code generation You can find free sound effects on freesound.org. 3. Build the project: ```bash npm run build ``` ## Usage Run the MCP server: ```bash npm start ``` The server will start and listen for events from Cursor through the stdio transport. ## Configuration The sound effects and volume can be customized by: 1. Replacing the sound files in the `sounds` directory 2. Modifying the sound file paths in `src/index.ts` ## Development For development with auto-recompilation: ```bash npm run dev ``` ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2022", "module": "ES2022", "moduleResolution": "node", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "typeRoots": ["./src/types", "./node_modules/@types"] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json { "name": "cursor-sound-mcp", "version": "1.0.0", "description": "MCP for Cursor that plays sounds after code generation", "main": "dist/index.js", "type": "module", "scripts": { "build": "tsc", "start": "node dist/index.js", "dev": "tsc -w" }, "keywords": [ "mcp", "cursor", "sound" ], "author": "", "license": "ISC", "dependencies": { "@modelcontextprotocol/sdk": "latest", "@types/play-sound": "^1.1.2", "play-sound": "^1.1.5", "zod": "^3.24.2" }, "devDependencies": { "@types/node": "^20.0.0", "typescript": "^5.0.0" } } ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import player from 'play-sound'; import path from 'path'; import { fileURLToPath } from 'url'; // Get the directory name of the current module const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const audioPlayer = player(); // Use the custom sound file from the sounds directory const COMPLETION_SOUND = path.join(__dirname, '..', 'sounds', 'completion.mp3'); // Set up a proper logging function that uses stderr const log = (message: string) => { process.stderr.write(`${message}\n`); }; async function main() { const server = new McpServer({ name: 'CursorSoundMCP', version: '1.0.0' }); // Tool to play sound after code generation server.tool( 'playCompletionSound', 'Plays a completion sound when called', async () => { try { // Play custom sound using a Promise to handle the callback properly await new Promise<void>((resolve, reject) => { audioPlayer.play(COMPLETION_SOUND, (err: Error | null) => { if (err) { log(`Error playing sound: ${err.message}`); reject(err); } else { log('Played completion sound successfully'); resolve(); } }); }); // Return proper JSON response return { content: [{ type: 'text', text: 'Played completion sound' }] }; } catch (error) { log(`Failed to play sound: ${error}`); return { content: [{ type: 'text', text: 'Failed to play sound' }] }; } } ); // Start the server using stdio transport const transport = new StdioServerTransport(); await server.connect(transport); log('Cursor Sound MCP server started...'); } main().catch(error => { log(`Failed to start MCP server: ${error}`); process.exit(1); }); ```