audio-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. audio_mcp-0.1.0/LICENSE +21 -0
  2. audio_mcp-0.1.0/PKG-INFO +177 -0
  3. audio_mcp-0.1.0/README.md +137 -0
  4. audio_mcp-0.1.0/pyproject.toml +65 -0
  5. audio_mcp-0.1.0/setup.cfg +4 -0
  6. audio_mcp-0.1.0/src/audio_mcp/__init__.py +3 -0
  7. audio_mcp-0.1.0/src/audio_mcp/__main__.py +3 -0
  8. audio_mcp-0.1.0/src/audio_mcp/analysis.py +578 -0
  9. audio_mcp-0.1.0/src/audio_mcp/audio_io.py +196 -0
  10. audio_mcp-0.1.0/src/audio_mcp/batch.py +182 -0
  11. audio_mcp-0.1.0/src/audio_mcp/cli.py +104 -0
  12. audio_mcp-0.1.0/src/audio_mcp/compare.py +167 -0
  13. audio_mcp-0.1.0/src/audio_mcp/dsp.py +175 -0
  14. audio_mcp-0.1.0/src/audio_mcp/dynamics.py +126 -0
  15. audio_mcp-0.1.0/src/audio_mcp/events.py +149 -0
  16. audio_mcp-0.1.0/src/audio_mcp/loudness.py +77 -0
  17. audio_mcp-0.1.0/src/audio_mcp/pitch.py +173 -0
  18. audio_mcp-0.1.0/src/audio_mcp/process.py +359 -0
  19. audio_mcp-0.1.0/src/audio_mcp/render.py +142 -0
  20. audio_mcp-0.1.0/src/audio_mcp/restore.py +89 -0
  21. audio_mcp-0.1.0/src/audio_mcp/server.py +232 -0
  22. audio_mcp-0.1.0/src/audio_mcp/synth.py +194 -0
  23. audio_mcp-0.1.0/src/audio_mcp/transcribe.py +138 -0
  24. audio_mcp-0.1.0/src/audio_mcp.egg-info/PKG-INFO +177 -0
  25. audio_mcp-0.1.0/src/audio_mcp.egg-info/SOURCES.txt +30 -0
  26. audio_mcp-0.1.0/src/audio_mcp.egg-info/dependency_links.txt +1 -0
  27. audio_mcp-0.1.0/src/audio_mcp.egg-info/entry_points.txt +2 -0
  28. audio_mcp-0.1.0/src/audio_mcp.egg-info/requires.txt +15 -0
  29. audio_mcp-0.1.0/src/audio_mcp.egg-info/top_level.txt +1 -0
  30. audio_mcp-0.1.0/tests/test_audio_mcp.py +381 -0
  31. audio_mcp-0.1.0/tests/test_contract.py +181 -0
  32. audio_mcp-0.1.0/tests/test_loudness.py +75 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mike Sharkey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: audio-mcp
3
+ Version: 0.1.0
4
+ Summary: Audio perception for AI agents: measure, see, compare, edit and synthesize sound over MCP.
5
+ Author: Mike Sharkey
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/mshark1/audio-mcp
8
+ Project-URL: Issues, https://github.com/mshark1/audio-mcp/issues
9
+ Project-URL: Changelog, https://github.com/mshark1/audio-mcp/blob/main/CHANGELOG.md
10
+ Keywords: mcp,model-context-protocol,audio,ai-agents,llm,loudness,spectrogram,dsp
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
21
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Editors
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: numpy>=1.24
27
+ Requires-Dist: scipy>=1.10
28
+ Requires-Dist: soundfile>=0.12.1
29
+ Requires-Dist: matplotlib>=3.7
30
+ Requires-Dist: mcp<3,>=2.3
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7; extra == "dev"
33
+ Requires-Dist: pyloudnorm>=0.1.1; extra == "dev"
34
+ Requires-Dist: ruff>=0.6; extra == "dev"
35
+ Requires-Dist: build>=1.2; extra == "dev"
36
+ Requires-Dist: twine>=5; extra == "dev"
37
+ Provides-Extra: speech
38
+ Requires-Dist: faster-whisper>=1.1; extra == "speech"
39
+ Dynamic: license-file
40
+
41
+ # audio-mcp
42
+
43
+ **Audio perception for AI agents.** Language models can't hear. This [MCP](https://modelcontextprotocol.io) server
44
+ turns sound into things they *can* reason about: measurements, plain-language problem reports, spectrogram images,
45
+ note lists, event timelines, transcripts and before/after diffs. It can also edit and synthesize audio, so an agent
46
+ can work in a loop: **make or fix a sound → measure it → look at it → verify the change.**
47
+
48
+ Everything runs locally. No GPU, no API keys. Core dependencies: numpy, scipy, soundfile, matplotlib.
49
+
50
+ Real output (JSON abbreviated) from the bundled demo, `scripts/demo.py`:
51
+
52
+ ```
53
+ > audio_analyze voice_raw.wav # speech recorded with mains hum and hiss
54
+ levels: lufs_integrated -32.16, true_peak_dbtp -11.76, clipped_samples 0
55
+ issues: [warning] Mains hum at 60 Hz (peaks at 60, 180 Hz). Fix: notch each with
56
+ {"op":"eq","hz":60,"db":-30,"q":30}, {"op":"eq","hz":180,"db":-30,"q":30};
57
+ for voice, highpass at ~80-100 Hz also removes the fundamental.
58
+ [info] Noise floor around -33.4 dBFS in the quietest parts; hiss or background noise may be audible.
59
+
60
+ > audio_events sfx.wav # a zap, a noise hit, another hit, a rising chirp
61
+ 0.09-0.36s | -4dB | tonal | balanced | glide G#6->B3 (-33st) | sharp attack
62
+ 0.59-0.69s | -16dB | noisy | very bright/harsh | sharp attack
63
+ ...
64
+
65
+ > audio_melody melody.wav # "Mary Had a Little Lamb", transcribed blind
66
+ E4(0.23) D4(0.24) C4(0.23) D4(0.24) E4(0.25) E4(0.25) E4(0.5) D4(0.24) D4(0.26) D4(0.49) E4(0.25) G4(0.26) G4(0.47)
67
+ ```
68
+
69
+ ## Tools
70
+
71
+ | Tool | What it gives the agent |
72
+ |---|---|
73
+ | `audio_analyze` | Peak, true peak, RMS, LUFS loudness, clipping, DC offset, a loudness sparkline, silence and noise floor, stereo correlation/width/balance, band energy, brightness, tonal vs. noisy, strongest frequencies as note names, pitch, onsets, tempo, edge clicks, loop-seam quality, and an **`issues`** list in plain language with suggested fixes |
74
+ | `audio_events` | Splits audio into distinct sounds and describes each one: timing, level, attack, tonal/noisy, brightness, pitch or glide |
75
+ | `audio_view` | PNG waveform and/or spectrogram, with an optional pitch overlay. Every column covers its full time span, so short clicks aren't skipped on long files |
76
+ | `audio_timeline` | Level and brightness over time. Streams the file, so it works on recordings of any length |
77
+ | `audio_melody` | Single-line transcription: notes, timings, cents, compact text |
78
+ | `audio_transcribe` | Speech to text with local Whisper: timed words, language, speaking rate, long pauses and **uncertain words** *(optional extra)* |
79
+ | `audio_compare` | A/B summary, metric deltas, per-band dB changes, issues fixed or introduced, and a **null test** (identical? only a gain change? lightly changed?) |
80
+ | `audio_process` | An ordered chain of edits written to a **new** file: gain, peak/LUFS normalize, true-peak limiter, compressor, noise reduction, trim, fades, crop, pad, high/low-pass, peaking EQ, shelves, DC removal, mono/stereo, resample, reverse, seamless-loop crossfade, mix, append |
81
+ | `audio_batch_survey` | Audits a folder for consistency (loudness outliers, mixed sample rates/channels/formats, uneven leading silence) and returns ready-to-run fixes |
82
+ | `audio_batch_process` | Applies one edit chain to many files and writes them to an output folder |
83
+ | `audio_synthesize` | Declarative synth: band-limited oscillators, noise colours, sweeps, ADSR, vibrato, tremolo, filters, pan, note sequences |
84
+ | `audio_info` | Metadata for a file, or a listing of the audio files in a folder |
85
+
86
+ Reads WAV, FLAC, OGG/Vorbis, Opus, MP3, AIFF and CAF (via libsndfile). Convert M4A/AAC with ffmpeg first.
87
+
88
+ ## Install
89
+
90
+ ```bash
91
+ pip install audio-mcp # or: uv tool install audio-mcp
92
+ pip install "audio-mcp[speech]" # adds audio_transcribe (faster-whisper; downloads a ~145 MB model on first use)
93
+ ```
94
+
95
+ ## Connect it to your MCP client
96
+
97
+ **Claude Code**
98
+
99
+ ```bash
100
+ claude mcp add audio -- uvx audio-mcp
101
+ # or, if installed with pip:
102
+ claude mcp add audio -- audio-mcp
103
+ ```
104
+
105
+ **Claude Desktop, Cursor, and other clients** (JSON config):
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "audio": { "command": "uvx", "args": ["audio-mcp"] }
111
+ }
112
+ }
113
+ ```
114
+
115
+ Then ask things like *"check the sound effects in ./sfx for problems"*, *"clean up interview.wav for a podcast"*
116
+ or *"design a short UI confirm sound and check it isn't harsh"*.
117
+
118
+ ### Restricting file access
119
+
120
+ By default the server can read and write any file your user account can. To confine it, set
121
+ `AUDIO_MCP_ALLOWED_DIRS` to a list of directories (separated by `;` on Windows, `:` elsewhere):
122
+
123
+ ```json
124
+ { "command": "uvx", "args": ["audio-mcp"], "env": { "AUDIO_MCP_ALLOWED_DIRS": "/home/me/audio" } }
125
+ ```
126
+
127
+ Paths are checked after resolving `..` and symlinks. Other settings: `AUDIO_MCP_MAX_SECONDS` (largest section loaded
128
+ into memory per call, default 1800), `AUDIO_MCP_WHISPER_MODEL` (default `base`), `AUDIO_MCP_ROOT` (base for
129
+ relative paths).
130
+
131
+ ## How accuracy is checked
132
+
133
+ The tests mostly use **synthetic signals whose correct answer is known by construction**, so they check
134
+ correctness rather than just "no crash":
135
+
136
+ - **Loudness:** our streaming BS.1770 meter matches pyloudnorm's exact-filter mode within 0.01 LU from 8 to 96 kHz,
137
+ and reads the EBU reference tone (997 Hz, 0 dBFS) at −3.01 LUFS.
138
+ - **Limiter:** a +15 dBTP input comes out at exactly −1.0 dBTP with no samples touched by the safety clip.
139
+ - **Pitch and melody:** sines, chirps and synthesized melodies are recovered note for note, including repeated notes.
140
+ - **Tempo, onsets, events, silence, stereo phase, hum, clipping, alignment offsets:** each is checked against a
141
+ constructed signal.
142
+ - **A contract test** runs every tool on every content type (silence, DC, noise, full-scale square), length
143
+ (1 sample to 3 s), format (16/24/float WAV, FLAC, Vorbis), channel count (1, 2, 6) and sample rate (8–96 kHz).
144
+ Each call must either succeed or fail with an `AudioError` that explains itself.
145
+ - **Memory:** analysis is chunked. A 20-minute stereo 48 kHz file analyzes in about 19 s with about 1.2 GB peak
146
+ memory, 0.7 GB of which is the audio itself.
147
+
148
+ ## Design principles
149
+
150
+ - **Never destructive by default.** Edits write `<name>_processed.wav`; overwriting needs `overwrite=true`, and
151
+ batch output can't target the input folder.
152
+ - **Errors say what to do next.** An unknown op lists every op with its parameters; an undecodable file names the
153
+ supported formats and the ffmpeg command to convert it. Unexpected errors are reported as bugs instead of being
154
+ hidden.
155
+ - **Honest about uncertainty.** Chords set `polyphony_likely` instead of reporting a confident wrong pitch, weak
156
+ tempos carry a low-confidence note, Whisper's uncertain words are listed, and LUFS is `null` for clips under
157
+ 0.4 s.
158
+ - **Compact output.** Rounded numbers, sparklines and one-line event summaries keep responses small enough for
159
+ an agent's context.
160
+
161
+ ## Limitations
162
+
163
+ - Pitch, melody and per-event pitch assume one note at a time. Chords and full mixes are flagged, not transcribed.
164
+ - Denoise is a spectral gate for *steady* noise (hiss, hum, fans, room tone). It doesn't remove clicks, music or
165
+ other voices. Too much `sensitivity` dulls quiet consonants, so verify speech edits with `audio_transcribe`.
166
+ - Tempo is a classic autocorrelation estimate; half- and double-tempo errors happen on complex music.
167
+ - The tools describe sound, but they don't judge taste ("is this satisfying?").
168
+
169
+ ## Contributing
170
+
171
+ Improvements from people and AI agents are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md); AI coding agents
172
+ should also read [AGENTS.md](AGENTS.md). The bar for a feature is that it does one thing well, with a test against
173
+ known ground truth.
174
+
175
+ ## License
176
+
177
+ [MIT](LICENSE)
@@ -0,0 +1,137 @@
1
+ # audio-mcp
2
+
3
+ **Audio perception for AI agents.** Language models can't hear. This [MCP](https://modelcontextprotocol.io) server
4
+ turns sound into things they *can* reason about: measurements, plain-language problem reports, spectrogram images,
5
+ note lists, event timelines, transcripts and before/after diffs. It can also edit and synthesize audio, so an agent
6
+ can work in a loop: **make or fix a sound → measure it → look at it → verify the change.**
7
+
8
+ Everything runs locally. No GPU, no API keys. Core dependencies: numpy, scipy, soundfile, matplotlib.
9
+
10
+ Real output (JSON abbreviated) from the bundled demo, `scripts/demo.py`:
11
+
12
+ ```
13
+ > audio_analyze voice_raw.wav # speech recorded with mains hum and hiss
14
+ levels: lufs_integrated -32.16, true_peak_dbtp -11.76, clipped_samples 0
15
+ issues: [warning] Mains hum at 60 Hz (peaks at 60, 180 Hz). Fix: notch each with
16
+ {"op":"eq","hz":60,"db":-30,"q":30}, {"op":"eq","hz":180,"db":-30,"q":30};
17
+ for voice, highpass at ~80-100 Hz also removes the fundamental.
18
+ [info] Noise floor around -33.4 dBFS in the quietest parts; hiss or background noise may be audible.
19
+
20
+ > audio_events sfx.wav # a zap, a noise hit, another hit, a rising chirp
21
+ 0.09-0.36s | -4dB | tonal | balanced | glide G#6->B3 (-33st) | sharp attack
22
+ 0.59-0.69s | -16dB | noisy | very bright/harsh | sharp attack
23
+ ...
24
+
25
+ > audio_melody melody.wav # "Mary Had a Little Lamb", transcribed blind
26
+ E4(0.23) D4(0.24) C4(0.23) D4(0.24) E4(0.25) E4(0.25) E4(0.5) D4(0.24) D4(0.26) D4(0.49) E4(0.25) G4(0.26) G4(0.47)
27
+ ```
28
+
29
+ ## Tools
30
+
31
+ | Tool | What it gives the agent |
32
+ |---|---|
33
+ | `audio_analyze` | Peak, true peak, RMS, LUFS loudness, clipping, DC offset, a loudness sparkline, silence and noise floor, stereo correlation/width/balance, band energy, brightness, tonal vs. noisy, strongest frequencies as note names, pitch, onsets, tempo, edge clicks, loop-seam quality, and an **`issues`** list in plain language with suggested fixes |
34
+ | `audio_events` | Splits audio into distinct sounds and describes each one: timing, level, attack, tonal/noisy, brightness, pitch or glide |
35
+ | `audio_view` | PNG waveform and/or spectrogram, with an optional pitch overlay. Every column covers its full time span, so short clicks aren't skipped on long files |
36
+ | `audio_timeline` | Level and brightness over time. Streams the file, so it works on recordings of any length |
37
+ | `audio_melody` | Single-line transcription: notes, timings, cents, compact text |
38
+ | `audio_transcribe` | Speech to text with local Whisper: timed words, language, speaking rate, long pauses and **uncertain words** *(optional extra)* |
39
+ | `audio_compare` | A/B summary, metric deltas, per-band dB changes, issues fixed or introduced, and a **null test** (identical? only a gain change? lightly changed?) |
40
+ | `audio_process` | An ordered chain of edits written to a **new** file: gain, peak/LUFS normalize, true-peak limiter, compressor, noise reduction, trim, fades, crop, pad, high/low-pass, peaking EQ, shelves, DC removal, mono/stereo, resample, reverse, seamless-loop crossfade, mix, append |
41
+ | `audio_batch_survey` | Audits a folder for consistency (loudness outliers, mixed sample rates/channels/formats, uneven leading silence) and returns ready-to-run fixes |
42
+ | `audio_batch_process` | Applies one edit chain to many files and writes them to an output folder |
43
+ | `audio_synthesize` | Declarative synth: band-limited oscillators, noise colours, sweeps, ADSR, vibrato, tremolo, filters, pan, note sequences |
44
+ | `audio_info` | Metadata for a file, or a listing of the audio files in a folder |
45
+
46
+ Reads WAV, FLAC, OGG/Vorbis, Opus, MP3, AIFF and CAF (via libsndfile). Convert M4A/AAC with ffmpeg first.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install audio-mcp # or: uv tool install audio-mcp
52
+ pip install "audio-mcp[speech]" # adds audio_transcribe (faster-whisper; downloads a ~145 MB model on first use)
53
+ ```
54
+
55
+ ## Connect it to your MCP client
56
+
57
+ **Claude Code**
58
+
59
+ ```bash
60
+ claude mcp add audio -- uvx audio-mcp
61
+ # or, if installed with pip:
62
+ claude mcp add audio -- audio-mcp
63
+ ```
64
+
65
+ **Claude Desktop, Cursor, and other clients** (JSON config):
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "audio": { "command": "uvx", "args": ["audio-mcp"] }
71
+ }
72
+ }
73
+ ```
74
+
75
+ Then ask things like *"check the sound effects in ./sfx for problems"*, *"clean up interview.wav for a podcast"*
76
+ or *"design a short UI confirm sound and check it isn't harsh"*.
77
+
78
+ ### Restricting file access
79
+
80
+ By default the server can read and write any file your user account can. To confine it, set
81
+ `AUDIO_MCP_ALLOWED_DIRS` to a list of directories (separated by `;` on Windows, `:` elsewhere):
82
+
83
+ ```json
84
+ { "command": "uvx", "args": ["audio-mcp"], "env": { "AUDIO_MCP_ALLOWED_DIRS": "/home/me/audio" } }
85
+ ```
86
+
87
+ Paths are checked after resolving `..` and symlinks. Other settings: `AUDIO_MCP_MAX_SECONDS` (largest section loaded
88
+ into memory per call, default 1800), `AUDIO_MCP_WHISPER_MODEL` (default `base`), `AUDIO_MCP_ROOT` (base for
89
+ relative paths).
90
+
91
+ ## How accuracy is checked
92
+
93
+ The tests mostly use **synthetic signals whose correct answer is known by construction**, so they check
94
+ correctness rather than just "no crash":
95
+
96
+ - **Loudness:** our streaming BS.1770 meter matches pyloudnorm's exact-filter mode within 0.01 LU from 8 to 96 kHz,
97
+ and reads the EBU reference tone (997 Hz, 0 dBFS) at −3.01 LUFS.
98
+ - **Limiter:** a +15 dBTP input comes out at exactly −1.0 dBTP with no samples touched by the safety clip.
99
+ - **Pitch and melody:** sines, chirps and synthesized melodies are recovered note for note, including repeated notes.
100
+ - **Tempo, onsets, events, silence, stereo phase, hum, clipping, alignment offsets:** each is checked against a
101
+ constructed signal.
102
+ - **A contract test** runs every tool on every content type (silence, DC, noise, full-scale square), length
103
+ (1 sample to 3 s), format (16/24/float WAV, FLAC, Vorbis), channel count (1, 2, 6) and sample rate (8–96 kHz).
104
+ Each call must either succeed or fail with an `AudioError` that explains itself.
105
+ - **Memory:** analysis is chunked. A 20-minute stereo 48 kHz file analyzes in about 19 s with about 1.2 GB peak
106
+ memory, 0.7 GB of which is the audio itself.
107
+
108
+ ## Design principles
109
+
110
+ - **Never destructive by default.** Edits write `<name>_processed.wav`; overwriting needs `overwrite=true`, and
111
+ batch output can't target the input folder.
112
+ - **Errors say what to do next.** An unknown op lists every op with its parameters; an undecodable file names the
113
+ supported formats and the ffmpeg command to convert it. Unexpected errors are reported as bugs instead of being
114
+ hidden.
115
+ - **Honest about uncertainty.** Chords set `polyphony_likely` instead of reporting a confident wrong pitch, weak
116
+ tempos carry a low-confidence note, Whisper's uncertain words are listed, and LUFS is `null` for clips under
117
+ 0.4 s.
118
+ - **Compact output.** Rounded numbers, sparklines and one-line event summaries keep responses small enough for
119
+ an agent's context.
120
+
121
+ ## Limitations
122
+
123
+ - Pitch, melody and per-event pitch assume one note at a time. Chords and full mixes are flagged, not transcribed.
124
+ - Denoise is a spectral gate for *steady* noise (hiss, hum, fans, room tone). It doesn't remove clicks, music or
125
+ other voices. Too much `sensitivity` dulls quiet consonants, so verify speech edits with `audio_transcribe`.
126
+ - Tempo is a classic autocorrelation estimate; half- and double-tempo errors happen on complex music.
127
+ - The tools describe sound, but they don't judge taste ("is this satisfying?").
128
+
129
+ ## Contributing
130
+
131
+ Improvements from people and AI agents are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md); AI coding agents
132
+ should also read [AGENTS.md](AGENTS.md). The bar for a feature is that it does one thing well, with a test against
133
+ known ground truth.
134
+
135
+ ## License
136
+
137
+ [MIT](LICENSE)
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "audio-mcp"
7
+ version = "0.1.0"
8
+ description = "Audio perception for AI agents: measure, see, compare, edit and synthesize sound over MCP."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Mike Sharkey" }]
13
+ requires-python = ">=3.10"
14
+ keywords = ["mcp", "model-context-protocol", "audio", "ai-agents", "llm", "loudness", "spectrogram", "dsp"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Multimedia :: Sound/Audio :: Analysis",
26
+ "Topic :: Multimedia :: Sound/Audio :: Editors",
27
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
28
+ ]
29
+ dependencies = [
30
+ "numpy>=1.24",
31
+ "scipy>=1.10",
32
+ "soundfile>=0.12.1",
33
+ "matplotlib>=3.7",
34
+ "mcp>=2.3,<3",
35
+ ]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/mshark1/audio-mcp"
39
+ Issues = "https://github.com/mshark1/audio-mcp/issues"
40
+ Changelog = "https://github.com/mshark1/audio-mcp/blob/main/CHANGELOG.md"
41
+
42
+ [project.optional-dependencies]
43
+ dev = ["pytest>=7", "pyloudnorm>=0.1.1", "ruff>=0.6", "build>=1.2", "twine>=5"]
44
+ speech = ["faster-whisper>=1.1"]
45
+
46
+ [project.scripts]
47
+ audio-mcp = "audio_mcp.cli:main"
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+
52
+ [tool.pytest.ini_options]
53
+ testpaths = ["tests"]
54
+
55
+ [tool.ruff]
56
+ line-length = 120
57
+ target-version = "py310"
58
+
59
+ [tool.ruff.lint]
60
+ select = ["E", "F", "W", "B", "UP", "I", "SIM", "PIE"]
61
+ ignore = [
62
+ "E501", # the formatter handles line length; long strings in tool descriptions are fine
63
+ "B905", # zip() without strict= : lengths are equal by construction here
64
+ "SIM108", # ternaries aren't always clearer
65
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Audio perception tools for AI agents."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()