Content
# 🎛️ audio-dsp-mcp
> **MCP server for DSP and audio modems**: signal generation, modulation (FSK/ASK/BPSK), analysis, equalization, FEC — all via Model Context Protocol.
[](https://modelcontextprotocol.io)
[](https://www.python.org)
[](LICENSE)
[](#tool-list)
Developed for a **software-defined audio modem** project — data transfer between devices through a speaker and microphone (acoustic coupling). Suitable for CTF, research, laboratory work, and prototyping communication systems without radio.
## ✨ Features
- **Signal Generation** — tone, FSK, chirp, noise, ASK, BPSK, line codes
- **Modulation** — FSK, ASK, BPSK, NRZ, Manchester, Differential Manchester
- **Analysis** — FFT, spectrogram, Goertzel, correlation, eye diagram, constellation
- **Audio I/O** — recording from a microphone, playback, loopback test
- **DSP** — Butterworth filters, resampling, LMS equalizer, measuring impulse response of a channel
- **Packets and FEC** — preamble + CRC-16, Reed-Solomon
- **Metrics** — BER (direct and simulated), SNR, channel delay
## 🚀 Installation
```bash
pip install numpy scipy sounddevice soundfile matplotlib reedsolo
```
`sounddevice` is required for audio I/O (optional — without it, signal generation/analysis works).
### Connecting to Cline / Roo Code / Claude Desktop
Add to `mcp_settings.json`:
```json
{
"mcpServers": {
"audio-dsp-mcp": {
"command": "python",
"args": ["C:/path/to/audio-dsp-mcp/audio_dsp_server.py"],
"disabled": false
}
}
}
```
## 🛠 Tool List
### 📡 Signal Generation
| Tool | Description |
|---|---|
| `generate_tone` | Sine wave at a given frequency |
| `generate_fsk` | FSK modulation of a bit string |
| `generate_chirp` | Linear/logarithmic/quadratic chirp |
| `generate_noise` | White/pink/brown noise |
| `generate_silence` | Silence |
### 🎚 Modulation
| Tool | Description |
|---|---|
| `ask_modulate` | ASK (amplitude manipulation) |
| `psk_modulate` | BPSK (phase manipulation) |
| `line_code` | NRZ / Manchester / Diff-Manchester |
### 🔬 Analysis
| Tool | Description |
|---|---|
| `spectrogram` | Spectrogram (PNG + data) |
| `fft_analysis` | FFT spectrum with peaks |
| `goertzel` | Detection of a single frequency (Goertzel algorithm) |
| `correlation` | Cross-correlation (search for preamble) |
| `constellation_diagram` | Constellation of I/Q symbols |
| `eye_diagram` | Eye diagram |
### 🎧 Audio I/O
| Tool | Description |
|---|---|
| `play_audio` | Playback through speakers |
| `record_audio` | Recording from a microphone |
| `loopback_test` | Play + Rec simultaneously (delay, SNR) |
| `load_audio` | Loading a file (WAV/MP3/FLAC) |
| `save_audio` | Saving to WAV |
### ⚙️ DSP
| Tool | Description |
|---|---|
| `trim` | Trimming by time |
| `concatenate` | Concatenation of signals |
| `normalize` | Normalization by peak |
| `add_noise` | Adding AWGN with a given SNR |
| `filter_design` | Designing a Butterworth filter |
| `apply_filter` | Applying a filter |
| `resample` | Resampling |
| `impulse_response` | Impulse response of a channel (chirp/MLS) |
| `equalize_lms` | Adaptive LMS equalizer |
### 📦 Packets and FEC
| Tool | Description |
|---|---|
| `packet_encode` | Preamble + data + CRC-16-CCITT |
| `packet_decode` | Synchronization, data extraction, CRC check |
| `reed_solomon_encode` | Reed-Solomon FEC |
| `reed_solomon_decode` | Decoding with error correction |
| `ber_measure` | BER (direct counting or simulation) |
### 🔤 Text and Modem (end-to-end)
| Tool | Description |
|---|---|
| `text_encode` | Text → base64 (bytes) for transmission |
| `text_decode` | base64 (bytes) → text |
| `fsk_demodulate` | FSK demodulation of audio → bits (Goertzel bit by bit) |
| `modem_tx` | **Full transmitter**: text → packet → FSK audio (WAV) |
| `modem_rx` | **Full receiver**: audio → synchronization → demodulation → text |
## 📖 Usage Examples
### Transmit "Hi" with one command (recommended)
```
modem_tx({ text: "Hi", baud_rate: 2000 }) → ready WAV (base64) with chirp synchronization, preamble, and CRC
play_audio({ audio_data_b64: <data field from modem_tx> })
```
The word "Hi" is transmitted directly — it doesn't need to be encoded manually.
### Receive with one command
```
record_audio({ duration: 3 })
modem_rx({ audio_data_b64: <recorded signal>, baud_rate: 2000 })
→ { status: "ok", text: "Hi", crc_ok: true, ... }
```
### What's "SGk=" in the old example? (step-by-step breakdown)
`"SGk="` is the **base64 encoding of the string "Hi"**. It's not listed as text anywhere because it's already encoded bytes:
```
text_encode({ text: "Hi" }) → { data_b64: "SGk=", bits: "0100100001101001" }
```
Manual pipeline (equivalent to `modem_tx`). Here, base64 **is not needed** — `packet_encode` and `reed_solomon_encode` accept `text` directly:
```
1. packet_encode({ text: "Hi" }) → preamble + bits + CRC
2. generate_fsk({ bits: "...", mark_freq: 1200, space_freq: 2200, baud_rate: 2000 })
3. play_audio({ audio_data_b64: "..." })
```
Manual reception (equivalent to `modem_rx`):
```
1. record_audio({ duration: 3 })
2. correlation({ audio_data_b64_ref: <chirp>, audio_data_b64_signal: <recorded> }) → find packet start
3. fsk_demodulate({ audio_data_b64: ..., mark_freq: 1200, space_freq: 2200, baud_rate: 2000 }) → bits
4. packet_decode({ packet_bits: "..." }) → CRC check, ready text field = "Hi"
```
The base64 path (`text_encode`/`text_decode`/`data_b64`) remains for compatibility and transmitting arbitrary bytes, but for regular text, it's no longer necessary.
### Measure BER at different SNRs
```
ber_measure({ tx_bits: "1010...", snr_range_db: [0, 5, 10, 15, 20] })
→ { results: [{snr_db, errors, ber}, ...], theoretical_ber: [...] }
```
### Evaluate the channel between a speaker and a microphone
```
loopback_test({ duration: 2, chirp: true })
→ { delay_seconds, snr_db, rx_data }
```
## 🧪 Applications
- **Audio modems** — data transfer through sound (speaker→mic, hydroacoustics)
- **CTF / security research** — exfiltration through an audio channel
- **Laboratory work** — FSK/PSK/QAM, BER, FEC, equalization
- **Prototyping** — quick experiments with DSP without Simulink
See [`plans/audio-modem-lab-plan.md`](../plans/audio-modem-lab-plan.md) for 6 ready laboratory works.
## 🏗 Architecture
```
┌─────────────────────────────────────────────────┐
│ MCP Client (Cline/Roo) │
└──────────────────┬──────────────────────────────┘
│ JSON-RPC over stdio
┌──────────────────▼──────────────────────────────┐
│ audio_dsp_server.py │
│ ┌──────────────────────────────────────────┐ │
│ │ AudioDSPTools (38 static methods) │ │
│ │ ─ numpy + scipy + sounddevice │ │
│ │ ─ soundfile + matplotlib │ │
│ └──────────────────────────────────────────┘ │
│ TOOLS registry → TOOL_FUNCTIONS → handler │
└─────────────────────────────────────────────────┘
```
- **Transport**: stdio (JSON-RPC 2.0, MCP protocol 2024-11-05)
- **Audio format**: base64-WAV in the `data` field
- **Images**: base64-PNG in the `image_png_base64` field
## 📦 Dependencies
| Package | Purpose | Required |
|---|---|---|
| `numpy` | Basic signal operations | ✅ |
| `scipy` | Filters, chirps, resampling | ✅ |
| `sounddevice` | Audio I/O (play/record) | ⚠️ for I/O |
| `soundfile` | Reading/writing WAV | ✅ |
| `matplotlib` | Spectrograms, diagrams | ⚠️ for visualization |
| `reedsolo` | Reed-Solomon FEC | ⚠️ for FEC |
## 📝 License
MIT — see [LICENSE](LICENSE).
## 🤝 Acknowledgements
Inspired by [amodem](https://github.com/romanz/amodem) and the task *"How to transfer data between devices when usual communication means are unavailable"* .
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
hyperframes
Write HTML. Render video. Built for agents.
palmier-pro
macOS video editor with AI generation
FireRed-OpenStoryline
FireRed-OpenStoryline is an AI video editing agent that transforms manual...
vexa
Open-source meeting transcription API for Google Meet, Microsoft Teams &...
MAI-UI
MAI-UI provides GUI agents focused on real-world applications.
vllm-mlx
OpenAI-compatible server for Apple Silicon. Run LLMs and vision-language...