#
tokens: 1425/50000 5/5 files
lines: off (toggle) GitHub
raw markdown copy
# 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);
});

```