Skip to main content
Glama

levelang.app MCP Server

CI Python 3.12+ MCP SDK uv

An MCP server that exposes the levelang.app translation API to AI assistants. Unlike standard translators that always produce native-speaker complexity, levelang.app constrains translations to the learner's proficiency level.


Features

  • Level-Aware Translation — Translate text at beginner, intermediate, advanced, or fluent proficiency with grammar constraints enforced per level

  • Multi-Language Support — French, German, Italian, Mandarin Chinese, Cantonese, with transliteration where applicable

  • Mood Control — Casual, polite, and formal translation styles

  • Language Discovery — Query available languages, levels, and moods dynamically from the backend

  • MCP Resourceslevelang://languages and levelang://languages/{code} for pulling language configs into context

  • Stateless Wrapper — No database, no shared state; translates MCP tool calls into backend HTTP requests

Related MCP server: Lokalise MCP Server

Quick Start

You need two things: the MCP server URL and an API key. No local setup required.

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "levelang": {
      "url": "https://your-mcp-server-url/mcp",
      "headers": {
        "Authorization": "Bearer your-api-key"
      }
    }
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "levelang": {
      "url": "https://your-mcp-server-url/mcp",
      "headers": {
        "Authorization": "Bearer your-api-key"
      }
    }
  }
}

Restart Claude Desktop. A hammer icon in the chat input indicates MCP tools are available.

Example Usage

Once connected, ask your AI assistant things like:

Translate "I would like to order a coffee, please" into French at the beginner level.

What languages does Levelang support?

Compare how "I'm worried the new rules might prevent us from finishing on time" translates into German at beginner vs advanced level.

Server Configuration

The settings below are for running the MCP server (local development or self-hosting). End users connecting via URL do not need these.

All configuration is through environment variables. When running locally via stdio, these go in the env block of your MCP client config.

Variable

Required

Default

Description

LEVELANG_API_BASE_URL

No

http://localhost:8000/api/v1

Levelang backend URL

LEVELANG_API_KEY

Depends

Service key (sk_xxx) for backend auth

MCP_TRANSPORT

No

stdio

Transport: stdio or streamable-http

MCP_PORT

No

8463

Port when using HTTP transport

MCP_API_KEYS

No

Comma-separated valid API keys for HTTP auth

LEVELANG_API_KEY is required when connecting to a remote backend (staging/production). It may be omitted for local development if the backend has auth disabled.

MCP_API_KEYS controls client authentication for the HTTP transport. When set, clients must send Authorization: Bearer <key> with a key from this list. When empty or unset, auth is disabled (open access). This has no effect on stdio transport.

Local stdio Connection

For local development you can run the MCP server as a subprocess instead of connecting via URL. This requires Python 3.12+, uv, and a running Levelang backend.

git clone https://github.com/beverage/levelang-mcp.git
cd levelang-mcp
uv sync
{
  "mcpServers": {
    "levelang": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/absolute/path/to/levelang-mcp",
        "python", "-m", "levelang_mcp"
      ],
      "env": {
        "LEVELANG_API_BASE_URL": "http://localhost:8000/api/v1"
      }
    }
  }
}

Development

Setup

uv sync
git config core.hooksPath .githooks

This enables pre-commit (auto-fix lint + format) and pre-push (lint + format check + tests) hooks.

Running Tests

uv run pytest tests/ -v

MCP Inspector

The MCP Inspector provides a web UI for browsing and invoking tools and resources:

npx @modelcontextprotocol/inspector uv run --directory /path/to/levelang-mcp python -m levelang_mcp

Project Structure

src/levelang_mcp/
├── __main__.py       # Entrypoint (python -m levelang_mcp)
├── server.py         # MCP tools and resources
├── auth.py           # API-key auth middleware for HTTP transport
├── client.py         # Async HTTP client for the Levelang API
├── config.py         # Environment variable loading
└── formatting.py     # API response → human-readable text

tests/
├── test_auth.py      # Auth middleware and config tests
├── test_client.py    # HTTP client tests (mocked)
├── test_formatting.py
└── test_tools.py     # Tool integration tests (mocked)

Architecture

MCP Client              levelang-mcp              Levelang Backend
(Claude, Cursor,   ◄── MCP/stdio ──►   (this)   ─── HTTP ──►   (FastAPI)
 Claude Code)                                     POST /translate
                                                  GET /languages/details
                                                  GET /languages/{code}

The MCP server is a stateless wrapper. It translates MCP tool calls into HTTP requests to the Levelang backend and formats responses as human-readable text for the LLM. It does not share code, database connections, or deployment with the backend.

License

MIT

Available Tools

3 tools
list_languagesA

List all languages supported by Levelang with their available levels and moods.

Use this to discover valid language codes, proficiency levels, mood options, and mode options before calling the translate tool.

Returns: Formatted list of supported languages and their configurations.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It describes the tool as a list operation, implying it's read-only and non-destructive, but doesn't explicitly state permissions, rate limits, or error handling. The description adds some context by specifying what information is returned (language codes, levels, moods, modes), but lacks details on format, pagination, or potential constraints. This is adequate but has gaps for a tool with no annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded: the first sentence states the core purpose, followed by usage guidance and return information. Every sentence earns its place by adding value—no waste or redundancy. The structure is clear and efficient, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (0 parameters, no annotations, but has an output schema), the description is complete enough. It explains the purpose, usage guidelines, and what information is returned. Since an output schema exists, the description doesn't need to detail return values, and it adequately covers the tool's role in the context of sibling tools. This provides sufficient information for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, and schema description coverage is 100% (since there are no parameters to describe). The description doesn't need to add parameter semantics, but it does mention that the tool helps discover 'valid language codes, proficiency levels, mood options, and mode options,' which indirectly clarifies the output context. With no parameters, a baseline of 4 is appropriate, as the description provides useful output-related context without redundancy.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'List all languages supported by Levelang with their available levels and moods.' This is specific (verb: 'List', resource: 'languages'), and it distinguishes from siblings by focusing on discovery rather than translation. The mention of 'valid language codes, proficiency levels, mood options, and mode options' further clarifies its role in providing configuration data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool: 'Use this to discover valid language codes, proficiency levels, mood options, and mode options before calling the translate tool.' It provides clear context (preparation for translation) and names an alternative ('translate tool'), effectively guiding the agent on usage versus siblings like 'translate' and 'translate_compare'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

translateA

Translate text to a target language at a specific proficiency level.

Unlike standard translators that produce native-speaker complexity, this translates at the learner's level -- beginner translations use simple grammar, intermediate uses more complex structures, etc.

Args: text: The text to translate (any length, any source language) target_language: Target language code -- use list_languages to see available codes (e.g. fra, deu, cmn, yue, ita) level: Proficiency level -- proficiency levels available for the target language (e.g. beginner, intermediate, advanced, and/or fluent) source_language: Source language code (default: eng for English) mood: Tone -- tones available for the target language mode: Language mode (spoken/written) -- controls whether the translation targets written or spoken register. Use list_languages to see available modes per language.

Returns: The translated text with metadata about the translation.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
target_languageYes
levelYes
source_languageNoeng
moodNocasual
modeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively explains the unique behavior of producing translations at learner proficiency levels (beginner, intermediate, etc.) rather than native-speaker complexity. It also mentions that returns include 'metadata about the translation,' which adds useful context beyond basic translation output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and appropriately sized. It starts with the core purpose, explains the unique value proposition, then provides clear parameter documentation in a structured format. Every sentence adds value with no wasted words, and the information is front-loaded effectively.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters, unique proficiency-based translation behavior) and the presence of an output schema (which handles return value documentation), the description provides complete context. It explains the tool's unique behavior, documents all parameters thoroughly, references related tools, and mentions the output includes metadata - covering all necessary aspects for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate. It provides excellent parameter semantics: explaining what each parameter does, giving examples (e.g., 'fra, deu, cmn'), clarifying defaults ('eng for English'), and explaining constraints ('any length, any source language'). The description adds substantial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Translate text to a target language at a specific proficiency level.' It distinguishes itself from standard translators by explaining it produces translations at the learner's level with varying complexity based on proficiency. This specificity helps differentiate it from generic translation tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool (for learner-level translations) and references the sibling tool 'list_languages' to discover available language codes and modes. However, it doesn't explicitly state when NOT to use this tool or how it differs from 'translate_compare' (the other sibling tool mentioned).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

translate_compareA

Translate text at multiple proficiency levels to compare complexity differences.

Shows how the same text is translated differently at different levels -- useful for understanding how grammar and vocabulary constraints change across proficiency.

Args: text: The text to translate (any length, any source language) target_language: Target language code -- use list_languages to see available codes (e.g. fra, deu, cmn, yue, ita) source_language: Source language code (default: eng for English) mood: Tone -- tones available for the target language levels: Optional list of proficiency level codes to compare (e.g. ["beginner", "advanced"]). If omitted, compares all available levels. Use list_languages to see valid codes per language. mode: Optional language mode (spoken/written) -- controls whether the translation targets written or spoken register. If omitted, compares all available levels. Use list_languages to see valid codes per language.

Returns: The same text translated at each requested level, formatted for comparison.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
target_languageYes
source_languageNoeng
moodNocasual
levelsNo
modeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden. It describes the core behavior (comparative translation across levels) and mentions output formatting ('formatted for comparison'). However, it lacks details about rate limits, authentication requirements, error conditions, or whether this is a read-only vs. mutating operation. The description adds some behavioral context but leaves significant gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear purpose statement, usage context, parameter documentation, and return value description. It's appropriately sized for a 6-parameter tool with complex functionality. Some sentences could be slightly more concise, but overall it's efficient and front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters, comparative functionality) and the presence of an output schema (which handles return values), the description is mostly complete. It covers purpose, usage context, and detailed parameter semantics. The main gap is in behavioral transparency aspects like rate limits and error handling, but the output schema reduces the need to describe return format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate. It provides detailed semantic explanations for all 6 parameters, including examples, default values, optionality, and references to other tools for valid values. The description adds substantial meaning beyond the bare schema, clearly explaining what each parameter controls and how to use them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Translate text at multiple proficiency levels to compare complexity differences.' It specifies the verb (translate), resource (text), and scope (multiple proficiency levels for comparison). It distinguishes from sibling 'translate' by emphasizing the comparative aspect across levels rather than single-level translation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: 'useful for understanding how grammar and vocabulary constraints change across proficiency.' It references sibling tools ('use list_languages to see available codes') but doesn't explicitly state when to choose this over the basic 'translate' tool or provide exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedlist_languages
    • First observedtranslate
    • First observedtranslate_compare

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: list_languages provides configuration discovery, translate performs single-level translation, and translate_compare enables multi-level comparison. There is no overlap in functionality, and an agent can easily distinguish between them based on their specific objectives.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: list_languages, translate, and translate_compare. The naming is predictable and readable, with no deviations or mixed conventions, making it easy for agents to understand the tool set's structure.

Tool Count4/5

With 3 tools, the count is reasonable for a language translation server, covering core operations like discovery, translation, and comparison. However, it feels slightly thin, as additional tools for managing translations or handling errors could enhance completeness, but the current set is well-scoped for basic functionality.

Completeness4/5

The tool set covers essential workflows: discovering supported languages, translating text at specific levels, and comparing translations across levels. Minor gaps exist, such as no tools for updating or deleting translations, but these are not critical for the server's purpose, and agents can work effectively with the provided operations.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers