main.pyβ’21.5 kB
from typing import Dict, Optional
from mcp.server.fastmcp import FastMCP, Context
from src.agents.tools.doctranslate import DocTranslateTools
from starlette.requests import Request
from dotenv import load_dotenv
load_dotenv()
# Initialize MCP server
app = FastMCP(
name="doc-translate-server",
description="MCP server for DocTranslate.io document translation and conversion services",
host="0.0.0.0",
port=8000,
)
server = app.streamable_http_app
app.settings.stateless_http = True
def get_api_key(request: Request) -> str:
try:
"""
Check and get API_KEY from headers or query params
Returns: API_KEY if found, None if not found
"""
# Check in headers
headers = dict(request.headers)
for key in headers:
if key.lower() == "api_key":
return headers[key]
# Check in query params
params = dict(request.query_params)
for key in params:
if key.lower() == "api_key":
return params[key]
return None
except Exception as e:
return None
@app.tool()
def translate_document(
file_path: str,
dest_lang: str,
tone: str = "Default",
domain: str = "Default",
original_lang: Optional[str] = None,
process_mode: Optional[str] = "replace",
translate_type: Optional[str] = "Professional",
is_translate_images: Optional[bool] = False,
bilingual_text_style__font: Optional[str] = None,
bilingual_text_style__color: Optional[str] = None,
dictionary: Optional[str] = None,
output_format: Optional[str] = "auto",
custom_prompt: str = "",
api_key: Optional[str] = None,
ctx: Context = None,
) -> Dict:
"""
Translate a document to the target language with specified tone and domain.
Args:
file_path (str): Path to the document file to be translated. (MUST HAVE)
Supported formats include DOCX, PDF, PPTX, and XLSX.
dest_lang (str): Target language code. (MUST HAVE) Supported languages:
- 'en' (English)
- 'vi' (Vietnamese)
- 'ja' (Japanese)
- 'zh-cn' (Simplified Chinese)
- 'zh-tw' (Traditional Chinese)
- 'ko' (Korean)
- 'es' (Spanish)
- 'pt' (Portuguese)
- 'ru' (Russian)
- 'fr' (French)
- 'de' (German)
- 'it' (Italian)
- 'hi' (Hindi)
- 'th' (Thai)
- 'tr' (Turkish)
- 'el' (Greek)
- 'ar' (Arabic)
- 'nl' (Dutch)
- 'pl' (Polish)
- 'uk' (Ukrainian)
- 'sv' (Swedish)
- 'da' (Danish)
- 'no' (Norwegian)
- 'fi' (Finnish)
- 'hu' (Hungarian)
- 'in' (Indonesian)
- 'ms-MY' (Malay)
- 'fil' (Filipino)
- 'bn' (Bengali)
tone (str, optional): Desired tone of the translation. Available options:
- 'Default': Default
- 'Serious': Serious
- 'Friendly': Friendly
- 'Humorous': Humorous
- 'Formal': Formal
- 'Romantic': Romantic
Defaults to 'Default'.
domain (str, optional): Domain of the content. Available options:
- 'Default': Default
- 'Banking': Banking
- 'Accounting': Accounting
- 'Management': Management
- 'Law': Law
- 'Logistics': Logistics
- 'Marketing': Marketing
- 'Securities - Investment': Securities - Investment
- 'Insurance': Insurance
- 'Real Estate': Real Estate
- 'Music': Music
- 'Painting': Painting
- 'Theater - Cinema': Theater - Cinema
- 'Poetry': Poetry
- 'Epic': Epic
- 'Children\'s Stories': Children's Stories
- 'Historical Stories': Historical Stories
- 'Fiction': Fiction
- 'Short Stories': Short Stories
- 'Physics': Physics
- 'Chemistry': Chemistry
- 'Informatics': Informatics
- 'Electronics': Electronics
- 'Medicine': Medicine
- 'Mechanics': Mechanics
- 'Meteorology - Hydrology': Meteorology - Hydrology
- 'Agriculture': Agriculture
- 'Legal Documents': Legal Documents
- 'Internal Documents': Internal Documents
- 'Email': Email
- 'Health': Health
- 'Sports': Sports
- 'Culture - Tourism': Culture - Tourism
- 'Press': Press
- 'Animals': Animals
- 'Fast Translation': Fast Translation
- 'Games': Games
Defaults to 'Default'.
original_lang (str, optional): Source language code. Optional but recommended for better accuracy.
Available languages same as dest_lang. Use None for AI detection.
process_mode (str, optional): Text processing mode. Options:
- 'replace': Replace the original text with the translated text
- 'append': Append the translated text to the original text (bilingual mode)
- 'append_reverse': Append the translated text in reverse order (bilingual mode)
Defaults to 'replace'.
translate_type (str, optional): Translation engine type. Options:
- 'professional': Professional translation mode
- 'paraphrase': Used to summarize text
Defaults to 'professional'.
is_translate_images (bool, optional): Flag indicating whether images within the document should also be translated.
Defaults to False.
bilingual_text_style__font (str, optional): Custom font for bilingual text mode. Options:
- 'Helvetica', 'Meiryo', 'Times News Roman', 'Arial'
- 'Calibri', 'Robeto', 'Georgia', 'Garamond'
- 'Futura', 'Open Sans'
Defaults to 'Default'.
bilingual_text_style__color (str, optional): Custom color for bilingual text mode.
Use hex color codes (e.g., #ff0000, #0056d6, #669d34).
dictionary (str, optional): Custom dictionary in JSON format for word-level translations.
Format: [{"ori_lang": "en", "des_lang": "vi", "ori_word": "hello", "des_word": "xin chΓ o"}]
output_format (str, optional): Output format for the translated document. Options:
- 'auto': Automatically selects the best format
- 'docx': Text-based documents, may simplify layout
- 'pptx': Visually rich documents, maintains layout and formatting
For scanned PDFs: 'auto' and 'docx' recommended.
For regular PDFs: All formats available.
Defaults to 'auto'.
custom_prompt (str, optional): Custom requirements of user for translation.
api_key (str, optional): User's API key.
ctx (Context, optional): Context object.
Returns:
Dict: Response from the DocTranslate API containing task information.
Raises:
FileNotFoundError: If the specified file does not exist.
requests.exceptions.RequestException: If the API request fails.
"""
api_key = get_api_key(ctx.request_context.request)
if not api_key:
return {"error": "API_KEY not found"}
doctranslate = DocTranslateTools(api_key)
return doctranslate.run_translate_document(
file_path=file_path,
dest_lang=dest_lang,
tone=tone,
domain=domain,
original_lang=original_lang,
process_mode=process_mode,
translate_type=translate_type,
is_translate_images=is_translate_images,
bilingual_text_style__font=bilingual_text_style__font,
bilingual_text_style__color=bilingual_text_style__color,
dictionary=dictionary,
output_format=output_format,
custom_prompt=custom_prompt,
)
@app.tool()
def get_translation_result(
task_id: str, api_key: Optional[str] = None, ctx: Context = None
) -> Dict:
"""
Get the result of a translation task.
Args:
task_id: ID of the translation task
api_key: User's API key
ctx: Context object
Returns:
Dict containing the translation result or status
"""
api_key = get_api_key(ctx.request_context.request)
if not api_key:
return {"error": "API_KEY not found"}
doctranslate = DocTranslateTools(api_key)
return doctranslate.get_translate_result_by_task_id(task_id)
@app.tool()
def convert_to_pptx(
file_path: str,
dest_lang: str,
template_path: str = "system/v2/template_1",
api_key: Optional[str] = None,
ctx: Context = None,
) -> Dict:
"""
Convert a document to PPTX format.
Args:
file_path (Union[str, os.PathLike]): Path to the document file to be converted.
dest_lang (str): Target language code for the text in the presentation.
Supported languages:
- 'en' (English)
- 'vi' (Vietnamese)
- 'ja' (Japanese)
- 'zh-cn' (Simplified Chinese)
- 'zh-tw' (Traditional Chinese)
- 'ko' (Korean)
- 'es' (Spanish)
- 'pt' (Portuguese)
- 'ru' (Russian)
- 'fr' (French)
- 'de' (German)
- 'it' (Italian)
- 'hi' (Hindi)
- 'th' (Thai)
- 'tr' (Turkish)
- 'el' (Greek)
- 'ar' (Arabic)
- 'nl' (Dutch)
- 'pl' (Polish)
- 'uk' (Ukrainian)
- 'sv' (Swedish)
- 'da' (Danish)
- 'no' (Norwegian)
- 'fi' (Finnish)
- 'hu' (Hungarian)
- 'in' (Indonesian)
- 'ms-MY' (Malay)
- 'fil' (Filipino)
- 'bn' (Bengali)
template_path (str, optional): Path to the template file.
Must be one of: 'system/v2/template_1', 'system/v2/template_2'
Defaults to 'system/v2/template_1'.
api_key: User's API key
ctx: Context object
Returns:
Dict: Response from the DocTranslate API containing the conversion result.
Raises:
FileNotFoundError: If the specified file does not exist.
ValueError: If any of the parameters are invalid.
requests.exceptions.RequestException: If the API request fails.
"""
api_key = get_api_key(ctx.request_context.request)
if not api_key:
return {"error": "API_KEY not found"}
doctranslate = DocTranslateTools(api_key)
return doctranslate.doc2pptx(
file_path=file_path,
dest_lang=dest_lang,
template_path=template_path,
api_key=api_key,
)
@app.tool()
def get_user_history(
page: int = 1,
page_size: int = 10,
status: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
ctx: Context = None,
) -> Dict:
"""
Get the user's translation history.
Args:
page: Page number (1-based)
page_size: Number of items per page (1-100)
status: Filter by status ('completed', 'processing', 'failed')
start_date: Filter by start date (YYYY-MM-DD)
end_date: Filter by end date (YYYY-MM-DD)
Returns:
Dict containing the user's translation history
"""
api_key = get_api_key(ctx.request_context.request)
if not api_key:
return {"error": "API_KEY not found"}
doctranslate = DocTranslateTools(api_key)
return doctranslate.get_user_history(
page=page,
page_size=page_size,
status=status,
start_date=start_date,
end_date=end_date,
)
@app.tool()
def translate_text(
text: str,
dest_lang: str,
original_lang: Optional[str] = None,
process_mode: Optional[str] = "replace",
translate_type: Optional[str] = "Professional",
tone: Optional[str] = "Default",
domain: Optional[str] = "Default",
bilingual_text_style__font: Optional[str] = None,
bilingual_text_style__font_size: Optional[str] = None,
bilingual_text_style__color: Optional[str] = None,
dictionary: Optional[str] = None,
custom_prompt: Optional[str] = "",
api_key: Optional[str] = None,
ctx: Context = None,
) -> Dict:
"""
Translate text to target language with specified options.
Args:
text (str): Text to be translated. (MUST HAVE)
dest_lang (str): Target language code (MUST HAVE). Supported languages:
- 'en' (English)
- 'vi' (Vietnamese)
- 'ja' (Japanese)
- 'zh-cn' (Simplified Chinese)
- 'zh-tw' (Traditional Chinese)
- 'ko' (Korean)
- 'es' (Spanish)
- 'pt' (Portuguese)
- 'ru' (Russian)
- 'fr' (French)
- 'de' (German)
- 'it' (Italian)
- 'hi' (Hindi)
- 'th' (Thai)
- 'tr' (Turkish)
- 'el' (Greek)
- 'ar' (Arabic)
- 'nl' (Dutch)
- 'pl' (Polish)
- 'uk' (Ukrainian)
- 'sv' (Swedish)
- 'da' (Danish)
- 'no' (Norwegian)
- 'fi' (Finnish)
- 'hu' (Hungarian)
- 'in' (Indonesian)
- 'ms-MY' (Malay)
- 'fil' (Filipino)
- 'bn' (Bengali)
original_lang (str, optional): Source language code. Optional but recommended for better accuracy.
Use None for AI detection.
process_mode (str, optional): Text processing mode. Defaults to 'replace'.
- 'replace': Replace the original text with the translated text
- 'append': Append the translated text to the original text (bilingual mode)
- 'append_reverse': Append the translated text to the original text in reverse order (bilingual mode)
translate_type (str, optional): Translation type. Defaults to 'Professional'.
- 'Paraphrase': Paraphrase the text
- 'Professional': Professional translation
tone (str, optional): Desired tone of the translation. Defaults to 'Default'.
Available options:
- 'Default': Default
- 'Serious': Serious
- 'Friendly': Friendly
- 'Humorous': Humorous
- 'Formal': Formal
- 'Romantic': Romantic
domain (str, optional): Domain of the content. Defaults to 'Default'.
Available options:
- 'Default': Default
- 'Banking': Banking
- 'Accounting': Accounting
- 'Management': Management
- 'Law': Law
- 'Logistics': Logistics
- 'Marketing': Marketing
- 'Securities - Investment': Securities - Investment
- 'Insurance': Insurance
- 'Real Estate': Real Estate
- 'Music': Music
- 'Painting': Painting
- 'Theater - Cinema': Theater - Cinema
- 'Poetry': Poetry
- 'Epic': Epic
- 'Children\'s Stories': Children's Stories
- 'Historical Stories': Historical Stories
- 'Fiction': Fiction
- 'Short Stories': Short Stories
- 'Physics': Physics
- 'Chemistry': Chemistry
- 'Informatics': Informatics
- 'Electronics': Electronics
- 'Medicine': Medicine
- 'Mechanics': Mechanics
- 'Meteorology - Hydrology': Meteorology - Hydrology
- 'Agriculture': Agriculture
- 'Legal Documents': Legal Documents
- 'Internal Documents': Internal Documents
- 'Email': Email
- 'Health': Health
- 'Sports': Sports
- 'Culture - Tourism': Culture - Tourism
- 'Press': Press
- 'Animals': Animals
- 'Fast Translation': Fast Translation
bilingual_text_style__font (str, optional): Custom font for bilingual text mode.
Available fonts: Helvetica, Meiryo, Times News Roman, Arial,
Calibri, Robeto, Georgia, Garamond, Futura, Open Sans.
bilingual_text_style__font_size (str, optional): Custom font size for bilingual text mode.
bilingual_text_style__color (str, optional): Custom color for bilingual text mode.
Use hex color codes (e.g., #ff0000).
dictionary (str, optional): Custom dictionary in JSON format for word-level translations.
Example: [{"ori_lang": "en", "des_lang": "vi", "ori_word": "hello", "des_word": "xin chΓ o"}]
custom_prompt (str, optional): Custom prompt for translation process.
api_key (str, optional): User's API key.
ctx (Context, optional): Context object.
Returns:
Dict: Response containing translation task information.
Raises:
ValueError: If any parameter is invalid.
requests.exceptions.RequestException: If the API request fails.
"""
api_key = get_api_key(ctx.request_context.request)
if not api_key:
return {"error": "API_KEY not found"}
doctranslate = DocTranslateTools(api_key)
return doctranslate.translate_text(
text=text,
dest_lang=dest_lang,
original_lang=original_lang,
process_mode=process_mode,
translate_type=translate_type,
tone=tone,
domain=domain,
bilingual_text_style__font=bilingual_text_style__font,
bilingual_text_style__font_size=bilingual_text_style__font_size,
bilingual_text_style__color=bilingual_text_style__color,
dictionary=dictionary,
custom_prompt=custom_prompt,
api_key=api_key,
)
if __name__ == "__main__":
app.run(transport="streamable-http")