Metadata-Version: 2.4
Name: ovos-translate-server
Version: 0.9.0a2
Summary: FastAPI server to host OpenVoiceOS translate plugins as a service
Author-email: JarbasAi <jarbasai@mailfence.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/OpenVoiceOS/ovos-translate-server
Project-URL: Repository, https://github.com/OpenVoiceOS/ovos-translate-server
Keywords: plugin,lang,detect,translate,OVOS,OpenVoiceOS
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: fastapi
Requires-Dist: uvicorn[standard]
Requires-Dist: ovos-plugin-manager
Provides-Extra: lang-names
Requires-Dist: langcodes; extra == "lang-names"
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == "mcp"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: httpx; extra == "test"
Requires-Dist: uvicorn; extra == "test"
Requires-Dist: deepl; extra == "test"
Requires-Dist: google-cloud-translate; extra == "test"
Requires-Dist: azure-ai-translation-text<2; extra == "test"
Requires-Dist: boto3; extra == "test"
Requires-Dist: libretranslatepy; extra == "test"
Requires-Dist: deeplx-tr; extra == "test"
Requires-Dist: marshmallow<4; extra == "test"
Dynamic: license-file

# OpenVoiceOS Translate Server

Turn any OVOS language plugin into an HTTP microservice for translation and
language detection.

Pair it with the [companion client plugin](https://github.com/OpenVoiceOS/ovos-translate-server-plugin)
to offload translation from an OVOS device, or point existing tooling at the
[vendor-compatible endpoints](#vendor-compatible-endpoints) below.

## Contents

- [Install](#install)
- [Usage](#usage)
- [HTTP API](#http-api)
- [AI Agent Integration](#ai-agent-integration) — UTCP & MCP
- [Vendor-compatible endpoints](#vendor-compatible-endpoints)
- [Docker](#docker)
- [Documentation](#documentation)
- [Examples](#examples)
- [Credits](#credits)

## Install

```bash
pip install ovos-translate-server
```

The server only hosts plugins — install at least one translation plugin, and
optionally a dedicated language-detection plugin, alongside it:

```bash
pip install ovos-translate-plugin-nllb              # translation
pip install ovos-lang-detector-classics-plugin      # detection (optional)
```

Optional extras:

| Extra | Installs | Enables |
|-------|----------|---------|
| `mcp` | `pip install "ovos-translate-server[mcp]"` | embedded [MCP](#mcp--model-context-protocol) server at `/mcp` |
| `lang-names` | `pip install "ovos-translate-server[lang-names]"` | human-readable language names in vendor `languages` responses |

## Usage

```bash
$ ovos-translate-server --help
usage: ovos-translate-server [-h] --tx-engine TX_ENGINE
                             [--detect-engine DETECT_ENGINE]
                             [--host HOST] [--port PORT]

Run the OVOS Translate HTTP server.

options:
  -h, --help            show this help message and exit
  --tx-engine TX_ENGINE
                        OPM translation plugin entry-point name (required)
  --detect-engine DETECT_ENGINE
                        OPM language-detection plugin entry-point name (optional)
  --host HOST           host to bind (default: 0.0.0.0)
  --port PORT           TCP port (default: 9686)
```

For example, to serve the [NLLB plugin](https://github.com/OpenVoiceOS/ovos-translate-plugin-nllb)
for translation and [Lang Classifier Classics](https://github.com/OpenVoiceOS/ovos-lang-detector-classics-plugin)
for detection:

```bash
ovos-translate-server \
  --tx-engine ovos-translate-plugin-nllb \
  --detect-engine ovos-lang-detector-classics-plugin
```

When `--detect-engine` is omitted, detection falls back to the translation
plugin's own `detect()` method. See [docs/detection.md](docs/detection.md).

## HTTP API

The native API is unauthenticated and uses `GET` requests. The text to
translate or detect is the **last path segment** and should be URL-encoded.

| Method & path | Purpose |
|---------------|---------|
| `GET /status` | Plugin name and supported languages |
| `GET /translate/{target}/{text}` | Translate, auto-detecting the source language |
| `GET /translate/{source}/{target}/{text}` | Translate with an explicit source language |
| `GET /detect/{text}` | Detect the language, returns a BCP-47 code |
| `GET /classify/{text}` | Per-language confidence scores |

```bash
curl http://localhost:9686/translate/en/o%20meu%20nome%20%C3%A9%20Casimiro
# "my name is Casimiro"

curl http://localhost:9686/detect/o%20meu%20nome%20%C3%A9%20Casimiro
# "pt"
```

Full reference: [docs/index.md](docs/index.md).

## AI Agent Integration

### UTCP — Universal Tool Calling Protocol

Every running instance of the server exposes a machine-readable
[UTCP](https://github.com/universal-tool-calling-protocol/python-utcp) manual at:

```
GET /utcp
```

The manual describes all translation and detection endpoints as **HTTP tools**
so UTCP-compatible AI agents can discover and invoke them directly — no extra
proxy layer required.  The URLs in the manual use the same host/port the
request arrived on, so the document is always self-consistent under any
reverse-proxy deployment.

```bash
curl http://localhost:9686/utcp | python3 -m json.tool
```

**Exposed tools**

| UTCP tool name | Description |
|---|---|
| `ovos_translate.translate` | Translate text, source language auto-detected |
| `ovos_translate.translate_with_source` | Translate text with explicit source language |
| `ovos_translate.detect_language` | Return the BCP-47 language tag of a string |
| `ovos_translate.classify_language` | Return per-language confidence scores |
| `ovos_translate.supported_languages` | List all supported language codes |

No extra dependency is required for UTCP; the `/utcp` endpoint is always
registered when the server starts.

### MCP — Model Context Protocol

An optional [MCP](https://modelcontextprotocol.io) server is embedded in
the main application when the `mcp` extra is installed:

```bash
pip install "ovos-translate-server[mcp]"
```

Once installed, the MCP endpoint is automatically mounted at `/mcp` using
the Streamable HTTP transport.  Agents that speak MCP (Claude Desktop,
Continue, etc.) can add it as a server at:

```
http://localhost:9686/mcp
```

**MCP tools**

| Tool | Arguments | Returns |
|---|---|---|
| `translate` | `text`, `target_lang`, `source_lang` (optional) | translated string |
| `detect_language` | `text` | BCP-47 language tag |

#### Standalone MCP process

If you prefer to run the MCP server as a separate process (e.g. to bind it
to `localhost` only while the HTTP API is public):

```bash
python -m ovos_translate_server.mcp_server \
    --tx-engine ovos-translate-plugin-nllb \
    --detect-engine ovos-lang-detector-classics-plugin \
    --host 127.0.0.1 \
    --port 9687
```

#### Embedding in a custom FastAPI app

```python
from ovos_translate_server import start_translate_server
from ovos_translate_server.mcp_server import get_mcp_app

app, engine = start_translate_server("ovos-translate-plugin-nllb")
# MCP is already mounted at /mcp; or mount it manually at a custom path:
# app.mount("/my-mcp", get_mcp_app(engine))
```

#### Claude Desktop configuration

```json
{
  "mcpServers": {
    "ovos-translate": {
      "url": "http://localhost:9686/mcp"
    }
  }
}
```

## Vendor-compatible endpoints

The server mounts compat routers under per-vendor prefixes so existing tools,
SDKs, and scripts that already target a commercial translation API can be
pointed at your local OVOS instance with zero code changes — typically just a
base-URL / endpoint override, exactly what a DNS redirect to the server would
achieve.

| Vendor | Prefix | Key endpoints | Client |
|--------|--------|---------------|--------|
| DeepL | `/deepl` | `POST /deepl/v2/translate` | official `deepl` SDK |
| DeepLX | `/deeplx` | `POST /deeplx/translate` | community `deeplx-tr` / HTTP |
| LibreTranslate | `/libretranslate` | `POST /libretranslate/translate`, `/detect`, `GET /libretranslate/languages` | official `libretranslatepy` |
| Lingva Translate | `/lingva` | `GET /lingva/api/v1/{source}/{target}/{query}` | HTTP (no SDK) |
| Google Cloud Translation | `/google` | `POST /google/language/translate/v2` | official `google-cloud-translate` |
| Azure Translator | `/azure` | `POST /azure/translate` | official `azure-ai-translation-text<2` |
| Amazon Translate | `/amazon` | `POST /amazon/translate/text` | official `boto3` |

A runnable script for each lives in [`examples/`](examples/). Full endpoint
reference, curl examples, and client-configuration snippets:
[docs/api-compatibility.md](docs/api-compatibility.md).

```bash
# DeepLX — simple {text, source_lang, target_lang} -> {code, data}
curl -s http://localhost:9686/deeplx/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "hello", "source_lang": "EN", "target_lang": "DE"}'

# Lingva — GET path params; use "auto" to auto-detect the source
curl -s "http://localhost:9686/lingva/api/v1/en/de/hello%20world"
```

## Docker

Any plugin can be served with a small Dockerfile:

```dockerfile
FROM python:3.11-slim

RUN pip install --no-cache-dir \
    ovos-translate-server \
    ovos-translate-plugin-nllb \
    ovos-lang-detector-classics-plugin

EXPOSE 9686
ENTRYPOINT ["ovos-translate-server", \
            "--tx-engine", "ovos-translate-plugin-nllb", \
            "--detect-engine", "ovos-lang-detector-classics-plugin"]
```

Build and run:

```bash
docker build -t my-translate-server .
docker run -p 9686:9686 my-translate-server
```

Each plugin can ship its own Dockerfile in its repository using
`ovos-translate-server` as the base.

## Documentation

| Document | Covers |
|----------|--------|
| [docs/index.md](docs/index.md) | Overview, installation, native HTTP API, plugin interface |
| [docs/api-compatibility.md](docs/api-compatibility.md) | Vendor routers — prefixes, endpoints, curl, client configuration |
| [docs/language-codes.md](docs/language-codes.md) | Per-vendor language-code normalisation |
| [docs/detection.md](docs/detection.md) | Language-detection priority and per-router behaviour |

## Examples

[`examples/`](examples/) holds one runnable script per vendor router (driving
each vendor's real client SDK where one exists) plus a native-API script. See
[examples/README.md](examples/README.md).

## Credits

Developed by [TigreGótico](https://tigregotico.pt) for
[OpenVoiceOS](https://openvoiceos.org).

[![NGI0 Commons Fund](./ngi.png)](https://nlnet.nl/project/OpenVoiceOS)

This project was funded through the [NGI0 Commons Fund](https://nlnet.nl/commonsfund),
a fund established by [NLnet](https://nlnet.nl) with financial support from the
European Commission's [Next Generation Internet](https://ngi.eu) programme, under
the aegis of [DG Communications Networks, Content and Technology](https://commission.europa.eu/about-european-commission/departments-and-executive-agencies/communications-networks-content-and-technology_en)
under grant agreement No [101135429](https://cordis.europa.eu/project/id/101135429).
