sarvam-mcp
by harshil1502
README.md
# sarvam-mcp
```
sarvam-mcp/ v0.1 ──────────────────────────────────────────────────
```
A focused, type-safe **MCP server** for the [Sarvam AI](https://www.sarvam.ai) API. Lets [Claude Code](https://claude.ai/code) (or any MCP-compatible client) speak to Sarvam's models — chat, translation, transliteration, language detection, speech-to-text, and text-to-speech — across **10 Indic languages plus English**.
> [!IMPORTANT]
> **This project is not affiliated with, endorsed by, or associated with Sarvam AI.** It's an unofficial MCP wrapper that calls the public Sarvam API using your own API key. No keys, audio, or text are routed through any third-party server.
> [!NOTE]
> **Requires a Sarvam AI API key.** Get one at [dashboard.sarvam.ai](https://dashboard.sarvam.ai). Free tier is generous enough to test all six tools.
---
## What it does
Wraps Sarvam's public REST surface in a small set of well-defined MCP tools. Tools are typed end-to-end with [Zod](https://zod.dev) schemas, validated at the boundary, and surface useful error messages when something goes wrong.
```
┌───────────────┐
│ Claude Code │
│ (or any MCP │
│ client) │
└───────┬───────┘
│ stdio (MCP)
▼
┌───────────────┐
│ sarvam-mcp │
└───────┬───────┘
│ HTTPS · api.sarvam.ai
▼
┌───────────────┐
│ Sarvam API │
│ (Sarvam-105B │
│ · Mayura │
│ · Saarika │
│ · Bulbul) │
└───────────────┘
```
---
## Why another wrapper?
Sarvam ships a great official SDK for Python and Node. This is the **MCP-shaped surface** that lets agentic clients call it directly — no SDK code, no glue layer.
- **6 tools, deliberately scoped.** Every tool is documented, typed, and tested.
- **Strict TypeScript.** No `any`, no implicit returns, `noUncheckedIndexedAccess` on.
- **Zod-validated boundaries.** Every input is parsed before the network call.
- **Typed errors.** `SarvamApiError`, `SarvamRateLimitError`, `SarvamConfigError`, `SarvamValidationError` — never bare `Error`.
- **`sarvam-mcp doctor`.** A diagnostic command that tells you exactly what's wrong with your setup.
Use this if you want a small, predictable surface you can read in an afternoon.
---
## The 6 tools
| Tool | What it does | Sarvam endpoint |
|------|--------------|-----------------|
| `sarvam_chat` | Chat completions (Sarvam-30B / Sarvam-105B), JSON mode supported | `POST /v1/chat/completions` |
| `sarvam_translate` | Bidirectional EN ↔ Indic and Indic ↔ Indic translation | `POST /translate` |
| `sarvam_transliterate` | Script conversion (Roman ↔ Devanagari, etc.) | `POST /transliterate` |
| `sarvam_detect_language` | Identify language and script of input text | `POST /text-lid` |
| `sarvam_speech_to_text` | Saarika v2.5 / Saaras v3 transcription from local audio file | `POST /speech-to-text` |
| `sarvam_text_to_speech` | Bulbul v3 synthesis. Returns base64 audio + optional WAV file | `POST /text-to-speech` |
Document Intelligence (Sarvam Vision) is on the v0.2 roadmap — it's an async batch flow that deserves its own treatment.
---
## Install
Requires Node.js 20+.
```bash
npm install -g sarvam-mcp
# or, in a project:
npm install sarvam-mcp
```
For development:
```bash
git clone https://github.com/harshil1502/sarvam-mcp.git
cd sarvam-mcp
npm install
npm run build
```
---
## Setup — three steps
### 1. Get a Sarvam API key
[dashboard.sarvam.ai](https://dashboard.sarvam.ai) → create key. Free tier is enough to test all six tools.
### 2. Export it
```bash
export SARVAM_API_KEY=<your_key>
```
(Or put it in a `.env` file and source it before launching the MCP client — see `.env.example`.)
### 3. Verify
```bash
sarvam-mcp doctor
```
You should see something like:
```
sarvam-mcp · doctor
─────────────────────────────────────────────
[ ok ] SARVAM_API_KEY env var
Set (40 chars).
[ ok ] Language ID endpoint
Detected: hi-IN (expected hi-IN).
[ ok ] Chat completions
Got: ok
─────────────────────────────────────────────
all green — sarvam-mcp is ready.
```
If something fails, the doctor prints the exact reason.
---
## Use with Claude Code
Add to your `~/.claude.json` MCP servers:
```json
{
"mcpServers": {
"sarvam": {
"command": "sarvam-mcp",
"env": { "SARVAM_API_KEY": "your_key_here" }
}
}
}
```
Then in Claude:
```
> translate "I'll be there at 9pm" to Tamil
[claude calls sarvam_translate]
→ "நான் இரவு 9 மணிக்கு அங்கு வருவேன்"
```
---
## Examples
### Chat in Hindi
```jsonc
// tool call: sarvam_chat
{
"messages": [
{ "role": "system", "content": "You are a helpful assistant. Reply in Hindi." },
{ "role": "user", "content": "What's the difference between Marathi and Hindi?" }
],
"model": "sarvam-105b",
"temperature": 0.4
}
```
### Translate code-mixed text
```jsonc
// tool call: sarvam_translate
{
"input": "मेरा नाम Harshil है and I work in AI",
"source_language_code": "auto",
"target_language_code": "en-IN",
"mode": "code-mixed"
}
// → { "translated_text": "My name is Harshil and I work in AI" }
```
### Transliterate a Hindi name to Roman script
```jsonc
// tool call: sarvam_transliterate
{
"input": "हर्षिल पटेल",
"source_language_code": "hi-IN",
"target_language_code": "en-IN"
}
// → { "transliterated_text": "Harshil Patel" }
```
### Identify language
```jsonc
// tool call: sarvam_detect_language
{ "input": "வணக்கம் உலகம்" }
// → { "language_code": "ta-IN", "script_code": "Taml" }
```
### Transcribe a voice memo
```jsonc
// tool call: sarvam_speech_to_text
{
"audio_path": "/Users/me/Downloads/voice-memo.m4a",
"language_code": "hi-IN",
"model": "saaras:v3",
"with_diarization": true
}
```
### Generate Tamil speech and save it
```jsonc
// tool call: sarvam_text_to_speech
{
"inputs": ["நான் உங்களுக்கு உதவ முடியும்."],
"target_language_code": "ta-IN",
"speaker": "anushka",
"output_path": "/tmp/reply.wav"
}
// → audio also written to /tmp/reply.wav
```
---
## Architecture
Four files, four responsibilities:
```
src/
├── client/sarvam.ts ← single fetch wrapper, both auth schemes
├── tools/
│ ├── chat.ts ← sarvam_chat
│ ├── translate.ts ← translate · transliterate · detect_language
│ └── speech.ts ← speech_to_text · text_to_speech
├── server.ts ← MCP transport + tool registration
├── cli/doctor.ts ← setup diagnostics
└── index.ts ← entry point + argv routing
```
When the next Sarvam API release breaks something, drift is contained to one file.
---
## Strict TypeScript across the agent boundary
```jsonc
// tsconfig.json (excerpts)
{
"strict": true,
"noImplicitAny": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true
}
```
Agents will happily call your tool with `null` and then narrate the resulting error. Don't let them.
---
## Errors
| Class | When it fires |
|-------|---------------|
| `SarvamConfigError` | Missing `SARVAM_API_KEY`, unreadable audio file. |
| `SarvamApiError` | Any 4xx/5xx from Sarvam (other than 429). Includes status, endpoint, and body excerpt. |
| `SarvamRateLimitError` | 429. Includes `retryAfterSeconds` if Sarvam sets `Retry-After`. |
| `SarvamValidationError` | Zod validation failed — the LLM passed bad arguments. |
Retries are intentionally **not** auto-implemented. The LLM gets the error and decides what to do.
---
## Contributing / roadmap
v0.2 — Document Intelligence (Sarvam Vision):
- `sarvam_doc_extract_start` — kick off async OCR job
- `sarvam_doc_extract_status` — poll
- `sarvam_doc_extract_results` — fetch structured output
v0.3 — streaming (WebSocket TTS / STT) for low-latency voice agents.
PRs welcome. Run `npm run typecheck && npm test` before opening one.
---
## License
MIT © 2026 Harshil Patel
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues