# Dùng VieNeu từ OpenAI API

Source: https://docs.vieneu.io/vi/docs/integrations/mcp/openai-api

Nếu bạn tự làm app trên model của OpenAI, bạn có thể trao thẳng các công cụ VieNeu
cho model: model tự quyết khi nào tìm giọng, khi nào đọc, còn OpenAI gọi
`https://api.vieneu.io/mcp` thay bạn.

**Cần có:** OpenAI API key và [API key của VieNeu](../../cloud-api/overview.md#authentication)
(`vn_sk_...`, tạo ở trang **Nhà phát triển**). Để cả hai trong biến môi trường:

```bash
export OPENAI_API_KEY=sk-...
export VIENEU_API_KEY=vn_sk_...
```

:::tip Chỉ cần audio từ code?
Nếu code của bạn đã biết sẵn văn bản và giọng thì không cần MCP hay LLM — gọi
thẳng [endpoint tương thích OpenAI](../../cloud-api/openai-compatible.md) bằng
OpenAI SDK. MCP dành cho lúc bạn muốn *model* tự quyết.
:::

## Responses API

Responses API có sẵn công cụ MCP từ xa. Đưa key VieNeu vào `authorization`; OpenAI
gửi nó tới VieNeu dưới dạng Bearer token, và VieNeu chấp nhận.

```python
import os
from openai import OpenAI

client = OpenAI()
resp = client.responses.create(
    model="gpt-5",  # model hiện hành bất kỳ có hỗ trợ tool
    tools=[{
        "type": "mcp",
        "server_label": "vieneu",
        "server_url": "https://api.vieneu.io/mcp",
        "authorization": os.environ["VIENEU_API_KEY"],
        "allowed_tools": ["list_voices", "text_to_speech", "get_speech_status", "get_token_balance"],
        "require_approval": "never",
    }],
    input="Tìm một giọng nữ miền Bắc rồi đọc câu: Xin chào, đây là VieNeu. Trả về link tải.",
)
print(resp.output_text)
```

```js
import OpenAI from "openai";

const client = new OpenAI();
const resp = await client.responses.create({
  model: "gpt-5",
  tools: [{
    type: "mcp",
    server_label: "vieneu",
    server_url: "https://api.vieneu.io/mcp",
    authorization: process.env.VIENEU_API_KEY,
    allowed_tools: ["list_voices", "text_to_speech", "get_speech_status", "get_token_balance"],
    require_approval: "never",
  }],
  input: "Tìm một giọng nữ miền Bắc rồi đọc câu: Xin chào, đây là VieNeu. Trả về link tải.",
});
console.log(resp.output_text);
```

- **`require_approval`:** mặc định mỗi lần gọi công cụ đều cần duyệt (khi đó câu
  trả lời có các mục `mcp_approval_request` mà bạn phải trả lời). `"never"` cho
  model tự tiêu token VieNeu của bạn mà không hỏi — hãy giới hạn `allowed_tools`,
  hoặc chỉ bắt duyệt riêng `text_to_speech`:
  `"require_approval": {"always": {"tool_names": ["text_to_speech"]}}`.
- **OpenAI không lưu key**, nên phải gửi kèm mỗi request.
- Link audio nằm trong kết quả công cụ và thường có trong câu trả lời của model;
  các mục `mcp_call` trong `resp.output` chứa kết quả thô.

## OpenAI Agents SDK (Python)

Để OpenAI gọi VieNeu thay bạn (hosted tool):

```python
import os
from agents import Agent, HostedMCPTool, Runner

agent = Agent(
    name="Narrator",
    instructions="Bạn đọc văn bản tiếng Việt bằng VieNeu và trả về link audio.",
    tools=[HostedMCPTool(tool_config={
        "type": "mcp",
        "server_label": "vieneu",
        "server_url": "https://api.vieneu.io/mcp",
        "authorization": os.environ["VIENEU_API_KEY"],
        "require_approval": "never",
    })],
)
result = Runner.run_sync(agent, "Đọc câu 'Chào buổi sáng' bằng giọng Thu Trang.")
print(result.final_output)
```

Hoặc kết nối từ chính tiến trình của bạn (code của bạn gọi VieNeu, header tuỳ ý):

```python
import asyncio, os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

async def main():
    async with MCPServerStreamableHttp(
        name="vieneu",
        params={
            "url": "https://api.vieneu.io/mcp",
            "headers": {"X-API-Key": os.environ["VIENEU_API_KEY"]},
            "timeout": 60,
        },
        cache_tools_list=True,
    ) as vieneu:
        agent = Agent(name="Narrator", mcp_servers=[vieneu])
        result = await Runner.run(agent, "Đọc câu 'Chào buổi sáng' bằng giọng Thu Trang.")
        print(result.final_output)

asyncio.run(main())
```

Để `timeout` rộng rãi: `text_to_speech` chờ audio xong (vài giây với câu ngắn,
tới khoảng 50 giây với văn bản dài).

## Chi phí

Hai hoá đơn riêng: OpenAI tính token của model, VieNeu trừ gói của bạn cho mỗi
lần tạo audio (theo ký tự, tối thiểu 50). `list_voices`, `list_emotion_tags`,
`get_speech_status` và `get_token_balance` miễn phí phía VieNeu.
