Skip to content

Commit ed673ce

Browse files
authored
Merge pull request #2 from theYahia/fix/tts-endpoint-mime-tls
fix: correct TTS endpoint, recognition MIME types & Sber TLS onboarding (v1.2.0)
2 parents 98fdb95 + 784cd21 commit ed673ce

18 files changed

Lines changed: 1204 additions & 680 deletions

.mcp.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"command": "npx",
55
"args": ["-y", "@theyahia/salutespeech-mcp"],
66
"env": {
7-
"SALUTE_AUTH_KEY": ""
7+
"SALUTESPEECH_API_KEY": ""
88
}
99
}
1010
}

CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented here.
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [1.2.0] - 2026-06-23
8+
9+
### Fixed
10+
- **Text-to-speech was completely broken.** `synthesize_speech` POSTed to the non-existent
11+
`/speech:synthesize`; the correct SaluteSpeech endpoint is `/text:synthesize`. Every TTS
12+
call previously failed.
13+
- **Recognition MIME types were wrong** for several formats. SaluteSpeech has no `audio/wav`
14+
content-type — WAV is now sent as `audio/x-pcm;bit=16;rate=<sr>` with the sample rate read
15+
from the file header. `.flac` now uses `audio/flac` (was `audio/x-flac`), and `.pcm` now
16+
requires a `sample_rate` and emits `audio/x-pcm;bit=16;rate=<sr>`. `.mp3`, `.ogg`, and
17+
`.opus` were already correct and are unchanged.
18+
19+
### Added
20+
- Configurable OAuth scope via `SALUTE_SPEECH_SCOPE` (default `SALUTE_SPEECH_PERS`), so
21+
corporate accounts (`SALUTE_SPEECH_CORP`, `SALUTE_SPEECH_B2B`) can authenticate.
22+
- `list_models` now reports the English voice **Kira** (`Kin_24000`/`Kin_8000`), the 8000 Hz
23+
telephony variants of every voice, the `alaw` synthesis format, and a note that the sample
24+
rate comes from the voice id suffix and other languages are selected via SSML.
25+
- Friendly size guard: recognition input over the 2 MB / 1 minute synchronous limit now
26+
fails with an actionable message pointing to the async flow (instead of a raw HTTP 413).
27+
- TLS troubleshooting: a clear OAuth error hint and a README section about installing the
28+
Russian Trusted Root CA (НУЦ Минцифры) via `NODE_EXTRA_CA_CERTS`.
29+
- All tool handlers now return `isError` on failure, so the model sees readable errors
30+
instead of opaque protocol errors.
31+
- `.alaw`/`.ulaw` recognition input mapping (`audio/pcma`/`audio/pcmu`).
32+
- New tests: WAV header parsing, size guard, recognition output shaping, exported
33+
`getAuthKey` priority, TLS-hint wrapping, and client retry behavior (429/500/abort).
34+
Handler tests assert request URL + content-type, locking in the endpoint and MIME fixes.
35+
36+
### Changed
37+
- Recognition tools now return a flattened `text` transcript alongside `emotions` and the
38+
raw API body (the transcript lives in `result[]`).
39+
- Synthesis input is validated to 1–4000 characters (the documented limit).
40+
- `.mcp.json` example uses `SALUTESPEECH_API_KEY` to match the README.
41+
- Removed unused type interfaces (`RecognitionResult`, `SynthesisResponse`, `SaluteModel`).
42+
43+
## [1.1.0]
44+
45+
- Upgrade to 5 tools, Vitest test suite, and Streamable HTTP transport.
46+
47+
## [1.0.0]
48+
49+
- Initial release.

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ Three options (checked in order):
4747
| `SALUTE_AUTH_KEY` | Same (legacy alias) |
4848
| `SALUTE_SPEECH_CLIENT_ID` + `SALUTE_SPEECH_CLIENT_SECRET` | Raw credentials (auto-encoded) |
4949

50-
OAuth tokens (scope `SALUTE_SPEECH_PERS`) are obtained and refreshed automatically.
50+
OAuth tokens are obtained and refreshed automatically. The scope defaults to
51+
`SALUTE_SPEECH_PERS` (individuals); set `SALUTE_SPEECH_SCOPE` for corporate accounts
52+
(`SALUTE_SPEECH_CORP` — postpaid, `SALUTE_SPEECH_B2B` — prepaid).
5153
Get credentials at [developers.sber.ru](https://developers.sber.ru).
5254

5355
## Tools (5)
@@ -73,6 +75,34 @@ Synthesize "Hello world" with voice Bys_24000 in wav16 format
7375
List available voices
7476
```
7577

78+
## Limits
79+
80+
`recognize_speech` / `recognize_file` use the **synchronous** endpoint, capped at
81+
**2 MB / 1 minute** of audio (larger input returns HTTP 413). For multi-channel audio only
82+
the first channel is recognized. Longer recordings need the asynchronous flow
83+
(`data:upload``speech:async_recognize``task:get``data:download`) — not yet exposed
84+
as tools; `get_task_status` covers the polling step.
85+
86+
Synthesis input is capped at **4000 characters** (incl. spaces and SSML markup).
87+
88+
## Troubleshooting
89+
90+
### `self-signed certificate in certificate chain` / `UNABLE_TO_VERIFY_LEAF_SIGNATURE`
91+
92+
Sber's endpoints use the **Russian Trusted Root CA (НУЦ Минцифры)**, which is **not** in
93+
Node.js's default trust store — so the very first OAuth call fails until you trust it.
94+
95+
Fix: download the root CA (`russian_trusted_root_ca_pem.crt`) from
96+
[gosuslugi.ru/crt](https://www.gosuslugi.ru/crt) and point Node at it:
97+
98+
```bash
99+
export NODE_EXTRA_CA_CERTS=/path/to/russian_trusted_root_ca_pem.crt
100+
```
101+
102+
In an MCP client, add it to the server's `env` block. **Do not** set
103+
`NODE_TLS_REJECT_UNAUTHORIZED=0` in production — it disables TLS verification entirely.
104+
Official guide: [SaluteSpeech certificates](https://developers.sber.ru/docs/ru/salutespeech/certificates).
105+
76106
## License
77107

78108
MIT

0 commit comments

Comments
 (0)